2011-12-10 13 views
12

मैं जीमेल को एचटीएमएल 5 ड्रैग/ड्रॉप अटैचमेंट्स को संभालने के तरीके को पुन: पेश करने की कोशिश कर रहा हूं - जहां आप पृष्ठ पर फ़ाइलों को खींचते हैं, यह एक नया तत्व प्रदर्शित करता है आप उन्हें छोड़ने के लिए। मुझे वह हिस्सा मिल गया (यह सीधे आगे नहीं था जैसा कि मैंने सोचा था कि यह होगा)।एचटीएमएल 5 ड्रैग ड्रॉप फाइलों के लिए माउस कर्सर बदलना (जीमेल ड्रैग ड्रॉप)

अब जब मैं बूंद तत्व के अलावा किसी भी अन्य तत्व पर माउस माउस कर्सर को बदलकर इसे पॉलिश करने की कोशिश कर रहा हूं, तो उपयोगकर्ता ड्रॉप करने की अनुमति नहीं है। मुझे कल्पना है कि मैं इसे एक कस्टम कर्सर के साथ कर सकता हूं, लेकिन ऐसा लगता है कि जीमेल क्या कर रहा है। The spec सुझाव देगा कि माउस कर्सर को भी बदलना संभव है, लेकिन मुझे ड्रॉपज़ोन/प्रभाव का उपयोग करके सही काम नहीं मिल रहा है। http://jsfiddle.net/guYWx/1/

अनुमानित समय: यहाँ है कि मैं क्या साथ समाप्त हो गया है: http://jsfiddle.net

किसी भी मदद की सराहना की जाएगी, यहां मेरे मौजूदा सेटअप है/guYWx/16/

<body style="border: 1px solid black;"> 
    <div id="d0" style="border: 1px solid black;">drag files onto this page</div> 
    <div id="d1" style="border: 1px solid black; display: none; background-color: red;">-&gt; drop here &lt;-</div> 
    <div id="d2" style="border: 1px solid black;">and stuff will happen</div> 
    <div style="float: left;">mouse them all over&nbsp;</div> 
    <div style="float: left;">these elements</div> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <div>end page</div> 
</body> 
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> 
<script type="text/javascript"> 
    var resetTimer; 

    var reset = function() 
    { 
     $('#d1').hide(); 
    }; 

    var f = function(e) 
    { 
     var srcElement = e.srcElement? e.srcElement : e.target; 

     if ($.inArray('Files', e.dataTransfer.types) > -1) 
     { 
      e.stopPropagation(); 
      e.preventDefault(); 

      e.dataTransfer.dropEffect = (srcElement.id == 'd1') ? 'copy' : 'none'; 

      if (e.type == "dragover") 
      { 
       if (resetTimer) 
       { 
        clearTimeout(resetTimer); 
       } 
       $('#d1').show(); 
       console.info('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.types is ' + e.dataTransfer.types + '\n\ne.dataTransfer.files.length is ' + e.dataTransfer.files.length); 

      } 
      else if (e.type == "dragleave") 
      { 
       resetTimer = window.setTimeout(reset, 25); 
      } 
      else if (e.type == "drop") 
      { 
       reset(); 
       alert('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.files.length is ' + (e.dataTransfer.files ? e.dataTransfer.files.length : 0)); 
      } 
     } 
    }; 

    document.body.addEventListener("dragleave", f, false); 
    document.body.addEventListener("dragover", f, false); 
    document.body.addEventListener("drop", f, false); 
</script> 
+0

हाय, मैं घंटों तक अपने आप से जूझ रहा हूं। आपका कोड तब मेरा और अधिक अच्छी तरह से काम करता है। क्या आप समझ सकते हैं कि रीसेट पर टाइमआउट देरी का क्या उद्देश्य है? – benb

+1

यह ड्रैगलेव ईवेंट के लिए झूठी सकारात्मक रोकता है। जब आप उप-तत्वों के समूह के साथ ड्रैगओवर/ड्रैगलेव को किसी तत्व पर बाध्य करते हैं, तो जब आप उप-तत्व से उप-तत्व तक माउस करते हैं तो ईवेंट आग लग जाएंगे। मैंने टाइमआउट को 'रीसेट' पर कॉल के साथ बदल दिया, ताकि आप देख सकें कि जब आप खींचते हैं तो यह कितना बुरा होता है: http://jsfiddle.net/guYWx/20/ (क्रोम में छिपाने/दिखाने के बहुत सारे)। – Langdon

