2013-04-11 7 views
18

अवलोकन:अद्यतन jquery.event.drag में dragstart आग के बाद उपलब्ध ड्रॉप लक्ष्य

मैं एक पृष्ठ jquery.event.drag और jquery.event.drop का उपयोग करता है। मुझे ड्रैग शुरू होने के बाद भी उन तत्वों पर खींचने और ड्रॉप करने में सक्षम होना चाहिए जिन्हें लगातार डोम में जोड़ा जा रहा है।


समस्या:

dragstart ईवेंट सक्रिय जब यह उपलब्ध ड्रॉप लक्ष्य के लिए जाँच करता है और उन्हें खींचें वस्तु के लिए कहते हैं।

मेरी समस्या यह है कि dragstart घटना समाप्त होने के बाद, मैं गतिशील रूप से ड्रॉप लक्ष्य जोड़ रहा हूं, और इसलिए उपयोगकर्ता इन गतिशील रूप से जोड़े गए ड्रॉप लक्ष्यों पर नहीं जा सकते हैं।


उदाहरण:

http://jsfiddle.net/blowsie/36AJq/


प्रश्न:

मैं खींचें अद्यतन कर सकते हैं कैसे तत्वों जिसके बाद डोम में जोड़ा गया है पर छोड़ने की अनुमति के लिए ड्रैग शुरू हो गया है?

उत्तर

5

आप इस स्निपेट का उपयोग कर सकते हैं।

महत्वपूर्ण कार्य है: $.event.special.drop.locate();

क्रोम/सफारी/फ़ायरफ़ॉक्स/IE9 पर परीक्षण किया गया और काम करने के लिए लगता है।

SEE DEMO


अद्यतन

वाली ईवेंट के लिए निम्न कोड काम करता है या नहीं। मैंने इसे किसी भी वैश्विक चर से बचने के लिए बस एक अज्ञात फ़ंक्शन के अंदर सेट किया है। आइडिया घटना की वर्तमान लक्ष्य संपत्ति का उपयोग करना है यह जांचने के लिए कि क्या वही तत्व उसी ईवेंट को ट्रिगर नहीं कर रहा है या नहीं। मैंने यहां परीक्षण के उद्देश्य से न्यूड्रोप तत्व पर एक आईडी सेट की है।

SEE UPDATED DEMO

(function() { 
    var $body = $("body"), 
     newdrops = [], 
     currentTarget = {}, 
     ondragstart = function() { 

      $(this).css('opacity', .75); 
     }, ondrag = function (ev, dd) { 
      $(this).css({ 
       top: dd.offsetY, 
       left: dd.offsetX 
      }); 
     }, ondragend = function() { 

      $(this).css('opacity', ''); 
      for (var i = 0, z = newdrops.length; i < z; i++) 
      $(newdrops[i]).off('dropstart drop dropend').removeClass('tempdrop'); 
      newdrops = []; 
     }, ondropstart = function (e) { 
      if (currentTarget.dropstart === e.currentTarget) return; 
      currentTarget.dropstart = e.currentTarget; 
      currentTarget.dropend = null; 
      console.log('start::' + e.currentTarget.id) 
      $(this).addClass("active"); 
     }, ondrop = function() { 
      $(this).toggleClass("dropped"); 
     }, ondropend = function (e) { 
      if (currentTarget.dropend === e.currentTarget) return; 
      currentTarget.dropend = e.currentTarget; 
      currentTarget.dropstart = null; 
      console.log('end::' + e.currentTarget.id) 
      $(this).removeClass("active"); 
     }; 

    $body.on("dragstart", ".drag", ondragstart) 
     .on("drag", ".drag", ondrag) 
     .on("dragend", ".drag", ondragend) 
     .on("dropstart", ".drop", ondropstart) 
     .on("drop", ".drop", ondrop) 
     .on("dropend", ".drop", ondropend); 



    var cnt = 0; 
    setInterval(function() { 
     var dataDroppables = $body.data('dragdata')['interactions'] ? $body.data('dragdata')['interactions'][0]['droppable'] : []; 

     var $newDrop = $('<div class="drop tempdrop" id="' + cnt + '">Drop</div>'); 
     cnt++; 
     $("#dropWrap").append($newDrop); 
     var offset = $newDrop.offset(); 
     var dropdata = { 
      active: [], 
      anyactive: 0, 
      elem: $newDrop[0], 
      index: $('.drop').length, 
      location: { 
       bottom: offset.top + $newDrop.height(), 
       elem: $newDrop[0], 
       height: $newDrop.height(), 
       left: offset.left, 
       right: offset.left + $newDrop.width, 
       top: offset.top, 
       width: $newDrop.width 
      }, 
      related: 0, 
      winner: 0 
     }; 
     $newDrop.data('dropdata', dropdata); 
     dataDroppables.push($newDrop[0]); 
     $newDrop.on("dropstart", ondropstart) 
      .on("drop", ondrop) 
      .on("dropend", ondropend); 
     $.event.special.drop.locate($newDrop[0], dropdata.index); 
     newdrops.push($newDrop[0]); 
    }, 1000); 
})(); 
+0

