wywołanie' dragleave ' elementu nadrzędnego podczas przeciągania elementów podrzędnych

Przegląd

Mam następującą strukturę HTML i dołączyłem zdarzenia dragenter i dragleave do elementu <div id="dropzone">.

<div id="dropzone">
    <div id="dropzone-content">
        <div id="drag-n-drop">
            <div class="text">this is some text</div>
            <div class="text">this is a container with text and images</div>
        </div>
    </div>
</div>

Problem

Gdy przeciągam plik nad <div id="dropzone">, Zdarzenie dragenter zostanie wywołane zgodnie z oczekiwaniami. Jednak gdy najadę myszką element potomny, taki jak <div id="drag-n-drop">, Zdarzenie dragenter zostanie wywołane dla elementu <div id="drag-n-drop">, a następnie zdarzenie dragleave zostanie wywołane dla elementu <div id="dropzone">.

Jeśli ponownie zawisnę nad elementem <div id="dropzone">, dragenter zdarzenie jest ponownie wywołane, co jest fajne, ale wtedy Zdarzenie dragleave jest wywołane dla elementu potomnego, który właśnie wyszedł, więc instrukcja removeClass jest wykonywana, co nie jest fajne.

To zachowanie jest problematyczne z dwóch powodów:]}
  1. I ' m only attaching dragenter & dragleave do <div id="dropzone"> więc nie rozumiem, dlaczego elementy dzieci mają te wydarzenia dołączone, jak również.

  2. Wciąż przeciągam element <div id="dropzone">, unosząc się nad jego dziećmi, więc nie chcę Ognia!

JsFiddle

Oto jsFiddle do majsterkowania: http://jsfiddle.net/yYF3S/2/

Pytanie

Więc... jak Mogę sprawić, że gdy przeciągam plik nad elementem <div id="dropzone">, dragleave nie odpala się, nawet jeśli przeciągam nad elementami potomnymi... powinien strzelać tylko wtedy, gdy opuszczę element <div id="dropzone">... w tym celu należy wykonać następujące czynności:]} wydarzenie.

Nie jest to jednak możliwe, ponieważ nie jest to możliwe w przypadku, gdy przeglądarka obsługuje HTML5 drag-n-drop, więc ta odpowiedź nie jest odpowiednia.

Wygląda na to, że Google i Dropbox domyśliły się tego, ale ich kod źródłowy jest minifikowany/złożony, więc nie byłem w stanie dowiedzieć się tego z ich implementacji.

Author: Brian Tompsett - 汤莱恩, 2012-06-03

22 answers

Jeśli nie trzeba wiązać zdarzeń z elementami potomnymi, zawsze można użyć właściwości pointer-events.

.child-elements {
  pointer-events: none;
}
 174
Author: Ben Rudolph,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-25 05:35:46

W końcu znalazłem rozwiązanie, z którego jestem zadowolony. Właściwie znalazłem kilka sposobów, aby zrobić to, co chcę, ale żaden nie był tak udany, jak obecne rozwiązanie... w jednym z rozwiązań doświadczyłem częstego migotania w wyniku dodawania / usuwania obramowania do elementu #dropzone... w innym przypadku ramka nigdy nie została usunięta, jeśli najedziesz kursorem na stronę przeglądarki.

W każdym razie, moje najlepsze hacky rozwiązanie jest to:

var dragging = 0;

attachEvent(window, 'dragenter', function(event) {

    dragging++;
    $(dropzone).addClass('drag-n-drop-hover');

    event.stopPropagation();
    event.preventDefault();
    return false;
});

attachEvent(window, 'dragover', function(event) {

    $(dropzone).addClass('drag-n-drop-hover');

    event.stopPropagation();
    event.preventDefault();
    return false;
});

attachEvent(window, 'dragleave', function(event) {

    dragging--;
    if (dragging === 0) {
        $(dropzone).removeClass('drag-n-drop-hover');
    }

    event.stopPropagation();
    event.preventDefault();
    return false;
});