उत्तर

24

क्या कुछ ने स्रोत के माध्यम से खुदाई की और पाया कि आपको अपने dragover ईवेंट हैंडलर के अंदर event.dataTransfer.dropEffect = 'move'; सेट करना होगा। Google पर dropEffect अधिक से पाया पढ़ने के लिए:

dataTransfer.dropEffect

नियंत्रण राय है कि उपयोगकर्ता dragenter और dragover घटनाओं के दौरान दिया जाता है। जब उपयोगकर्ता लक्ष्य तत्व पर हो जाता है, तो ब्राउज़र का कर्सर इंगित करेगा कि किस प्रकार का ऑपरेशन स्थान (उदाहरण के लिए एक प्रति, एक चाल, आदि) ले जाएगा। प्रभाव में से किसी एक मान पर ले जा सकता है: कोई नहीं, प्रतिलिपि बनाएँ, लिंक करें, स्थानांतरित करें।

से: http://www.html5rocks.com/en/tutorials/dnd/basics/

संपादित करें: http://jsfiddle.net/guYWx/16/

यह पूरी तरह काम कर पाने के एक अतिरिक्त चाल करना था: यहाँ है कि मैं क्या साथ समाप्त हो गया है। यह इतना ड्रॉपर प्रकट नहीं होता था जब आप पाठ का चयन करें और यह पेज चारों ओर खींचें:

if ($.inArray('Files', e.dataTransfer.types) > -1) 
-3

आप cursor सीएसएस संपत्ति बदलना होगा।

आपको cursorhere के विभिन्न मानों की एक सूची मिलती है।

आप cursor: url('foo.png'); के साथ एक कस्टम कर्सर छवि भी निर्दिष्ट कर सकते हैं।

+0

मुझे पता है कि मैं कर्सर बदल सकता हूं, लेकिन जीमेल यह नहीं कर रहा है। कर्सर के बीच बहुत अंतर है: नो-ड्रॉप और कर्सर जीमेल पर कैसा दिखता है। – Langdon

4

@Langdon - उनका कहना है मैं वास्तव में क्या जरूरत के लिए धन्यवाद! मैंने इसे ऊपर उठाया है।

इतने घंटों खर्च करने के बाद मुझे यह सुझाव मिल गया जैसा कि इरादे से काम कर रहा था।

मैं के उपयोग dropEffectके साथ संयोजन में effectAllowed जब खींचें ड्रॉप ऑपरेशनों को दृश्य संकेत प्रदान करने के लिए बनाया है। पूरी तरह से क्रॉस ब्राउज़र!

$(document).on('dragstart dragenter dragover', function(event) {  
    // Only file drag-n-drops allowed, http://jsfiddle.net/guYWx/16/ 
    if ($.inArray('Files', event.originalEvent.dataTransfer.types) > -1) { 
     // Needed to allow effectAllowed, dropEffect to take effect 
     event.stopPropagation(); 
     // Needed to allow effectAllowed, dropEffect to take effect 
     event.preventDefault(); 

     $('.dropzone').addClass('dropzone-hilight').show();  // Hilight the drop zone 
     dropZoneVisible= true; 

     // http://www.html5rocks.com/en/tutorials/dnd/basics/ 
     // http://api.jquery.com/category/events/event-object/ 
     event.originalEvent.dataTransfer.effectAllowed= 'none'; 
     event.originalEvent.dataTransfer.dropEffect= 'none'; 

     // .dropzone .message 
     if($(event.target).hasClass('dropzone') || $(event.target).hasClass('message')) { 
      event.originalEvent.dataTransfer.effectAllowed= 'copyMove'; 
      event.originalEvent.dataTransfer.dropEffect= 'move'; 
     } 
    } 
}).on('drop dragleave dragend', function (event) { 
    dropZoneVisible= false; 

    clearTimeout(dropZoneTimer); 
    dropZoneTimer= setTimeout(function(){ 
     if(!dropZoneVisible) { 
      $('.dropzone').hide().removeClass('dropzone-hilight'); 
     } 
    }, dropZoneHideDelay); // dropZoneHideDelay= 70, but anything above 50 is better 
}); 
संबंधित मुद्दे