এইচটিএমএল 5 ড্রাগলেভ যখন কোনও শিশু উপাদানকে ঘুরে বেড়াচ্ছে তখন তা নিক্ষেপ করা হয়েছে


300

আমার যে সমস্যাটি হচ্ছে তা হ'ল সেই dragleaveউপাদানটির একটি শিশু উপাদানকে ঘুরিয়ে দেওয়ার সময় কোনও এলিমেন্টের ঘটনাটি নষ্ট হয়ে যায়। এছাড়াও, dragenterপুনরায় প্যারেন্ট উপাদানকে ঘোরাফেরা করার সময় বরখাস্ত করা হয় না।

: আমি একটি সরলীকৃত বেহালার তৈরি http://jsfiddle.net/pimvdb/HU6Mk/1/

এইচটিএমএল:

<div id="drag" draggable="true">drag me</div>

<hr>

<div id="drop">
    drop here
    <p>child</p>
    parent
</div>

নিম্নলিখিত জাভাস্ক্রিপ্ট সহ:

$('#drop').bind({
                 dragenter: function() {
                     $(this).addClass('red');
                 },

                 dragleave: function() {
                     $(this).removeClass('red');
                 }
                });

$('#drag').bind({
                 dragstart: function(e) {
                     e.allowedEffect = "copy";
                     e.setData("text/plain", "test");
                 }
                });

এটি করার কথা যা হ'ল divসেখানে কিছু টেনে আনার সময় ব্যবহারকারীকে ড্রপকে লাল করে জানান not এটি কাজ করে, তবে আপনি যদি pশিশুটিকে টেনে নিয়ে যান তবে dragleaveগুলি চালানো হবে এবং এটি divআর লাল নয়। ড্রপটিতে ফিরে যাওয়াও divএটিকে আবার লাল করে না। এটি পুরোপুরি ড্রপ থেকে সরানো divএবং এটিকে আবার লাল করতে আবার এটিতে টেনে আনতে হবে।

dragleaveকোনও শিশু উপাদানকে টেনে আনলে কী গুলি চালানো থেকে বিরত রাখা সম্ভব ?

2017 আপডেট: টিএল; ডিআর, pointer-events: none;নীচে @ এইচডি এর উত্তর বর্ণিত সিএসএস দেখুন যা আধুনিক ব্রাউজার এবং আই 11 এ কাজ করে।


রিপোর্ট করা বাগ পিমভডিবি এখনও ২০১২ সালের মে পর্যন্ত ওয়েবকিটে উপস্থিত রয়েছে dra
এজেএম

2
@ আজম: ধন্যবাদ, এটি একটি পরিমাণে কাজ করে। যাইহোক, ক্রোমে, শিশু উপাদানটিতে প্রবেশ বা রেখে যাওয়ার সময় একটি ফ্ল্যাশ উপস্থিত থাকে সম্ভবত সম্ভবত কারণ dragleaveসেই ক্ষেত্রেই বহিস্কার রয়েছে।
pimvdb

আমি একটি জিকুয়েরি ইউআই বাগ খুলেছি আপগেটগুলি স্বাগত জানানো হচ্ছে যাতে তারা এটিতে সংস্থান
স্থাপনের

@ ফগুইলেন: আমি দুঃখিত তবে jQuery UI এর সাথে কোনও সম্পর্ক নেই। আসলে, jQuery এমনকি ত্রুটি ট্রিগার প্রয়োজন হয় না। আমি ইতিমধ্যে একটি ওয়েবকিট বাগ ফাইল করেছি তবে এখন পর্যন্ত কোনও আপডেট নেই।
pimvdb

2
@ pimvdb আপনি কেন এইচডি এর উত্তর গ্রহণ করবেন না?
টাইলার

উত্তর:


336

আপনার কেবল একটি রেফারেন্স কাউন্টার রাখা দরকার, যখন আপনি ড্রেজেটার পাবেন তখন এটি বাড়িয়ে তোলা হবে, যখন আপনি ড্র্যাগলেভে পাবেন তখন হ্রাস পাবে। যখন কাউন্টার 0 এ থাকে - ক্লাসটি সরিয়ে ফেলুন।

var counter = 0;

$('#drop').bind({
    dragenter: function(ev) {
        ev.preventDefault(); // needed for IE
        counter++;
        $(this).addClass('red');
    },

    dragleave: function() {
        counter--;
        if (counter === 0) { 
            $(this).removeClass('red');
        }
    }
});

দ্রষ্টব্য: ড্রপ ইভেন্টে শূন্য থেকে পাল্টা পুনরায় সেট করুন এবং যোগ করা ক্লাসটি সাফ করুন।

আপনি এটি এখানে চালাতে পারেন


8
ওএমজি এটি সর্বাধিক সুস্পষ্ট সমাধান এবং কেবলমাত্র একটি ভোট ছিল ... লোকেরা আসুন, আপনি আরও ভাল করতে পারেন। আমি সে সম্পর্কে ভাবছিলাম কিন্তু প্রথম কয়েকটি উত্তরের পরিশীলনের স্তরটি দেখার পরে আমি প্রায় এটি বাতিল করে দিয়েছি। আপনার কোন ত্রুটি আছে?
আর্থার কোরেঞ্জান

11
যখন টেনে আনার উপাদানটির প্রান্তটি অন্য ড্রাগেগ উপাদানের প্রান্তকে স্পর্শ করে তখন এটি কাজ করে না। উদাহরণস্বরূপ একটি বাছাইযোগ্য তালিকা; পরের ড্রাগেবল আইটেমটিকে নীচের দিকে টেনে নিয়ে যাওয়াটি কাউন্টারটিকে পিছনে 0 এ কমায় না, পরিবর্তে এটি 1 এ আটকে যায় But তবে আমি যদি এটিকে অন্যদিকে টেনে নিয়ে যায় এমন উপাদান থেকে বাইরে ধরে টেনে নিয়ে যাই, এটি কাজ করে। আমি pointer-events: noneবাচ্চাদের সাথে গেলাম । যখন আমি টানা শুরু করি তখন আমি এই শ্রেণিটি সংযুক্ত করি যেখানে এই সম্পত্তি রয়েছে, যখন আমি টেনে না নিয়ে ক্লাসটি সরিয়ে ফেলি। সাফারি এবং ক্রোমে সুন্দরভাবে কাজ করেছেন তবে ফায়ারফক্সে নয়।
আর্থার কোরেঞ্জান

13
এটি আমার জন্য সমস্ত ব্রাউজারে কাজ করেছিল তবে ফায়ারফক্স। আমার একটি নতুন সমাধান রয়েছে যা আমার ক্ষেত্রে সর্বত্র কাজ করে। প্রথমটিতে dragenterআমি event.currentTargetএকটি নতুন ভেরিয়েবলে সঞ্চয় করি dragEnterTarget। যতক্ষণ dragEnterTargetসেট করা থাকে ততক্ষণ আমি আরও dragenterইভেন্টগুলি উপেক্ষা করি কারণ সেগুলি শিশুদের থেকে। সমস্ত dragleaveইভেন্টে আমি পরীক্ষা করি dragEnterTarget === event.target। যদি এটি মিথ্যা হয় তবে ইভেন্টটি কোনও শিশু দ্বারা বরখাস্ত করার কারণে তা এড়ানো হবে। এটি সত্য হলে আমি পুনরায় সেট dragEnterTargetকরতে চাই undefined
পাইপো

3
দুর্দান্ত সমাধান। যদিও আমি ড্রপটি গ্রহণ করে এমন ফাংশনটিতে কাউন্টারটিকে 0 এ রিসেট করার দরকার ছিল, অন্যথায় পরবর্তী ড্রাগগুলি প্রত্যাশা অনুযায়ী কাজ করে নি।
লিয়াম জনস্টন