To działa całkiem dobrze, ale problemy pojawiły się w Firefoksie, ponieważ Firefox był podwójne wywołanie dragenter więc mój licznik był wyłączony. Niemniej jednak nie jest to bardzo eleganckie rozwiązanie.

Wtedy natknąłem się na pytanie: Jak wykryć Zdarzenie dragleave w Firefoksie podczas przeciągania poza okno

Więc wziąłem odpowiedź i zastosowałem ją do mojej sytuacji:

$.fn.dndhover = function(options) {

    return this.each(function() {

        var self = $(this);
        var collection = $();

        self.on('dragenter', function(event) {
            if (collection.size() === 0) {
                self.trigger('dndHoverStart');
            }
            collection = collection.add(event.target);
        });

        self.on('dragleave', function(event) {
            /*
             * Firefox 3.6 fires the dragleave event on the previous element
             * before firing dragenter on the next one so we introduce a delay
             */
            setTimeout(function() {
                collection = collection.not(event.target);
                if (collection.size() === 0) {
                    self.trigger('dndHoverEnd');
                }
            }, 1);
        });
    });
};

$('#dropzone').dndhover().on({
    'dndHoverStart': function(event) {

        $('#dropzone').addClass('drag-n-drop-hover');

        event.stopPropagation();
        event.preventDefault();
        return false;
    },
    'dndHoverEnd': function(event) {

        $('#dropzone').removeClass('drag-n-drop-hover');

        event.stopPropagation();
        event.preventDefault();
        return false;
    }
});

Jest to czyste i eleganckie i wydaje się działać w każdej przeglądarce, którą do tej pory testowałem(nie testowałem jeszcze IE).

 59
Author: Hristo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:19

To jest trochę brzydkie, ale działa do cholery!...

Na Twoim 'dragenter' przechowuj Zdarzenie.target (W Zmiennej wewnątrz zamknięcia, lub cokolwiek), a następnie w' dragleave ' obsługi tylko odpalić Kod jeśli zdarzenie./ align = "left" /

Jeśli twój 'dragenter' uruchamia się, gdy nie chcesz (np. gdy wchodzi po opuszczeniu elementów potomnych), to ostatni raz, gdy uruchamia się, zanim mysz opuści rodzica, jest na rodzicu, więc rodzic zawsze będzie ostatni "dragenter" przed zamierzonym "dragleave".

(function () {

    var droppable = $('#droppable'),
        lastenter;

    droppable.on("dragenter", function (event) {
        lastenter = event.target;
        droppable.addClass("drag-over");            
    });

    droppable.on("dragleave", function (event) {
        if (lastenter === event.target) {
            droppable.removeClass("drag-over");
        }
    });

}());
 40
Author: hacklikecrack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-04 20:40:26

Na początku zgodziłem się z ludźmi odrzucającymi podejście. Ale wtedy zadałem sobie pytanie:

Czy do pracy z elementami potomnymi w trakcie przeciągania naprawdę potrzebne są zdarzenia pointera?

W moim przypadku, mam wiele rzeczy dzieje się w dzieci, np. najedź kursorem, aby pokazać przyciski dla dodatkowych działań, edycji inline, itp... Jednak żadne tego nie jest konieczne, a w rzeczywistości nawet pożądane podczas przeciągnięcia.

W moim przypadku używam coś takiego, aby wyłączać zdarzenia wskaźnika selektywnie dla wszystkich węzłów potomnych kontenera nadrzędnego:

  div.drag-target-parent-container.dragging-in-progress * {
    pointer-events: none;
  }

Użyj swojego ulubionego podejścia, aby dodać / usunąć klasę dragging-in-progress w dragEnter/dragLeave Obsługa zdarzeń, tak jak zrobiłem lub zrobiłem to samo w dragStart, et. al.

 32
Author: bargar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-03 18:21:55

To wygląda na błąd Chrome.

Jedynym obejściem, jakie mogłem wymyślić, było stworzenie przezroczystego elementu nakładki, aby uchwycić twoje Wydarzenia: http://jsfiddle.net/yYF3S/10/

JS :

