События «перетаскивания» в браузере: может кто-нибудь заполнить пробелы? - PullRequest
7 голосов
/ 26 января 2009

До сих пор у меня никогда не было необходимости использовать какие-либо функции перетаскивания, поэтому позвольте мне рассказать вам о том, что я обнаружил до сих пор:

  • События перетаскивания - это события, которые происходят, когда пользователь перетаскивает объект. Это «правильное» перетаскивание ОС, например: перетаскивание некоторого текста и перетаскивание его или даже перетаскивание чего-либо извне браузера.
  • При перетаскивании, насколько я могу судить, другие события браузера не будут запускаться. (например, onmouseover игнорируется). Единственными работающими событиями являются события перетаскивания.
  • Во всех современных браузерах onDragEnter и onDragOver работают ... но в Firefox отсутствует "onDragLeave."
  • Для удаления FF использует "onDragDrop", в то время как IE и другие используют "onDrop", в то время как Safari не поддерживает его.
  • Кажется, что события работают только с "сбрасываемыми" элементами, такими как textarea и text. На других элементах работают только некоторые события.
  • Различные причуды для каждого браузера, которые я даже не хочу обсуждать.
  • Очень мало задокументировано об этих событиях.

Да, я должен использовать фактическое перетаскивание + падение и не могу имитировать его.

Мои вопросы:

  • Есть ли способ обнаружить "ondragleave" или подобное в FF?
  • Есть ли способ определить «ondragdrop» или подобное в Safari?
  • Есть что добавить в Drag + Drop?

Вот быстрый и грязный шаблон, демонстрирующий события перетаскивания:

<script>
    addEvent = function(obj, eventname, fn){
        if (document.addEventListener) obj.addEventListener(eventname, fn, false);
        else obj.attachEvent('on'+eventname, fn);
    }

    window.onload = function(){
        var logger = document.getElementById("logger");
        var log = function(str){ logger.value = str + logger.value; }

        //log a variety of drag events for the textarea
        var obj = document.getElementById("tarea");
        var events = ["dragenter","dragover","dragout","dragleave","dragdrop","drop"];
        for (var i=0; i<events.length; i++){
            (function(event){//create a closure to remove variable scope
                addEvent(obj, event, function(){ log("textarea: " + event + "\n"); });
            })(events[i]);
        }

        //log events on the div
        obj = document.getElementById("div");
        events = ["mouseover","mouseout","mouseup","mousedown","click","dblclick",
                "dragenter","dragover","dragout","dragleave","dragdrop","drop"];
        for (var i=0; i<events.length; i++){
            (function(event){//create a closure to remove variable scope
                addEvent(obj, event, function(){ log("div: " + event + "\n"); });
            })(events[i]);
        }
    }
</script>
Life's a drag when doing cross browser stuff.<br><br>
<div id="div" style="width: 100px; height: 100px; background: green; float: left;">
</div>
<textarea id="tarea" style="width: 100px; height: 100px; float: left; margin: 0px 5px;">
</textarea>

<textarea id="logger" style="width: 200px; height: 400px; float: left;">
</textarea>

Ответы [ 3 ]

6 голосов
/ 26 января 2009

Я нашел способ обработки onDragLeave с помощью делегирования события.

Просто добавьте событие для отслеживания "dragover" по всему документу. Когда источником события становится ваш элемент, о котором идет речь, установите флаг, а когда источником события больше не будет этот элемент, запустите событие «dragleave».

Примечание:

  • Нужно изменить, чтобы "e.source == obj" на самом деле был "obj.childOf (e.source)" ... так как исходный элемент может быть потомком рассматриваемого объекта.
  • Требуется среда обработки событий, чтобы выяснить, какой «источник» основан на браузере.

К сожалению, похоже, что отсутствие Safari «ondrop» не может быть исправлено ... его просто никогда не уволят.

Как добиться «Dragleave» в FF (ну, во всех браузерах):

var setOnDragLeave = function(obj, fn){
    var on=false;
    var dragover = function(e){
        if (on){
            if (e.source!=obj){
                on = false;
                e.eventname = "dragleave";
                fn.call(obj, e);
            }
            return;
        }else{
            if (e.source==obj) on = true;
            return;
        }
    }
    addEvent(document.documentElement, "dragover", dragover);
}
setOnDragLeave(obj, function(e){ logEvent(e); });

Я искренне надеюсь, что кто-то еще на этой планете сможет использовать это ...

0 голосов
/ 04 июня 2009

Firefox реализует событие "dragleave" как "dragexit", кажется. Просто узнал это сейчас. И это работает.

0 голосов
/ 18 февраля 2009

Хорошая статья. Я тоже ищу эквивалент ondrop / ondragdrop в Safari. Однако существует возможный обходной путь для «внутреннего» случая перетаскивания, то есть источник перетаскивания и цель перетаскивания находятся в одном документе.

IE поддерживает события ondragstart, ondrag и ondragend для элемента источника перетаскивания. Safari 3 также запускает их. Firefox3 запускает ondrag и ondragend, но не ondragstart (хотя документация предполагает, что он должен). В любом случае, в зависимости от вашего сценария, вы можете использовать ondragend, чтобы определить, когда операция перетаскивания завершена.

...