javascript - 浏览器 "drag and drop"事件 : Can anyone fill in the blanks?

标签 javascript firefox events drag-and-drop safari

直到现在我才真正需要使用任何拖动功能,所以让我向您介绍一下我到目前为止的发现:

  • 拖动事件是在用户拖动对象时发生的事件。这是“正确的”操作系统拖动,例如:隐藏一些文本并拖动它,或者甚至从浏览器外部拖入某些内容。
  • 据我所知,拖动时不会触发其他浏览器事件。 (例如,onmouseover 被忽略)。唯一有效的事件是拖动事件。
  • 在所有现代浏览器中,onDragEnter 和 onDragOver 似乎都可以工作...但 firefox 缺少“onDragLeave”。
  • 对于拖放,FF 使用“onDragDrop”,而 IE 和其他使用“onDrop”,而 Safari 似乎不支持它。
  • 事件似乎只适用于“可放置”元素,例如文本区域和文本。在其他元素上,只有一些事件有效。
  • 每个浏览器的各种其他怪癖,我什至不想再说了。
  • 关于这些事件的记录很少。

是的,我必须使用实际的拖放,不能模拟它。

我的问题:

  • 有没有办法在 FF 中检测“ondragleave”或类似的东西?
  • 有没有办法在 Safari 中检测“ondragdrop”或类似的东西?
  • 关于拖放,您有什么要补充的吗?

这是一个演示拖放事件的快速而粗略的模板:

<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>

最佳答案

我找到了一种通过事件委托(delegate)来处理 onDragLeave 的方法。

只需添加一个事件来监控整个文档上的“dragover”。当事件源成为您的相关元素时,设置一个标志,一旦事件源不再是该元素,就触发“dragleave”事件。

注意:

  • 需要进行修改,以便“e.source==obj”实际上是“obj.childOf(e.source)”...因为源元素可能是相关对象的后代。
  • 需要事件处理框架来确定基于浏览器的“源”。

不幸的是,Safari 缺少“ondrop”似乎无法修复……它根本就不会被解雇。

如何在 FF 中实现“dragleave”(好吧,所有浏览器):

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

我真诚地希望这个星球上的其他人可以使用它...

关于javascript - 浏览器 "drag and drop"事件 : Can anyone fill in the blanks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/478724/

相关文章:

javascript - 我有一个 'n' 的数组,如何使用 jQuery 将所有数组连接到一个数组中

javascript - 如果单击禁用选项,如何避免执行脚本?

android - Viewpager onClickListener 在 android 中引用了错误的 View

javascript - 注册多个事件监听器,即使我正在使用 removeEventListener

c# - 如何使用内部构造函数模拟事件

javascript - 是否可以在 TypeScript 中组合用户定义的类型保护?

javascript - javascript中的replace()回调函数没有被调用

javascript - 条件API调用并在react-select中发送数据

javascript - 触发 javascript 重定向后图像无法加载

javascript - 在浏览器的特定窗口中打开多个选项卡?