$(document).ready(function() {
    var dropzone = $('#overlay');

    dropzone.on('dragenter', function(event) {
        $('#dropzone-highlight').addClass('dnd-hover');
    });

    dropzone.on('dragleave', function(event) {
        $('#dropzone-highlight').removeClass('dnd-hover');
    });

});​

HTML :

<div id="dropzone-highlight">
    <div id="overlay"></div>

    <div id="dropzone" class="zone">
        <div id="drag-n-drop">
            <div class="text1">this is some text</div>
            <div class="text2">this is a container with text and images</div>
        </div>
    </div>
</div>

<h2 draggable="true">Drag me</h2>
​
 12
Author: Blender,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-03 03:14:41

Problem polega na tym, że twoje elementy wewnątrz stref Dropzone są oczywiście częścią strefy dropzone i kiedy wejdziesz do dzieci, zostawisz rodzica. Rozwiązanie tego nie jest łatwe. Możesz też spróbować dodać zdarzenia do dzieci, dodając klasę ponownie do rodzica.

$("#dropzone,#dropzone *").on('dragenter', function(event) {

    // add a class to #dropzone

    event.stopPropagation(); // might not be necessary
    event.preventDefault();
    return false;
});

Twoje Wydarzenia nadal będą strzelać wiele razy, ale nikt nie zobaczy.

/ / Edit: użyj zdarzenia dragmove, aby trwale nadpisać Zdarzenie dragleave:

$("#dropzone,#dropzone *").on('dragenter dragover', function(event) {

    // add a class to #dropzone

    event.stopPropagation(); // might not be necessary
    event.preventDefault();
    return false;
});

Zdefiniuj Zdarzenie dragleave tylko dla dropzone.

 5
Author: Oliver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-03 03:16:58

Jako benr wspomniany w ta odpowiedź , możesz zapobiec uruchamianiu węzłów potomnych na zdarzeniach, ale jeśli chcesz powiązać niektóre zdarzenia, zrób to:

#dropzone.dragover *{
   pointer-events: none;
}

I dodaj ten do swojego kodu JS:

$("#dropzone").on("dragover", function (event) {
   $("#dropzone").addClass("dragover");
});

$("#dropzone").on("dragleave", function (event) {
   $("#dropzone").removeClass("dragover");
});
 4
Author: Vahid Ashrafian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:51

Jeśli używasz jQuery, sprawdź to: https://github.com/dancork/jquery.event.dragout

To jest naprawdę niesamowite.

Specjalne Zdarzenie stworzone do obsługi funkcji True dragleave.

HTML5 Zdarzenie dragleave działa bardziej jak mouseout. Ta wtyczka została stworzony, aby odtworzyć funkcjonalność stylu mouseleave podczas przeciąganie.

Przykład Użycia:

$('#myelement').on ('dragout', function (event){ // TWÓJ KOD });

EDIT: właściwie to nie jest zależne od jQuery, prawdopodobnie możesz po prostu użyć kodu nawet bez niego.

 3
Author: nkkollaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-23 18:56:37

@hristo mam o wiele bardziej eleganckie rozwiązanie. Sprawdź, czy to ci się przyda.

Twój wysiłek nie został jednak zmarnowany. Na początku udało mi się użyć Twojego, ale miałem inne problemy w FF, Chrome. Po spędzeniu tak wielu godzin otrzymałem tę sugestię działającą dokładnie tak, jak zamierzałem.

Oto jak wygląda implementacja. Skorzystałem również z wizualnych wskazówek, aby poprawnie kierować użytkowników o strefie zrzutu.

$(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
});
 2
Author: visitsb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-09 16:02:13

Moje dwa grosze: Ukryj warstwę nad dropzone, a następnie pokaż ją podczas przeciągania i celuj w nią.

Demo: https://jsfiddle.net/t6q4shat/

HTML

<div class="drop-zone">
  <h2 class="drop-here">Drop here</h2>
  <h2 class="drop-now">Drop now!</h2>
  <p>Or <a href="#">browse a file</a></p>
  <div class="drop-layer"></div>
</div>

CSS

.drop-zone{
  padding:50px;
  border:2px dashed #999;
  text-align:center;
  position:relative;
}
.drop-layer{
  display:none;
  position:absolute;
  top:0;
  left:0;
  bottom:0;
  right:0;
  z-index:5;
}
.drop-now{
  display:none;
}

JS

$('.drop-zone').on('dragenter', function(e){
    $('.drop-here').css('display','none');
    $('.drop-now').css('display','block');
    $(this).find('.drop-layer').css('display','block');
    return false;
});

$('.drop-layer').on('dragleave', function(e){
    $('.drop-here').css('display','block');
    $('.drop-now').css('display','none');
    $(this).css('display','none');
    return false;
});
 2
Author: jeremie.b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-29 14:21:13

Więc dla mnie podejście pointer-events: none; nie działało zbyt dobrze... Oto moje alternatywne rozwiązanie:

    #dropzone {
        position: relative;
    }

    #dropzone(.active)::after {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        content: '';
    }