देख रहे हैं अच्छा काम! मुझे लगता है कि Blowsie प्रसन्न होगा –

+0

'डेटा ('ड्रैगडाटा') ['इंटरैक्शन'] 'सुंदर कुंजी थी! धन्यवाद – Blowsie

+0

यह भी कोई विचार है कि आप ईवेंट ओवरलैपिंग को कैसे रोक सकते हैं? Http://jsfiddle.net/blowsie/qtnQF/2/ – Blowsie

-1

refreshPositions option सक्षम करें।

+0

ओपी jQueryUI का उपयोग नहीं कर रहा है। –

+0

भी ताज़ा करें JQUI में समस्या का समाधान नहीं करता है http://bugs.jqueryui.com/ticket/7619 – Blowsie

-2

सभी divs को पृष्ठ में क्यों न रखें और अपनी दृश्यता को छिपाने के लिए सेट करें? फिर प्रत्येक सेकेंड की दृश्यता को बदलने के लिए setInterval() का उपयोग करें।

+0

डोम आकार को नीचे रखने और प्रदर्शन में सुधार करने के लिए तत्वों को गतिशील रूप से जोड़ा और हटा दिया जाता है – Blowsie

+0

@ ब्लॉसी क्या यदि आप अपनी चौड़ाई/ऊंचाई 0 पर सेट करते हैं और फिर इसे प्रत्येक सेकेंड के आवश्यक आकार में बढ़ा देते हैं। – Tobi

+0

वे अभी भी डोम और धीमे में होंगे, फिर उनका आकार बदलने से एक रिफ्लो होगा। यह वास्तव में एक व्यावहारिक विकल्प नहीं है – Blowsie

0