2
@ ওউডি আমি এখানে মন্তব্যগুলির বিশাল তালিকায় তার মন্তব্য দেখিনি, তবে হ্যাঁ, এটি ঠিক the কেন আপনার উত্তরের সাথে এটি অন্তর্ভুক্ত করবেন না?
বিটি

93

কোনও শিশু উপাদানকে টেনে আনলে ড্র্যাগেরেভকে গুলি চালানো থেকে বিরত রাখা কি সম্ভব?

হ্যাঁ.

#drop * {pointer-events: none;}

সেই সিএসএস Chrome এর জন্য যথেষ্ট বলে মনে হচ্ছে।

ফায়ারফক্সের সাথে এটি ব্যবহার করার সময়, # দ্রষ্ট্রে সরাসরি পাঠ্য নোডগুলি থাকা উচিত নয় (অন্যথায় একটি অদ্ভুত সমস্যা রয়েছে যেখানে কোনও উপাদান এটি "নিজের কাছে ছেড়ে দেয়" ), তাই আমি কেবলমাত্র একটি উপাদান দিয়ে রেখে দেওয়ার পরামর্শ দিই (উদাহরণস্বরূপ, ভিতরে একটি ডিভ ব্যবহার করুন) সব কিছু ভিতরে dropুকিয়ে দেওয়ার জন্য # পটভূমি)

মূল প্রশ্নটি (ভাঙা) উদাহরণটি সমাধান করার জন্য এখানে একটি জিসফিল দেওয়া আছে

আমি @ থিডোর ব্রাউন উদাহরণ থেকে একটি সরলীকৃত সংস্করণও তৈরি করেছি , তবে কেবল এই সিএসএসে ভিত্তিক।

সমস্ত ব্রাউজারে এই সিএসএস প্রয়োগ করা হয়নি, যদিও: http://caniuse.com/pointer-events

ফেসবুক উত্স কোডটি দেখে আমি এটি pointer-events: none;বেশ কয়েকবার খুঁজে পেতে পারি , তবে সম্ভবত এটি গ্রেফিউস ডিগ্রেশন ফ্যালব্যাকস সহ একসাথে ব্যবহৃত হয়েছে। কমপক্ষে এটি এত সহজ এবং অনেক পরিবেশের জন্য সমস্যাটি সমাধান করে।


পয়েন্টার-ইভেন্টস সম্পত্তি হ'ল সঠিক সমাধানটি এগিয়ে চলছে, তবে দুর্ভাগ্যক্রমে এটি IE8-IE10 এ কাজ করে না, যা এখনও ব্যাপকভাবে ব্যবহৃত হয়। এছাড়াও, আমার এটিও উল্লেখ করা উচিত যে আপনার বর্তমান জেএসফিডেল এমনকি আই 11 এও কাজ করে না, কারণ এটি প্রয়োজনীয় ইভেন্ট শ্রোতা এবং ডিফল্ট আচরণ প্রতিরোধ যুক্ত করে না।
থিওডোর ব্রাউন

2
পয়েন্টার-ইভেন্টগুলি ব্যবহার করা সত্যিই একটি ভাল উত্তর, আমি নিজের দ্বারা অনুসন্ধান করার আগে আমি কিছুটা লড়াই করেছি, উত্তরটি আরও বেশি হওয়া উচিত।
ফ্লোরাইবান

পুরানো ব্রাউজারগুলিকে সমর্থন না করার জন্য আমাদের যথেষ্ট ভাগ্যবানদের জন্য দুর্দান্ত বিকল্প।
লুক হ্যানসফোর্ড

7
আপনার বাচ্চারা যদি একটি বোতাম হয়? ও
ডেভিড

9
এটি কেবল তখনই কাজ করে যদি আপনার অঞ্চলে অন্যান্য নিয়ামক উপাদান (সম্পাদনা, মোছা) না থাকে, কারণ এই সমাধান
তাদেরকেও

45

এখানে, সহজতম ক্রস ব্রাউজার সমাধান (গুরুতরভাবে):

jsfiddle <- কিছু ফাইল বাক্সের ভিতরে টেনে আনার চেষ্টা করুন

আপনি এর মতো কিছু করতে পারেন:

var dropZone= document.getElementById('box');
var dropMask = document.getElementById('drop-mask');

dropZone.addEventListener('dragover', drag_over, false);
dropMask.addEventListener('dragleave', drag_leave, false);
dropMask.addEventListener('drop', drag_drop, false);

কয়েকটি কথায়, আপনি ড্রপজোনের ভিতরে একটি "মুখোশ" তৈরি করেন, প্রস্থ এবং উচ্চতা উত্তরাধিকার সূত্রে প্রাপ্ত, স্থিতিশীল অবস্থানের সাথে, ড্রাগগোভার শুরু হওয়ার পরে এটি প্রদর্শিত হবে।
সুতরাং, সেই মুখোশটি দেখানোর পরে, আপনি অন্যজনকে ড্র্যাগএলভে এড়িয়ে ড্রপ ইভেন্টগুলিতে সংযুক্ত করে কৌশলটি করতে পারেন।

ছাড়ার পরে বা নামার পরে, আপনি কেবল আবার মুখোশটি আড়াল করুন।
সহজ এবং জটিলতা ছাড়াই।

(ওবস: গ্রেগ পেটিট পরামর্শ - আপনি অবশ্যই নিশ্চিত হন যে মুখোশটি সীমান্ত সহ পুরো বাক্সটিকে ঘুরিয়ে দেবে)


কেন তা নিশ্চিত নয় তবে এটি ক্রোমের সাথে ধারাবাহিকভাবে কাজ করছে না। কখনও কখনও অঞ্চল ছেড়ে মাস্কটি দৃশ্যমান রাখে।
গ্রেগ পেটিট

2
আসলে, এটি সীমান্ত। নিজের কোনও সীমানা ছাড়াই সীমানাকে ওভারল্যাপিংয়ের মুখোশটি রাখুন এবং এটি ঠিকঠাক কাজ করা উচিত।
গ্রেগ পেটিট

1
মনে রাখবেন, আপনার jsfiddle, drag_drop, আপনি হোভার শ্রেণী "#box" এ না "# বক্স একটি" মুছে ফেলা আবশ্যক এটি একটি বাগ আছে
এনট্রপি

এটি একটি দুর্দান্ত সমাধান, তবে কোনওভাবে এটি আমার পক্ষে কার্যকর হয়নি। আমি অবশেষে একটি workaround খুঁজে বের করতে। আপনারা যারা তাদের জন্য অন্য কিছু খুঁজছেন For আপনি এটি চেষ্টা করতে পারেন: github.com/bingjie2680/jquery-draghover
bingjie2680

না, আমি শিশু উপাদানগুলির উপর নিয়ন্ত্রণ হারাতে চাই না। আমি একটি সহজ jQuery প্লাগইন তৈরি করেছি যা আমাদের জন্য কাজ করতে সমস্যাটি মোকাবেলা করে। আমার উত্তর পরীক্ষা করে দেখুন
লুকা ফাগিওলি

38

এই প্রশ্নটি জিজ্ঞাসা করার পরে বেশ কিছু সময় হয়েছে এবং প্রচুর সমাধান (কুরুচিপূর্ণ হ্যাক সহ) সরবরাহ করা হয়েছে।

আমি সম্প্রতি এই উত্তরের উত্তরটির জন্য একই সমস্যাটি সমাধান করতে সক্ষম হয়েছি এবং ভেবেছিলাম যে এই পৃষ্ঠায় আসা কারও পক্ষে এটি সহায়ক হতে পারে। পুরো ধারণা সঞ্চয় করতে হয় evenet.targetমধ্যে ondrageenterবাবা-মা বা শিশু উপাদানের কোনো তারা এগুলো বলা হয়। তারপরে ondragleaveচেক করে দেখুন যে বর্তমান টার্গেট ( event.target) আপনি সংরক্ষণ করেছেন সেই বস্তুর সমান ondragenter