W ten sposób nie jest możliwe dragleave rodzic (na dziecku) lub dragover element potomny. mam nadzieję, że to pomoże:)

*The '.active ' - klasa i dodana, gdy i dragenter lub dragleave. Ale jeśli pracujesz bez tego, po prostu zostaw klasę.

 1
Author: MMachinegun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-16 23:03:13

Super prosta szybka poprawka do tego, nie testowana intensywnie, ale działa teraz w Chrome.

Przepraszam za kawę.

  dragEndTimer = no

  document.addEventListener 'dragover', (event) ->
    clearTimeout dragEndTimer
    $('body').addClass 'dragging'
    event.preventDefault()
    return no

  document.addEventListener 'dragenter', (event) ->
    $('section').scrollTop(0)
    clearTimeout dragEndTimer
    $('body').addClass 'dragging'

  document.addEventListener 'dragleave', (event) ->
    dragEndTimer = setTimeout ->
      $('body').removeClass 'dragging'
    , 50

To naprawia błąd migotania Chrome, a przynajmniej jego permutację, która powodowała problemy.

 1
Author: Dom Vinyard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-06 12:38:43

Podoba mi się to, co widzę w https://github.com/lolmaus/jquery.dragbetter / ale chciał podzielić się możliwą alternatywą. Moja ogólna strategia polegała na zastosowaniu stylu tła do dropzone (Nie jego dzieci) podczas przeciągania go lub dowolnego dziecka z niego (poprzez bubbling). Następnie usuwam styl podczas przeciągania strefy upuszczania. Pomysł był przy przenoszeniu do dziecka, nawet jeśli usunę styl z dropzone podczas opuszczania go( odpala dragleave), po prostu ponownie zastosuję styl do parent dropzone na przeciąganie dowolnego dziecka. Problem polega oczywiście na tym, że podczas przechodzenia z dropzone do child of the dropzone, dragenter zostaje wystrzelony na dziecko przed dragleave, więc moje style zostały zastosowane Nie w porządku. Rozwiązaniem dla mnie było użycie timera, aby wymusić Zdarzenie dragenter z powrotem do kolejki komunikatów, co pozwoliło mi przetworzyć je po przeciągnięciu. Użyłem zamknięcia, aby uzyskać dostęp do wydarzenia na oddzwanianiu timera.

$('.dropzone').on('dragenter', function(event) {
  (function (event) {
    setTimeout(function () {
      $(event.target).closest('.dropzone').addClass('highlight');
    }, 0);
  }) (event.originalEvent); 
});

To chyba działa w chrome, ie, firefox i działa niezależnie od liczby dzieci w strefie zrzutu. Jestem nieco zaniepokojony czasem gwarantującym resekwencję zdarzeń, ale wydaje się, że działa całkiem dobrze dla mojego przypadku użycia.

 1
Author: mefopolis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-10 17:44:27

Odpowiedź można znaleźć tutaj:

HTML5 dragleave wywołany po umieszczeniu kursora na elemencie potomnym

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');
        }
    }
});
 1
