2012-01-21 16 views
12

मैं व्यूपोर्ट पर एक div ओवरले करना चाहता हूं जब उपयोगकर्ता विंडो पर फ़ाइल खींचता है।इवेंट प्रचार, ओवरले और ड्रैग-एंड-ड्रॉप इवेंट

हालांकि, मुझे घटना प्रसार के साथ परेशानी हो रही है। जब मैं ओवरले को display: block पर सेट करता हूं तो यह dragleave ईवेंट और फिर dragenter और फिर एक और dragleave फिर से आग लग रहा है, इसलिए यह हमेशा एक पोस्ट-ड्रैगलेव स्थिति में होता है। बेशक मैं ईवेंट ऑब्जेक्ट पर e.stopPropagation() और e.preventDefault() पर कॉल करता हूं, लेकिन ऐसा कोई फर्क नहीं पड़ता है।

console.log() उत्पादन जब तुम खिड़की पर कुछ खींचें:

dragenter 
dragenter 
dragleave 
dragenter 
dragleave 

सीएसएस। #overlaydisplay: none डिफ़ॉल्ट रूप से करने के लिए सेट कर दिया जाता है, लेकिन अगर bodydragenter वर्ग है दिखाएगा:

body { 
     position: absolute; 
     height: auto; 
     top: 0; 
     left: 0; 
     right: 0; 
     bottom: 0; 
     margin: 0; 
     padding: 0; 
    } 

    #overlay { 
     position: absolute;   
     height: auto; 
     width: auto; 
     top: 0; 
     left: 0; 
     right: 0; 
     bottom: 0; 
     background: url(bg.png) repeat-x top right, url(bg.png) repeat-x bottom left, url(bg.png) repeat-y top right, url(bg.p 
ng) repeat-y bottom left; 
     display: none; 
    } 

    body.dragenter #overlay { 
     display: block; 
    } 

जावास्क्रिप्ट। dragenter पर 'dragenter' वर्ग जोड़ें और dragleave पर उसे निकाल देता है:

$(document).on('dragenter', function (e) { 
    e.stopPropagation(); 
    e.preventDefault(); 
    console.log('dragenter'); 
    $(document.body).addClass('dragenter'); 
}); 