যখন আপনার টানা ব্রাউজার উইন্ডোটি ছাড়ছে তখন কেবলমাত্র এই দুটির সাথেই মেলে।

এই সূক্ষ্ম কাজ করার কারণটি হ'ল মাউস যখন কোনও উপাদান (বলুন el1) ছেড়ে দেয় এবং অন্য উপাদানটিতে (বলে el2) প্রবেশ করে , প্রথমে el2.ondragenterবলা হয় এবং তারপরে el1.ondragleave। শুধুমাত্র যখন ড্র্যাগ ছাড়ছেন / ব্রাউজার উইন্ডোতে প্রবেশ event.targetহবে ''উভয় el2.ondragenter এবং el1.ondragleave

এখানে আমার কাজের নমুনা। আমি এটি IE9 +, ক্রোম, ফায়ারফক্স এবং সাফারিতে পরীক্ষা করেছি।

(function() {
    var bodyEl = document.body;
    var flupDiv = document.getElementById('file-drop-area');

    flupDiv.onclick = function(event){
        console.log('HEy! some one clicked me!');
    };

    var enterTarget = null;

    document.ondragenter = function(event) {
        console.log('on drag enter: ' + event.target.id);
        enterTarget = event.target;
        event.stopPropagation();
        event.preventDefault();
        flupDiv.className = 'flup-drag-on-top';
        return false;
    };

    document.ondragleave = function(event) {
        console.log('on drag leave: currentTarget: ' + event.target.id + ', old target: ' + enterTarget.id);
        //Only if the two target are equal it means the drag has left the window
        if (enterTarget == event.target){
            event.stopPropagation();
            event.preventDefault();
            flupDiv.className = 'flup-no-drag';         
        }
    };
    document.ondrop = function(event) {
        console.log('on drop: ' + event.target.id);
        event.stopPropagation();
        event.preventDefault();
        flupDiv.className = 'flup-no-drag';
        return false;
    };
})();

এবং এখানে একটি সহজ এইচটিএমএল পৃষ্ঠা:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Multiple File Uploader</title>
<link rel="stylesheet" href="my.css" />
</head>
<body id="bodyDiv">
    <div id="cntnr" class="flup-container">
        <div id="file-drop-area" class="flup-no-drag">blah blah</div>
    </div>
    <script src="my.js"></script>
</body>
</html>

যথাযথ স্টাইলিংয়ের মাধ্যমে আমি যা করেছি তা হ'ল অভ্যন্তরীণ ডিভ (# ফাইল-ড্রপ-অঞ্চল) অনেক বড় করা যখনই কোনও ফাইল স্ক্রিনে টানা হয় যাতে ব্যবহারকারী সহজেই ফাইলগুলি যথাযথ জায়গায় ফেলে দিতে পারে।


4
এটি সর্বোত্তম সমাধান, এটি কাউন্টারের চেয়ে ভাল (বিশেষত যদি আপনি ইভেন্টগুলি প্রতিনিধিত্ব করেন) এবং এটি ড্রাগেবল বাচ্চাদের সাথেও কাজ করে।
ফ্রেড

3
এটি নকল ড্রেজেটার ইভেন্টগুলির সমস্যার জন্য সহায়তা করে না
বিটি

এটি কি "বাচ্চাদের" জন্য কাজ করে যা সিএসএস সিউডো-উপাদান বা সিউডো-ক্লাস হয়? আমি এটি পেতে পারি না, তবে সম্ভবত আমি এটি ভুল করছিলাম।
জোশ ব্লিচার স্নাইডার

1
এটা কাজ করেছে! অন্যরা না, ধন্যবাদ!
বেরসান

1
2020 সালের মার্চ পর্যন্ত আমি এই সমাধানটির সাথেও শুভকামনা পেয়েছি। দ্রষ্টব্য: কিছু লিটার ==ওভার ব্যবহার সম্পর্কে অভিযোগ করতে পারে ===। আপনি ইভেন্ট টার্গেট অবজেক্ট রেফারেন্স তুলনা করছেন, তাই ===খুব ভাল কাজ করে।
অ্যালেক্স

33

এই সমস্যাটি সমাধানের "ডান" উপায়টি হ'ল ড্রপ টার্গেটের শিশু উপাদানগুলিতে পয়েন্টার ইভেন্টগুলি অক্ষম করা (@ এইচডি এর উত্তর হিসাবে)। এখানে আমি তৈরি করেছি একটি জেএসফিডাল যা এই কৌশলটি প্রদর্শন করে । দুর্ভাগ্যক্রমে, এটি IE11 এর আগে ইন্টারনেট এক্সপ্লোরারের সংস্করণগুলিতে কাজ করে না, যেহেতু তারা পয়েন্টার ইভেন্টগুলিকে সমর্থন করে না

ভাগ্যক্রমে, আমি এমন একটি কাজের সাথে আসতে সক্ষম হয়েছি যা আইই এর পুরানো সংস্করণগুলিতে কাজ করে । মূলত, এটিতে dragleaveশিশুদের উপাদানগুলি টেনে আনার সময় ঘটে যাওয়া ইভেন্টগুলি সনাক্ত করা এবং উপেক্ষা করা জড়িত । কারণ dragenterইভেন্টের আগে শিশু নোড উপর বহিস্কার করা হয় dragleaveপিতা বা মাতা এর ইভেন্টে আলাদা ঘটনা শ্রোতাকে প্রতিটি শিশুর নোড যা যোগ করতে অথবা ড্রপ লক্ষ্য থেকে একটি "অগ্রাহ্য-ড্র্যাগ ছুটি" শ্রেণী মুছে ফেলার জন্য যোগ করা যাবে। তারপরে ড্রপ টার্গেটের dragleaveইভেন্ট শ্রোতা এই ক্লাসটির উপস্থিতি উপস্থিত কলগুলিকে কেবল উপেক্ষা করতে পারে। এখানে একটি জেএসফিডাল এই কার্যকারিতাটি প্রদর্শন করছে । এটি ক্রোম, ফায়ারফক্স এবং আই 8 + এ পরীক্ষিত এবং কাজ করছে।

হালনাগাদ:

আমি বৈশিষ্ট্য সনাক্তকরণ ব্যবহার করে একটি সংযুক্ত সমাধান প্রদর্শন করে একটি জেএসফিডেল তৈরি করেছি , যেখানে সমর্থিত হলে বর্তমানে পয়েন্টার ইভেন্টগুলি ব্যবহার করা হয় (বর্তমানে ক্রোম, ফায়ারফক্স এবং আইই ১১), এবং পয়েন্টার ইভেন্ট সমর্থনটি উপলব্ধ না হলে ব্রাউজারটি শিশু নোডগুলিতে ইভেন্টগুলি যুক্ত করতে ফিরে আসে (IE8) -10)।


এই উত্তরটি অবাঞ্ছিত গুলি চালানোর জন্য একাত্মক কর্মসূচী দেখায় তবে "শিশুদের উপাদানকে টেনে নিয়ে যাওয়ার সময় ড্র্যাগেরেভকে গুলি চালানো থেকে রক্ষা করা কি সম্ভব?" এই প্রশ্নটিকে অবহেলা করে? সম্পূর্ণরূপে।
এইচডি

ব্রাউজারের বাইরে থেকে কোনও ফাইল টেনে আনলে আচরণটি আশ্চর্যজনক হতে পারে। ফায়ারফক্সে আমি "সন্তানের প্রবেশ -> পিতামাতার প্রবেশ -> সন্তান রেখে যাওয়া -> সন্তানের প্রবেশ -> সন্তান রেখে যাওয়া" পিতামাতাকে না রেখেই পেয়েছি, যা "ওভার" ক্লাসে ফেলেছে। ওল্ড আইইয়ের অ্যাডএভেন্টলিস্টনারের জন্য একটি অ্যাচটিভেন্ট প্রতিস্থাপনের প্রয়োজন হবে।
এইচডি