Author: zeros-and-ones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:18

Moja wersja:

$(".dropzone").bind("dragover", function(e){
    console.log('dragover');
});

$(".dropzone").bind("dragleave", function(e) {
  var stopDrag = false;
  if (!e.relatedTarget) stopDrag = true;
  else {
    var parentDrop = $(e.relatedTarget).parents('.dropzone');
    if (e.relatedTarget != this && !parentDrop.length) stopDrag = true;
  }

  if (stopDrag) {
    console.log('dragleave');
  }
});

Z tym układem:

<div class="dropzone">
  <div class="inner-zone">Inner-zone</div>
</div>

Zrobiłem zrzut klas elementów dla e.target, e.currentTarget, e.relatedTarget zarówno dla dragover jak i dragleave zdarzeń.

Pokazało mi, że opuszczając blok rodzica (.dropzone) e.relatedTarget nie jest dzieckiem tego bloku, więc wiem, że jestem poza strefą zrzutu.

 1
Author: mortalis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-16 11:46:31

Tutaj jedno z najprostszych rozwiązań ●︿●

Spójrz na to fiddle

Możesz zrobić coś takiego:

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);
Dzięki temu powinieneś już wiedzieć, co się tu dzieje.
Spójrz na skrzypce.
 0
Author: Diego T. Yamaguchi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-06 17:21:34

Miałem podobny problem i naprawiłem go w ten sposób:

Problem: Funkcja drop (ev) jest wywoływana, gdy użytkownik upuszcza element w "strefie upuszczania" (element ul), ale niestety również, gdy element upuszcza się w jednym z jego potomków ( elementy li).

Poprawka:

function drop(ev) { 
ev.preventDefault(); 
data=ev.dataTransfer.getData('Text'); 
if(ev.target=="[object HTMLLIElement]")  
{ev.target.parentNode.appendChild(document.getElementById(data));}
else{ev.target.appendChild(document.getElementById(data));} 
} 
 0
Author: Pao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-22 11:24:47

Próbowałem zaimplementować to dla pola przesyłania plików, gdzie kolor pola zmieniłby się, gdy użytkownicy przeciągnęli plik w Przestrzeń.

Znalazłem rozwiązanie, które jest miłą mieszanką Javascript i CSS. Powiedzmy, że masz opuszczaną strefę z div z id #drop. Dodaj to do swojego Javascript:

$('#drop').on('dragenter', function() {
    $(this).addClass('dragover');
    $(this).children().addClass('inactive');
});

$('#drop').on('dragleave', function() {
    $(this).removeClass('dragover');
    $(this).children().removeClass('inactive');
});

Następnie dodaj to do CSS, aby dezaktywować wszystkie dzieci będą klasą .inactive:

#drop *.inactive {
    pointer-events: none;
}

Tak więc elementy potomne będą nieaktywne tak długo, jak długo użytkownik będzie przeciągał element nad pudełkiem.

 0
Author: David A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-07 05:56:07

Nie czułem się zadowolony z żadnego z obejść przedstawionych tutaj, ponieważ nie chcę stracić kontroli nad elementami dziecięcymi.

Więc użyłem innego podejścia logicznego, tłumacząc to na wtyczkę jQuery, o nazwie jquery-draghandler . Absolutnie nie manipuluje DOM, gwarantując wysokie osiągi. Jego użycie jest proste:

$(document).ready(function() {

    $(selector).draghandler({
        onDragEnter: function() {
            // $(this).doSomething();
        },
        onDragLeave: function() {
            // $(this).doSomethingElse();
        }
    });

});

Radzi sobie bezbłędnie z problemem, nie narażając żadnej funkcjonalności DOM.

Pobierz, szczegóły i objaśnienia dotyczące jego repozytorium Git .

 0
Author: Luca Fagioli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-26 17:52:42

Sam próbowałem to zaimplementować i nie chciałem też Jquery ani żadnej wtyczki.

Chciałem poradzić sobie z uploadowaniem pliku, w następujący sposób:

Struktura Plików:

- - - / uploads {uploads katalog}

- - - / js / slyupload.js {plik javascript.}

--- indeks.php

--- upload.php

--- style.css {tylko trochę stylizacji..}

Kod HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>my Dzone Upload...</title>
<link rel="stylesheet" href="styles.css" />
</head>

<body>
    <div id="uploads"></div>        
    <div class="dropzone" id="dropzone">Drop files here to upload</div>     
    <script type="text/javascript" src="js/slyupload.js"></script>      
</body>
</html>

To jest załączony Plik Javascript:: 'js / slyupload.js "

<!-- begin snippet:  -->

<!-- language: lang-js -->

    // JavaScript Document

    //ondragover, ondragleave...


    (function(){        

        var dropzone = document.getElementById('dropzone');
        var intv;

        function displayUploads(data){
            //console.log(data, data.length);
            var uploads = document.getElementById('uploads'),anchor,x;

            for(x=0; x < data.length; x++){

                //alert(data[x].file);
                anchor = document.createElement('a');
                anchor.href = data[x].file;
                anchor.innerText = data[x].name;

                uploads.appendChild(anchor);
            }               
        }

        function upload(files){
            //console.log(files);
            var formData = new FormData(), 
                xhr      = new XMLHttpRequest(),    //for ajax calls...
                x;                                  //for the loop..

                for(x=0;x<files.length; x++){
                    formData.append('file[]', files[x]);

                    /*//do this for every file...
                    xhr = new XMLHttpRequest();

                    //open... and send individually..
                    xhr.open('post', 'upload.php');
                    xhr.send(formData);*/
                }

                xhr.onload = function(){
                    var data = JSON.parse(this.responseText);   //whatever comes from our php..
                    //console.log(data);
                    displayUploads(data);

                    //clear the interval when upload completes... 
                    clearInterval(intv);
                }                   

                xhr.onerror = function(){
                    console.log(xhr.status);
                }

                //use this to send all together.. and disable the xhr sending above...

                //open... and send individually..
                intv = setInterval(updateProgress, 50);
                xhr.open('post', 'upload.php');
                xhr.send(formData);

                //update progress... 
                 /* */                   
        }

        function updateProgress(){
            console.log('hello');
         }          

        dropzone.ondrop = function(e){
            e.preventDefault(); //prevent the default behaviour.. of displaying images when dropped...
            this.className = 'dropzone';
            //we can now call the uploading... 
            upload(e.dataTransfer.files); //the event has a data transfer object...
        }

        dropzone.ondragover = function(){
            //console.log('hello');
            this.className = 'dropzone dragover';
            return false;
        }

        dropzone.ondragleave = function(){
            this.className = 'dropzone';
            return false;
        }           
    }(window));

CSS:

body{
	font-family:Arial, Helvetica, sans-serif; 
	font-size:12px;
}

.dropzone{
	width:300px; 
	height:300px;
	border:2px dashed #ccc;
	color:#ccc;
	line-height:300px;
	text-align:center;
}

.dropzone.dragover{
	border-color:#000;
	color:#000;
}
 0
Author: Ande Caleb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-28 12:44:40

Przykro mi, że to javascript, a nie jquery, ale dla mnie jest to najbardziej logiczny sposób na rozwiązanie tego problemu. Przeglądarka powinna wywołać dropleave (poprzedniego elementu) przed dropenter (ofr nowego elementu, ponieważ coś nie może wprowadzić czegoś innego przed opuszczeniem rzeczy forst, nie rozumiem, dlaczego to zrobili ! Więc musisz tylko opóźnić de dropleave w ten sposób:

function mydropleave(e)
{
    e.preventDefault();
    e.stopPropagation();

    setTimeout(function(e){ //the things you want to do },1);
}

I dropenter stanie się po dropleave, to wszystko !

 0
Author: Entretoize,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-25 06:40:34

Użyj greedy : true do dziecka jako funkcji droppable. Następnie uruchom tylko Zdarzenie kliknięte na pierwszej warstwie.

 -1
Author: Adam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-12 21:30:15