$(document).on('dragleave', function (e) { 
    e.stopPropagation(); 
    e.preventDefault(); 
    console.log('dragleave'; 
    $(document.body).removeClass('dragenter'); 
}); 

एचटीएमएल:

<body> 
<div id="overlay">...</div> 
...  
</body> 

उत्तर

1

Scottux के लिए धन्यवाद, कि मुझे सही रास्ते पर नेतृत्व किया।

केवल समस्या यह भी बाकी पृष्ठ को कवर किया गया था, इसलिए तत्वों या इनपुट में से कोई भी क्लिक करने योग्य नहीं था। मैं "प्रदर्शन: कोई नहीं" के साथ डिफ़ॉल्ट रूप से #dragOverlay को छिपाने के लिए किया था और इस घटना पर प्रदर्शित

// Display an overlay when dragging a file over 
$('*:visible').live('dragenter', function(e) { 
    e.stopPropagation(); 
    $('body').addClass('drag-enter'); 
}); 
+0

बहुत बढ़िया, ठीक है, मैं अब कुछ घंटों के लिए हल करने की तलाश में था;) लेकिन जहां तक ​​मुझे jquery, $ ('*: visual') पता है। लाइव() एक बहुत महंगा चयनकर्ता होना चाहिए। क्या कोई और समाधान हो सकता है? मेरा मतलब imgur पर लोग हैं।कॉम स्पष्ट रूप से एक रास्ता मिला (साइट पर अपने खोजक/एक्सप्लोरर से एक फ़ाइल खींचें और आप देखेंगे) लेकिन मैं यह पता लगाने के लिए कोड को इंजीनियर नहीं कर सका :( –

+0

मुझे लगता है कि यह एक भारी हाथ का समाधान है भी, लेकिन यह सबसे आसान है (मुझे एक कार्य प्रोजेक्ट और सभी समय पर बाधाओं के साथ)। मैंने इमगुर कोड को भी देखने की कोशिश की है और ऐसा कुछ नहीं है जिसे मैं गहराई से खोदना चाहता हूं। – twig

5

आपका ओवरले पूरे दस्तावेज़ आकार लेता है, जब आप में खींचें, इसे अपने स्थान को भरता और आपका माउस प्रभावी ढंग से शरीर से बाहर निकाला जाता है और अब ओवरले पर है। यह एक माउसलेव/माउसएन्टर लूप ट्रिगर करता है। आप जो हासिल कर रहे हैं उसे प्राप्त करने के लिए, आप ईवेंट को एक अति-जेड-इंडेक्स के साथ एक पारदर्शी ओवरले पर जोड़ना चाहते हैं जो दृश्यमान ओवरले पर कम जेड-इंडेक्स है। यह घटना को उच्चतम तत्व में रखेगा।

उदाहरण:

http://jsfiddle.net/scottux/z7yaB/

+0

सही उदाहरण, तो धन्यवाद। – Kate

+0

ऐसा करने का तरीका है! – BastienSander

0

सरल समाधान के बजाय dragenter उपयोग dragover

dragover इस का उपयोग करने का है घटना को निकाल दिया जाता है क्योंकि एक ड्रैग होने पर माउस को तत्व पर ले जाया जाता है। अधिकांश समय, श्रोता के दौरान होने वाला ऑपरेशन ड्रैगेंटर ईवेंट जैसा ही होगा।

+0

सिवाय इसके कि आप इसका पता नहीं लगा सकते जब यह ड्रॉप क्षेत्र छोड़ देता है। – cdmckay

+0

यह कोड को बार-बार आग लगने के लिए ओवरले की दृश्यता को बदलने का कारण बनता है, जो प्रदर्शन परिणामों के हो सकता है (या नहीं)। – ZachB

1
var dropZone = function() { 
     var self = this; 
     this.eTimestamp = 0; 
     this.showDropZone = function(e) { 
      e.stopPropagation(); 
      e.preventDefault(); 
      if (self.eTimestamp + 300 < e.timeStamp) { 
       $("#coverDropZone").show(); 
       self.eTimestamp = e.timeStamp; 
      } 
      return false; 
     } 
     this.hideDropZone = function(e) { 
      e.stopPropagation(); 
      e.preventDefault(); 
      if (self.eTimestamp + 300 < e.timeStamp) { 
       $("#coverDropZone").hide(); 
       self.eTimestamp = e.timeStamp; 
      } 
      return false; 
     } 
     this.showImage = function(e) { 
      e.stopPropagation(); 
      e.preventDefault(); 
      console.log(e); 
      return false; 
     } 
     document.addEventListener('dragenter', self.showDropZone, false); 
     document.addEventListener('dragleave', self.hideDropZone, false); 
     document.addEventListener('drop', self.showImage, false); 
    } 
+2

क्या आप कृपया अपना उत्तर समझा सकते हैं? विस्तार के बिना कोड पोस्ट करना दूसरों को भ्रमित कर सकता है एक ही मुद्दे के साथ। – Seth

+0

यह निश्चित रूप से कुछ स्पष्टीकरण की आवश्यकता है। – ouflak

+0

जब माउस विंडो में प्रवेश कर रहा है तो ड्रॉप-ज़ोन दिखाने के लिए इस कोड का उपयोग कर रहा हूं एक फाइल agging। ऑब्जेक्ट में एक प्रॉपर्टी है। ETimestamp जिसमें event.timeStamp और im जांच कर रहा है यदि एकाधिक फ़ायरिंग को रोकने के लिए दोनों घटनाओं के बीच कम से कम 300ms हैं (मुझे वह समस्या थी) –

संबंधित मुद्दे