এই সমাধানটি বুদবুদয়ের উপর দৃ strongly়ভাবে নির্ভর করে, সমস্ত অ্যাডএভেন্টলিস্টনারের "মিথ্যা "টিকে প্রয়োজনীয় হিসাবে জোর দেওয়া উচিত (যদিও এটি ডিফল্ট আচরণ) তবে যেহেতু অনেকেই এটি সম্পর্কে জানেন না।
এইচডি

সেই একক ড্রাগগ্রেবল ড্রপজোনটিতে এমন একটি প্রভাব যুক্ত করে যা ড্রপস্টোন ইভেন্টটিকে ট্রিগার না করে এমন অন্যান্য ড্রাগেবল অবজেক্টের জন্য ড্রপজোন ব্যবহার করার সময় উপস্থিত হয় না। অন্য হ্যান্ডলারের সাথে সত্যিকারের ড্রপজোন রাখার সময় টেনে আনার প্রভাবের জন্য সমস্ত কিছু সম্ভবত ড্রপজোন হিসাবে ব্যবহার করা তা করবে।
এইচডি

1
@ এইচডি আমি dragleaveক্রোম, ফায়ারফক্স এবং আইই ১১ + এ ইভেন্টটিকে গুলি চালানো থেকে বিরত রাখতে পয়েন্টার-ইভেন্টস সিএসএস সম্পত্তি ব্যবহার করার তথ্যের সাথে আমার উত্তর আপডেট করেছি । আইই 10 ছাড়াও আইই 8 এবং আই 9 সমর্থন করার জন্য আমি আমার অন্যান্য কর্মক্ষেত্র আপডেট করেছি। এটি ইচ্ছাকৃত যে ড্রপজোন এফেক্টটি কেবল তখন "টেনে আনুন" লিঙ্কটিকে টেনে এলে যুক্ত করা হয়। অন্যরা তাদের ব্যবহারের ক্ষেত্রে সমর্থন করার জন্য প্রয়োজন হিসাবে এই আচরণটি নির্দ্বিধায় অনুভব করতে পারে।
থিওডোর ব্রাউন

14

সমস্যাটি হ'ল dragleaveঘটনাটি যখন মাউসটি শিশু উপাদানটির সামনে চলে যায় তখন তা বরখাস্ত করা হয়।

e.targetউপাদানটি উপাদানটির মতো হয় কিনা তা পরীক্ষা করার জন্য আমি বিভিন্ন পদ্ধতি ব্যবহার করে দেখেছি this, তবে কোনও উন্নতি করতে পারিনি।

যেভাবে আমি এই সমস্যাটি ঠিক করেছি তা হ্যাকের কিছুটা হলেও, 100% কাজ করে।

dragleave: function(e) {
               // Get the location on screen of the element.
               var rect = this.getBoundingClientRect();

               // Check the mouseEvent coordinates are outside of the rectangle
               if(e.x > rect.left + rect.width || e.x < rect.left
               || e.y > rect.top + rect.height || e.y < rect.top) {
                   $(this).removeClass('red');
               }
           }

1
ধন্যবাদ! আমি তবে এটি ক্রোমে কাজ করতে পারি না। আপনি কি আপনার হ্যাকের একটি ওয়ার্কিং ফিডল সরবরাহ করতে পারেন?
pimvdb

3
আমিও কর্ডগুলি পরীক্ষা করে এটি করার কথা ভাবছিলাম। আপনি আমার জন্য বেশিরভাগ কাজ করেছেন, ধন্যবাদ :)। যদিও আমাকে কিছু সামঞ্জস্য করতে হয়েছিল:if (e.x >= (rect.left + rect.width) || e.x <= rect.left || e.y >= (rect.top + rect.height) || e.y <= rect.top)
ক্রিস্টফ

এটি ক্রোমে কাজ করবে না কারণ এটির ইভেন্টটি নেই e.xএবং e.y
হেনজি

আমি এই সমাধানটি পছন্দ করি। ফায়ারফক্সে আগে কাজ করিনি। তবে আপনি যদি e। এছাড়াও ক্রোমে কাজ করে।
নিকোল স্টুটজ

আমার জন্য ক্রোমে কাজ করেনি, ক্রিস বা ড্যানিয়েল স্টুটস যা বলেছিল তা-ও করেনি
টিমো হুভিনেন

14

আপনি যদি এইচটিএমএল 5 ব্যবহার করে থাকেন তবে আপনি পিতামাতার ক্লায়েন্টের রেকর্ডটি পেতে পারেন:

let rect = document.getElementById("drag").getBoundingClientRect();

তারপরে প্যারেন্ট.ড্রেগালভে ():

dragleave(e) {
    if(e.clientY < rect.top || e.clientY >= rect.bottom || e.clientX < rect.left || e.clientX >= rect.right) {
        //real leave
    }
}

এখানে একটি jsfiddle আছে


2
দুর্দান্ত উত্তর।
broc.seib 14

ধন্যবাদ বন্ধু, আমি সরল জাভাস্ক্রিপ্ট পদ্ধতির পছন্দ করি।
টিম গারহার্ড

উপাদানগুলি ব্যবহার করার border-radiusসময়, পয়েন্টারটি কোণার কাছাকাছি চলে যাওয়া আসলে উপাদানটি ছেড়ে যায় তবে এই কোডটি এখনও আমাদের ভিতরে থাকতে পারে বলে মনে হয় (আমরা উপাদানটি রেখে দিয়েছি তবে আমরা এখনও আবদ্ধ আয়তক্ষেত্রের মধ্যে আছি)। তারপরে dragleaveইভেন্ট হ্যান্ডলারটি মোটেই কল করা হবে না।
জয় দধনিয়া

11

একটি খুব সহজ সমাধান হ'ল pointer-eventsসিএসএস সম্পত্তি ব্যবহার করা । শুধু তার মান সেট noneউপরে dragstart প্রত্যেক সন্তানের উপাদান। এই উপাদানগুলি মাউস-সম্পর্কিত ইভেন্টগুলি আর ট্রিগার করবে না, সুতরাং তারা তাদের উপরের উপরের মাউসটি ধরবে না এবং এভাবে পিতামাতার উপরের ড্রাগলভেটিকে ট্রিগার করবে না ।

autoটানা শেষ করার পরে এই সম্পত্তিটি আবার সেট করতে ভুলবেন না ;)


11

এই মোটামুটি সহজ সমাধান আমার জন্য এখন পর্যন্ত কাজ করছে, ধরে নিচ্ছি আপনার ইভেন্টটি প্রতিটি ড্রাগ উপাদান পৃথকভাবে সংযুক্ত রয়েছে।

if (evt.currentTarget.contains(evt.relatedTarget)) {
  return;
}

এটা অসাধারণ! @ অ্যালেন্থ ভাগ করার জন্য ধন্যবাদ, আপনি আমার দিন বাঁচিয়েছেন! অন্যান্য উত্তরগুলি কেবলমাত্র যদি আপনার একক ড্রপযোগ্য জোন থাকে তবে প্রয়োগ হয়।
এন্টোনি

আমার জন্য এটি ক্রোম এবং ফায়ারফক্সে কাজ করে তবে আইডিতে এজ তে কাজ হয় না। দয়া করে দেখুন: jsfiddle.net/iwiss/t9pv24jo
iwis


7

আপনি jQuery উত্স কোড থেকে কিছুটা অনুপ্রেরণা দিয়ে এটি ফায়ারফক্সে ঠিক করতে পারেন :