आप नहीं कर सकते। dragstart पर, संभव ड्रॉप ज़ोन की गणना DOM से की जाती है, और इसे dragend तक संपादित नहीं किया जा सकता है। यहां तक ​​कि लगातार .on() (डेमो: http://jsfiddle.net/36AJq/84/) को वांछित प्रभाव प्रदान नहीं करेगा।

मैंने इस मुद्दे को थोड़ा अलग हल किया। (डेमो: http://jsfiddle.net/36AJq/87/)

  1. एचटीएमएल में प्रत्येक <div> के साथ शुरू करें।
  2. इसे अदृश्य बनाने के लिए opacity: 0 लागू करें, और width: 0 इसे छुपाए जाने पर dropend प्राप्त करने से रोकने के लिए।
  3. प्रत्येक 1000ms के अगले छिपे हुए div ($('.drop:not(.visible)').first()) को दिखाने के लिए setInterval का उपयोग करें।

जे एस:

$("body") 
    .on("dragstart", ".drag", function() { 
    $(this).css('opacity', .75); 
    }) 
    .on("drag", ".drag", function (ev, dd) { 
    $(this).css({ 
     top: dd.offsetY, 
     left: dd.offsetX 
    }); 
    }) 
    .on("dragend", ".drag", function() { 
    $(this).css('opacity', ''); 
    }) 
    .on("dropstart", ".drop", function() { 
    $(this).addClass("active"); 
    }) 
    .on("drop", ".drop", function() { 
    $(this).toggleClass("dropped"); 
    }) 
    .on("dropend", ".drop", function() { 
    $(this).removeClass("active"); 
    }); 
setInterval(function() { 
    $('.drop:not(.visible)').first() 
     .addClass('visible').removeClass('hidden'); 
}, 1000) 
+0

क्या डाउनवॉटर कृपया मुझे बताएगा कि उन्होंने मेरा जवाब क्यों कम किया? – Mooseman

+1

मैं डाउनवॉटर नहीं हूं, लेकिन चूंकि आपने मुझे सही समाधान से कम करने के लिए डाउनोट किया है, इसलिए मैं आपकी समस्या को इंगित करूंगा। ड्रैगिंग शुरू होने पर सभी ड्रॉप लक्ष्य बनाए जाने की आवश्यकता होती है, जब सवाल का सबसे आवश्यक हिस्सा गति लक्ष्य को गतिशील रूप से जोड़ने की आवश्यकता होती है। –

+0

@AliGangji अगर आप एक संपादन करते हैं, तो मैं डाउनवोट को हटा सकता हूं। – Mooseman

1

मैं इस jquery.event.drag और jquery.event.drop काम कर रहा का उपयोग कर प्राप्त करने में सक्षम नहीं था, लेकिन मैं इसे देशी एचटीएमएल 5 घटनाओं के साथ काम किया:

http://jsfiddle.net/R2B8V/1/

समाधान एक समारोह के भीतर ड्रॉप ठिकानों पर घटनाओं के लिए बाध्य और कॉल कि बाइंडिंग अद्यतन करने के लिए किया गया था।मुझे संदेह है कि आप एक समान प्रिंसिपल का उपयोग कर jquery.event.drag और jquery.event.drop के साथ काम कर सकते हैं। अगर मैं उन कामों को प्राप्त कर सकता हूं तो मैं अपना जवाब अपडेट करूंगा।

यहाँ जेएस है:

$(function() { 
    var bind_targets = function() { 
     $(".drop").on({ 
      dragenter: function() { 
       $(this).addClass("active"); 
       return true; 
      }, 
      dragleave: function() { 
       $(this).removeClass("active"); 
      }, 
      drop: function() { 
       $(this).toggleClass("dropped"); 
      } 
     }); 
    };  

    $("div[draggable]").on({ 
     dragstart: function(evt) { 
      evt.originalEvent.dataTransfer.setData('Text', 'data'); 
     }, 
     dragend: function(evt) { 
      $('.active.drop').removeClass('active'); 
     } 
    }); 
    setInterval(function() { 
     $("#dropWrap").append('<div class="drop">Drop</div>'); 
     // Do something here to update the dd.available 
     bind_targets(); 
    }, 1000) 
}); 
+0

पर होगा, इसमें दो समस्याएं हैं: ब्राउज़र तुलनात्मकता और अनुकूलन। (उदाहरण के लिए, 'dragEnd' पर कर्सर स्थिति और '.drag' का स्थान।) – Mooseman

+0

मैंने यह नहीं कहा कि यह एक आदर्श समाधान था। मैं एक अवधारणा का वर्णन कर रहा था। –

+0

आपके द्वारा उल्लिखित अनुकूलन यहां लागू किया जा सकता है। ब्राउज़र संगतता के संबंध में, यह ब्राउज़र के विशाल बहुमत में काम करेगा। यह आईई 8 या उससे कम में काम नहीं करेगा, लेकिन यह एक समस्या नहीं है। –

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