dragleave: function(e) {
    var related = e.relatedTarget,
        inside = false;

    if (related !== this) {

        if (related) {
            inside = jQuery.contains(this, related);
        }

        if (!inside) {

            $(this).removeClass('red');
        }
    }

}

দুর্ভাগ্যক্রমে এটি ক্রোমে কাজ করে না কারণ relatedTargetপ্রদর্শিত হচ্ছে dragleaveইভেন্টগুলিতে উপস্থিত নেই এবং আমি ধরে নিয়েছি আপনি Chrome এ কাজ করছেন কারণ আপনার উদাহরণটি ফায়ারফক্সে কাজ করে নি। উপরোক্ত কোডটি প্রয়োগ করে এখানে একটি সংস্করণ দেওয়া আছে।


অনেক ধন্যবাদ, তবে প্রকৃতপক্ষে এটি ক্রোম আমি এই সমস্যাটি সমাধান করার চেষ্টা করছি
pimvdb

5
@ পিমভিডিবি আমি দেখতে পেয়েছি আপনি একটি বাগ লগ করেছেন , অন্য কেউ যদি এই উত্তরটি না দেখেন আমি কেবল এখানে একটি রেফারেন্স এখানে রেখে দেব।
রবার্টক

আমি সত্যিই করেছি, তবে আমি এখানে একটি লিঙ্ক যুক্ত করতে ভুলে গেছি। এটা করার জন্য ধন্যবাদ।
pimvdb

ক্রোম বাগটি মাঝামাঝি সময়ে স্থির করা হয়েছে।
পিএইচকে

7

এবং এটি এখানে যায়, ক্রোমের জন্য একটি সমাধান:

.bind('dragleave', function(event) {
                    var rect = this.getBoundingClientRect();
                    var getXY = function getCursorPosition(event) {
                        var x, y;

                        if (typeof event.clientX === 'undefined') {
                            // try touch screen
                            x = event.pageX + document.documentElement.scrollLeft;
                            y = event.pageY + document.documentElement.scrollTop;
                        } else {
                            x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                            y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
                        }

                        return { x: x, y : y };
                    };

                    var e = getXY(event.originalEvent);

                    // Check the mouseEvent coordinates are outside of the rectangle
                    if (e.x > rect.left + rect.width - 1 || e.x < rect.left || e.y > rect.top + rect.height - 1 || e.y < rect.top) {
                        console.log('Drag is really out of area!');
                    }
                })

এটি কি «যদি (typof ইভেন্ট.clientX === 'অপরিজ্ঞাত') into এ যায়?
অ্যালডেকেইন

1
সুন্দরভাবে কাজ করেছেন তবে ব্রাউজারের উপরে অন্য উইন্ডো থাকতে পারে, তাই মাউসের অবস্থান পাওয়া এবং এটি আয়তক্ষেত্রাকার পর্দার সাথে তুলনা করা যথেষ্ট নয়।
এইচডি

আমি border-radius@ এইচডি এর সাথেও একমত, এছাড়াও উপরের @ আজলারের জবাব সম্পর্কে আমার মন্তব্যে যেমন ব্যাখ্যা করা হয়েছে তত বড় উপাদানগুলির কারণ হতে পারে
জয় দধনিয়া

7

ডকুমেন্ট.ইলেটমেন্টফ্রন্টপয়েন্ট ব্যবহার করে এখানে আরও একটি সমাধান দেওয়া হয়েছে:

 dragleave: function(event) {
   var event = event.originalEvent || event;
   var newElement = document.elementFromPoint(event.pageX, event.pageY);
   if (!this.contains(newElement)) {
     $(this).removeClass('red');
   }
}

আশা করি এটি কার্যকর, এখানে একটি মূর্খতা


3
এই বাক্স থেকে আমার জন্য কাজ করে না। event.clientX, event.clientYপরিবর্তে আমার ব্যবহার করা দরকার, যেহেতু তারা পৃষ্ঠার চেয়ে ভিউপোর্টের সাথে সম্পর্কিত। আমি আশা করি এটি সেখানে অন্য হারানো আত্মাকে সাহায্য করবে।
জন আব্রামস

7

একটি সহজ সমাধান হ'ল সিএসএস নিয়মটি pointer-events: noneসন্তানের উপাদানটিতে যুক্ত করা ট্রিগারটি রোধ করতে ondragleave। উদাহরণ দেখুন:

function enter(event) {
  document.querySelector('div').style.border = '1px dashed blue';
}

function leave(event) {
  document.querySelector('div').style.border = '';
}
div {
  border: 1px dashed silver;
  padding: 16px;
  margin: 8px;
}

article {
  border: 1px solid silver;
  padding: 8px;
  margin: 8px;
}

p {
  pointer-events: none;
  background: whitesmoke;
}
<article draggable="true">drag me</article>

<div ondragenter="enter(event)" ondragleave="leave(event)">
  drop here
  <p>child not triggering dragleave</p>
</div>


আমার একই সমস্যা ছিল এবং আপনার সমাধান দুর্দান্ত কাজ করে। অন্যদের জন্য পরামর্শ, এটি আমার ক্ষেত্রে ছিল: আপনি যে শিশু উপাদানটিকে ড্রাগ করার ঘটনাটিকে অগ্রাহ্য করার চেষ্টা করছেন তা যদি উপাদানটিকে টেনে আনার ক্লোন হয় (ভিজ্যুয়াল পূর্বরূপ অর্জনের চেষ্টা করা হয়), ক্লোন তৈরি করার সময় আপনি এটি ভিতরে ড্রাগস্টার্ট ব্যবহার করতে পারেন :dragged = event.target;clone = dragged.cloneNode();clone.style.pointerEvents = 'none';
স্কারামোচে

4

নিশ্চিত না যে এই ক্রস ব্রাউজারটি, তবে আমি Chrome এ পরীক্ষা করেছি এবং এটি আমার সমস্যার সমাধান করে:

আমি পুরো পৃষ্ঠার উপরে একটি ফাইল টেনে আনতে চাই, তবে আমি যখন শিশু উপাদানকে টেনে নিয়ে যাই তখন আমার ড্র্যাগলেভ নিক্ষেপ করা হয়। আমার ফিক্সটি ছিল মাউসের এক্স এবং ওয়াইয়ের দিকে তাকানো:

আমার একটি ডিভ রয়েছে যা আমার পুরো পৃষ্ঠাটি ওভারল করে, যখন পৃষ্ঠাটি লোড হয় আমি এটি আড়াল করি।

আপনি যখন নথির উপরে টেনে আনেন আমি এটি দেখায় এবং আপনি যখন পিতামাতার উপরে পড়ে তখন তা এটি পরিচালনা করে এবং আপনি যখন পিতামাতাকে ছেড়ে যান তখন আমি x এবং y পরীক্ষা করে দেখি।

$('#draganddrop-wrapper').hide();

$(document).bind('dragenter', function(event) {
    $('#draganddrop-wrapper').fadeIn(500);
    return false;
});

$("#draganddrop-wrapper").bind('dragover', function(event) {
    return false;
}).bind('dragleave', function(event) {
    if( window.event.pageX == 0 || window.event.pageY == 0 ) {
        $(this).fadeOut(500);
        return false;
    }
}).bind('drop', function(event) {
    handleDrop(event);

    $(this).fadeOut(500);
    return false;
});

1
হ্যাকি কিন্তু চালাক। আমি পছন্দ করি. আমার জন্য কাজ করেছেন।
কাপকেকিডিড

1
ওহ, আমি এই উত্তরটি আরও ভোট পেতে চাই কিভাবে! ধন্যবাদ
কির্বি

4

এই সঠিক সমস্যাটি হ্যান্ডেল করার জন্য আমি ড্র্যাগস্টার নামে একটি ছোট্ট লাইব্রেরি লিখেছি , আইই তে চুপচাপ কিছু না করা বাদে সর্বত্র কাজ করে (যা ডম ইভেন্ট কনস্ট্রাক্টরকে সমর্থন করে না, তবে jQuery এর কাস্টম ইভেন্টগুলি ব্যবহার করে অনুরূপ কিছু লিখতে খুব সহজ হবে)


খুব দরকারী (কমপক্ষে আমার জন্য যেখানে আমি কেবল Chrome সম্পর্কে যত্নশীল)।
এম কাটজ

4

আমার একই সমস্যা ছিল এবং pk7s সমাধানটি ব্যবহার করার চেষ্টা করেছি। এটি কাজ করেছে তবে অতিরিক্ত ডোম উপাদান ছাড়াই এটি আরও কিছুটা ভাল করা যেতে পারে।

মূলত ধারণাটি একই - ড্রপযোগ্য ক্ষেত্রের উপরে একটি অতিরিক্ত অদৃশ্য ওভারলে যুক্ত করুন। কোনও অতিরিক্ত ডোম উপাদান ছাড়াই এটি করতে দেয়। এখানে অংশটি ছিল সিএসএস সিউডো-উপাদানগুলি খেলতে আসে।

জাভাস্ক্রিপ্ট

var dragOver = function (e) {
    e.preventDefault();
    this.classList.add('overlay');
};

var dragLeave = function (e) {
    this.classList.remove('overlay');
};


var dragDrop = function (e) {
    this.classList.remove('overlay');
    window.alert('Dropped');
};

var dropArea = document.getElementById('box');

dropArea.addEventListener('dragover', dragOver, false);
dropArea.addEventListener('dragleave', dragLeave, false);
dropArea.addEventListener('drop', dragDrop, false);

সিএসএস

এই নিয়মের পরে ড্রপযোগ্য ক্ষেত্রের জন্য পুরোপুরি আচ্ছাদিত ওভারলে তৈরি করবে।

#box.overlay:after {
    content:'';
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    z-index: 1;
}

এখানে সম্পূর্ণ সমাধান: http://jsfiddle.net/F6GDq/8/

আমি আশা করি এটি একই সমস্যা সহ যে কাউকে সহায়তা করে।


1
মাঝে মাঝে ক্রোমে কাজ করে না (ড্র্যাগলেভ সঠিকভাবে ধরেনা)
টিমো হুভিনেন

4

ড্র্যাগ ওভার এলিমেন্টটি যদি শিশু হয় তবে তা পরীক্ষা করে দেখুন, তবে আপনার 'ড্রাগোভার' স্টাইলের ক্লাসটি সরাবেন না। খুব সহজ এবং আমার জন্য কাজ করে:

 $yourElement.on('dragleave dragend drop', function(e) {
      if(!$yourElement.has(e.target).length){
           $yourElement.removeClass('is-dragover');
      }
  })

আমার কাছে সবচেয়ে সহজ সমাধান বলে মনে হচ্ছে এবং এটি আমার সমস্যার সমাধান করেছে। ধন্যবাদ!
ফ্রান্সেসকো মার্কেটি-স্টাসি

3

আমি একই সমস্যার জন্য হোঁচট খেয়েছি এবং আমার সমাধান এখানে দেওয়া হয়েছে - যা আমার মনে হয় উপরের চেয়ে অনেক সহজ। আমি নিশ্চিত নই যে এটি ক্রসব্রোজার (এমনকি বুদ্বুদী ক্রমের উপর নির্ভর করে)

আমি সরলতার জন্য jQuery ব্যবহার করব, তবে সমাধানটি কাঠামোর স্বতন্ত্র হওয়া উচিত।

ঘটনাটি পিতামাতার কাছে বুদবুদকে দেওয়া হয়:

<div class="parent">Parent <span>Child</span></div>

আমরা ইভেন্টগুলি সংযুক্ত করি

el = $('.parent')
setHover = function(){ el.addClass('hovered') }
onEnter  = function(){ setTimeout(setHover, 1) }
onLeave  = function(){ el.removeClass('hovered') } 
$('.parent').bind('dragenter', onEnter).bind('dragleave', onLeave)

এবং এটি সম্পর্কে। :) এটি কাজ করে, যদিও পিতামাতার উপর মৃত্যুর আগে শিশুদের আগুনের সূত্রপাত হওয়া সত্ত্বেও, আমরা এটি ক্রমটিকে কিছুটা বিপরীত করতে বিলম্ব করি, সুতরাং ক্লাসটি প্রথমে সরানো হয় এবং পরে মিলিসেকেন্ডের পরে পুনরায় প্রয়োগ করা হয়।


এই স্নিপেটটি কেবলমাত্র 'হোল্ড' শ্রেণিটিকে পরবর্তী টিক চক্রটি পুনরায় প্রয়োগ করে ('ড্রাগলেভ' ইভেন্টটিকে অকেজো করে তোলে) সরিয়ে ফেলা বাধা প্রদান করছে।
নাল

এটি অকেজো নয়। আপনি যদি পিতামাতাকে ছেড়ে যান তবে এটি প্রত্যাশার মতো কাজ করবে। এই সমাধানের শক্তিটি এটি সরলতা, এটি আদর্শ বা সর্বোত্তম নয়। আরও সলিউশন হ'ল কোনও সন্তানের প্রবেশের চিহ্নটি হ'ল, আমরা সবেমাত্র সন্তানের প্রবেশ করিয়েছি কিনা তা অন্লিভ চেক করে, এবং যদি তা না হলে ছুটির ইভেন্টটি ট্রিগার করা হয়। এটির জন্য টেস্টিং, অতিরিক্ত প্রহরী, নাতি-নাতনিদের জন্য চেক ইত্যাদির দরকার
পড়বে

3

আমি ড্রিপ-ড্রপ মডিউল লিখেছিলাম যার নাম ড্রিপ-ড্রপ যা অন্যদের মধ্যে এই অদ্ভুত আচরণকে স্থির করে। যদি আপনি একটি ভাল নিম্ন-স্তরের ড্র্যাগ-অ্যান্ড-ড্রপ মডিউলটি সন্ধান করছেন তবে আপনি যে কোনও কিছুর ভিত্তি হিসাবে ব্যবহার করতে পারেন (ফাইল আপলোড, অ্যাপ্লিকেশন ড্রাগ-এ-ড্রপ, বাইরের উত্স থেকে বা টেনে নিয়ে যাওয়া) আপনার এটি পরীক্ষা করা উচিত মডিউল আউট:

https://github.com/fresheneesz/drip-drop

আপনি ড্রিপ-ড্রপে যা করার চেষ্টা করছেন তা এইভাবেই করবেন:

$('#drop').each(function(node) {
  dripDrop.drop(node, {
    enter: function() {
      $(node).addClass('red')  
    },
    leave: function() {
      $(node).removeClass('red')
    }
  })
})
$('#drag').each(function(node) {
  dripDrop.drag(node, {
    start: function(setData) {
      setData("text", "test") // if you're gonna do text, just do 'text' so its compatible with IE's awful and restrictive API
      return "copy"
    },
    leave: function() {
      $(node).removeClass('red')
    }
  })
})

লাইব্রেরি ছাড়াই এটি করার জন্য, কাউন্টার টেকনিকটি হ'ল আমি ড্রিপ-ড্রপটিতে যা ব্যবহার করেছি, উচ্চতর রেট করা উত্তরটি গুরুত্বপূর্ণ পদক্ষেপগুলি মিস করে যা প্রথম ড্রপ ব্যতীত সমস্ত কিছুর জন্য জিনিসগুলি ভেঙে দেবে। এটি কীভাবে সঠিকভাবে করা যায় তা এখানে:

var counter = 0;    
$('#drop').bind({
    dragenter: function(ev) {
        ev.preventDefault()
        counter++
        if(counter === 1) {
          $(this).addClass('red')
        }
    },

    dragleave: function() {
        counter--
        if (counter === 0) { 
            $(this).removeClass('red');
        }
    },
    drop: function() {
        counter = 0 // reset because a dragleave won't happen in this case
    }
});

2

একটি বিকল্প কাজের সমাধান, কিছুটা সহজ।

//Note: Due to a bug with Chrome the 'dragleave' event is fired when hovering the dropzone, then
//      we must check the mouse coordinates to be sure that the event was fired only when 
//      leaving the window.
//Facts:
//  - [Firefox/IE] e.originalEvent.clientX < 0 when the mouse is outside the window
//  - [Firefox/IE] e.originalEvent.clientY < 0 when the mouse is outside the window
//  - [Chrome/Opera] e.originalEvent.clientX == 0 when the mouse is outside the window
//  - [Chrome/Opera] e.originalEvent.clientY == 0 when the mouse is outside the window
//  - [Opera(12.14)] e.originalEvent.clientX and e.originalEvent.clientY never get
//                   zeroed if the mouse leaves the windows too quickly.
if (e.originalEvent.clientX <= 0 || e.originalEvent.clientY <= 0) {

এটি ক্রোমে সর্বদা কাজ করে বলে মনে হয় না। আমি clientXমাউস বক্সের বাইরে থাকাকালীন উপলক্ষে 0 থেকে উপরে পেতে পারি । মঞ্জুর, আমার উপাদানগুলি হলেনposition:absolute
হেনজি

এটি কি সব সময় হয় বা কেবল কখনও কখনও হয়? কারণ যদি মাউসটি খুব দ্রুত গতিতে চলেছে (যেমন উইন্ডোর বাইরে), আপনি ভুল মান পেতে পারেন।
Profet

এটি 90% সময় ঘটে। এমন বিরল ঘটনা রয়েছে (10 বারের মধ্যে 1) যেখানে আমি এটি 0 এ পৌঁছাতে পারি I'll আমি আবার মাউসকে ধীর করে নিয়ে যাওয়ার চেষ্টা করব, তবে আমি বলতে পারি না আমি দ্রুত গতিতে চলেছি (সম্ভবত আপনি যাকে স্বাভাবিক গতি বলবেন)।
হেনজি

2

অনেক ঘন্টা ব্যয় করার পরেও আমি সেই পরামর্শটি পেয়েছি ঠিক যেমনটি ঠিক তেমন কাজ করে। আমি কেবল তখনই কিউ সরবরাহ করতে চেয়েছিলাম যখন ফাইলগুলি টেনে আনে এবং ডকুমেন্ট ড্রাগোভার, ড্রাগলিভ ক্রোম ব্রাউজারে বেদনাদায়ক ফ্লিকার সৃষ্টি করে।

এটিই আমি এটির সমাধান করেছি, ব্যবহারকারীর জন্য সঠিক সংকেতও দিচ্ছি।

$(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
});

1

আমার একই রকম সমস্যা ছিল - গুগল ক্রোমে ড্রপজোন ঝাঁকুনিতে পরিণতকারী শিশু উপাদানগুলিকে ঘোরাফেরা করার সময় শরীরের জন্য ড্রাগলভে ইভেন্টে ড্রপজোনটি লুকানোর জন্য আমার কোডটি বিতর্কিতভাবে বরখাস্ত করা হয়েছিল।

আমি এখুনি ফোন করার পরিবর্তে ড্রপজোনটি লুকানোর জন্য ফাংশনটি শিডিয়ুল করে এটি সমাধান করতে সক্ষম হয়েছি। তারপরে, অন্য কোনও ড্রাগগোভার বা ড্র্যাগলেভ বরখাস্ত করা থাকলে, নির্ধারিত ফাংশন কলটি বাতিল হয়ে যায়।

body.addEventListener('dragover', function() {
    clearTimeout(body_dragleave_timeout);
    show_dropzone();
}, false);

body.addEventListener('dragleave', function() {
    clearTimeout(body_dragleave_timeout);
    body_dragleave_timeout = setTimeout(show_upload_form, 100);
}, false);

dropzone.addEventListener('dragover', function(event) {
    event.preventDefault();
    dropzone.addClass("hover");
}, false);

dropzone.addEventListener('dragleave', function(event) {
    dropzone.removeClass("hover");
}, false);

এটি আমিও শেষ করেছিলাম, তবে এটি এখনও স্কেচি।
এমপেন

1

মাউস পয়েন্টার লক্ষ্য পাত্রে টেনে আনার জায়গা থেকে বের হয়ে গেলে " ড্রাগলভে " ইভেন্টটি নিক্ষেপ করা হয়।

যা অনেক কিছু বোঝায় যেহেতু অনেক ক্ষেত্রে কেবল পিতামাতাই ছাড়তে পারবেন এবং বংশধররাও নন। আমি মনে করি ইভেন্ট.স্টপপ্রোপেশন () উচিত এই পরিচালনা করা উচিত ছিল তবে মনে হয় এটি কৌশলটি করে না।

উপরে উল্লিখিত কিছু সমাধান বেশিরভাগ ক্ষেত্রেই কাজ করে বলে মনে হয় তবে সেই শিশুদের ক্ষেত্রে ব্যর্থ হয় যা ড্রেজেটার / ড্রাগলভে ইভেন্টগুলিকে সমর্থন করে না যেমন আইফ্রেমে

1 টি কার্যবিবরণী হ'ল ইভেন্টটি সম্পর্কিত তথ্যটি যাচাই করতে হবে এবং এটি কনটেইনারটির অভ্যন্তরে অবস্থান করে কিনা তা যাচাই করা হয় তবে ড্র্যাগলেভ ইভেন্টটি আমি এখানে যেমন করেছি তা উপেক্ষা করুন:

function isAncestor(node, target) {
    if (node === target) return false;
    while(node.parentNode) {
        if (node.parentNode === target)
            return true;
        node=node.parentNode;
    }
    return false;
}

var container = document.getElementById("dropbox");
container.addEventListener("dragenter", function() {
    container.classList.add("dragging");
});

container.addEventListener("dragleave", function(e) {
    if (!isAncestor(e.relatedTarget, container))
        container.classList.remove("dragging");
});

আপনি এখানে একটি কাজের ফিডল খুঁজে পেতে পারেন !


1

সলভ ..!

প্রাক্তনের জন্য কোনও অ্যারে ঘোষণা করুন:

targetCollection : any[] 

dragenter: function(e) {
    this.targetCollection.push(e.target); // For each dragEnter we are adding the target to targetCollection 
    $(this).addClass('red');
},

dragleave: function() {
    this.targetCollection.pop(); // For every dragLeave we will pop the previous target from targetCollection
    if(this.targetCollection.length == 0) // When the collection will get empty we will remove class red
    $(this).removeClass('red');
}

শিশু উপাদান সম্পর্কে চিন্তা করার দরকার নেই।


1

আমি এগুলির সাথে অনেকগুলি লড়াই করেছিলাম, এমনকি এই সমস্ত উত্তর পড়ার পরেও, এবং ভেবেছিলাম যে আমি আমার সমাধানটি আপনার সাথে ভাগ করে নিতে পারি, কারণ আমি অনুভব করেছি যে এটি সহজ পদ্ধতির একটি হতে পারে, যদিও কিছুটা আলাদা। আমার চিন্তা কেবল বাদ দেওয়া ছিলdragleave ইভেন্ট শ্রোতাকে পুরোপুরি এবং ড্র্যাগেন্টার ইভেন্টগুলিকে অকারণে চালিত করা হবে না তা নিশ্চিত করে প্রতিটি নতুন ড্রেজেটার ইভেন্টের সাথে ড্র্যাগেরভে আচরণকে কোডিং করা ছিল।

নীচের আমার উদাহরণে, আমার একটি টেবিল রয়েছে, যেখানে আমি টানা সারি সামগ্রীগুলি একে অপরের সাথে টানুন এবং ড্রপ এপিআইয়ের মাধ্যমে বিনিময় করতে সক্ষম হতে চাই। চালু করার জন্য dragenter, আপনি বর্তমানে সারি উপাদানটিতে একটি সিএসএস শ্রেণি যুক্ত করা হবে যেখানে আপনি বর্তমানে আপনার উপাদানটি টানছেন, এটি হাইলাইট করার জন্য এবং dragleaveএই শ্রেণিটি সরানো হবে।

উদাহরণ:

খুব বেসিক এইচটিএমএল টেবিল:

<table>
  <tr>
    <td draggable="true" class="table-cell">Hello</td>
  </tr>
  <tr>
    <td draggable="true" clas="table-cell">There</td>
  </tr>
</table>

আর dragenter ইভেন্ট হ্যান্ডলার ফাংশন, প্রতিটি টেবিলের সেল সম্মুখের জোড়া হয়েছে (সরাইয়া dragstart, dragover, drop, এবং dragendহ্যান্ডেলার, যা এই প্রশ্নের নির্দিষ্ট নয়, তাই এখানে কপি না):

/*##############################################################################
##                              Dragenter Handler                             ##
##############################################################################*/

// When dragging over the text node of a table cell (the text in a table cell),
// while previously being over the table cell element, the dragleave event gets
// fired, which stops the highlighting of the currently dragged cell. To avoid
// this problem and any coding around to fight it, everything has been
// programmed with the dragenter event handler only; no more dragleave needed

// For the dragenter event, e.target corresponds to the element into which the
// drag enters. This fact has been used to program the code as follows:

var previousRow = null;

function handleDragEnter(e) {
  // Assure that dragenter code is only executed when entering an element (and
  // for example not when entering a text node)
  if (e.target.nodeType === 1) {
    // Get the currently entered row
    let currentRow = this.closest('tr');
    // Check if the currently entered row is different from the row entered via
    // the last drag
    if (previousRow !== null) {
      if (currentRow !== previousRow) {
        // If so, remove the class responsible for highlighting it via CSS from
        // it
        previousRow.className = "";
      }
    }
    // Each time an HTML element is entered, add the class responsible for
    // highlighting it via CSS onto its containing row (or onto itself, if row)
    currentRow.className = "ready-for-drop";
    // To know which row has been the last one entered when this function will
    // be called again, assign the previousRow variable of the global scope onto
    // the currentRow from this function run
    previousRow = currentRow;
  }
}

কোডগুলিতে খুব বুনিয়াদি মন্তব্যগুলি বাকী রয়েছে, যেমন এই কোডটি আরম্ভকারীদের পক্ষেও স্যুট। আশা করছি এটি তোমার সাহায্যে আসবে! মনে রাখবেন যে এটি অবশ্যই কাজ করার জন্য আপনার অবশ্যই প্রতিটি টেবিল সেলে আমি উল্লিখিত সমস্ত ইভেন্ট শ্রোতাদের যুক্ত করতে হবে।


0

এখানে ইভেন্টগুলির সময় ভিত্তিক আরেকটি পদ্ধতি রয়েছে।

dragenterঘটনা সন্তান উপাদান থেকে প্রেষিত পিতা বা মাতা উপাদান ক্যাপচার করা যেতে পারে এবং এটা সবসময় সামনে ঘটে dragleave। এই দুটি ইভেন্টের মধ্যে সময় দেওয়া সম্ভব যেকোনও সম্ভব মাউস অ্যাকশনের চেয়ে সংক্ষিপ্ত, খাটো। সুতরাং, ধারণাটি হ'ল সময়টি মুখস্থ করা dragenterএবং dragleaveঘটনার পরে ফিল্টার হওয়া ইভেন্টগুলি "খুব দ্রুত নয়" পরে ফিল্টার করা ...

এই সংক্ষিপ্ত উদাহরণটি ক্রোম এবং ফায়ারফক্সে কাজ করে:

var node = document.getElementById('someNodeId'),
    on   = function(elem, evt, fn) { elem.addEventListener(evt, fn, false) },
    time = 0;

on(node, 'dragenter', function(e) {
    e.preventDefault();
    time = (new Date).getTime();
    // Drag start
})

on(node, 'dragleave', function(e) {
    e.preventDefault();
    if ((new Date).getTime() - time > 5) {
         // Drag end
    }
})

0

pimvdb ..

আপনি ড্র্যাগলেভের পরিবর্তে ড্রপ ব্যবহার করে কেন চেষ্টা করবেন না । এটা আমার জন্য কাজ করেছে। আশা করি এটি আপনার সমস্যার সমাধান করে।

দয়া করে জেএসফিডেলটি দেখুন: http://jsfiddle.net/HU6Mk/118/

$('#drop').bind({
                 dragenter: function() {
                     $(this).addClass('red');
                 },

                 drop: function() {
                     $(this).removeClass('red');
                 }
                });

$('#drag').bind({
                 dragstart: function(e) {
                     e.allowedEffect = "copy";
                     e.setData("text/plain", "test");
                 }
                });

2
যদি ব্যবহারকারী তাদের মন পরিবর্তন করে এবং ফাইলটি ব্রাউজারের বাইরে রেখে দেয় তবে এটি লাল থাকবে remain
ZachB

0

আপনি একটি transitioningপতাকা সহ একটি সময়সীমা ব্যবহার করতে পারেন এবং শীর্ষ উপাদানটি শুনতে পারেন। dragenter/ dragleaveশিশু ইভেন্ট থেকে ধারক পর্যন্ত বুদবুদ হবে।

যেহেতু dragenterধারকটির আগে শিশু উপাদানটি জ্বলতে থাকে dragleave, তাই আমরা 1 মিমি রূপান্তর হিসাবে পতাকা শোটি সেট করব ... dragleaveশ্রোতা 1 এমএস শেষ হওয়ার আগে পতাকাটি পরীক্ষা করবে।

পতাকাটি কেবলমাত্র শিশু উপাদানগুলিতে স্থানান্তরিত হওয়ার সময় সত্য হবে এবং পিতামাতার উপাদানগুলিতে স্থানান্তরিত করার সময় এটি সত্য হবে না (ধারকটির)

var $el = $('#drop-container'),
    transitioning = false;

$el.on('dragenter', function(e) {

  // temporarily set the transitioning flag for 1 ms
  transitioning = true;
  setTimeout(function() {
    transitioning = false;
  }, 1);

  $el.toggleClass('dragging', true);

  e.preventDefault();
  e.stopPropagation();
});

// dragleave fires immediately after dragenter, before 1ms timeout
$el.on('dragleave', function(e) {

  // check for transitioning flag to determine if were transitioning to a child element
  // if not transitioning, we are leaving the container element
  if (transitioning === false) {
    $el.toggleClass('dragging', false);
  }

  e.preventDefault();
  e.stopPropagation();
});

// to allow drop event listener to work
$el.on('dragover', function(e) {
  e.preventDefault();
  e.stopPropagation();
});

$el.on('drop', function(e) {
  alert("drop!");
});

জেএসফিডাল: http://jsfiddle.net/ilovett/U7mJj/


0

আপনাকে ড্র্যাগ টার্গেটের সমস্ত শিশু অবজেক্টের জন্য পয়েন্টার ইভেন্টগুলি সরিয়ে ফেলতে হবে।

function disableChildPointerEvents(targetObj) {
        var cList = parentObj.childNodes
        for (i = 0; i < cList.length; ++i) {
            try{
                cList[i].style.pointerEvents = 'none'
                if (cList[i].hasChildNodes()) disableChildPointerEvents(cList[i])
            } catch (err) {
                //
            }
        }
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.