Javascript firefox滥发垃圾信息事件

Javascript firefox滥发垃圾信息事件,javascript,html,firefox,Javascript,Html,Firefox,试图构建一些拖放功能,Firefox中出现了一个奇怪的bug。我将整个文档的正文作为一个拖放区,并希望在页面上拖动某个对象时更改h1值 看起来一点问题都没有: 它在任何地方都能正常工作,除了Firefox。当我在页面中拖动一个对象时——这没有问题,除了在文本上拖动对象的情况,如果您尝试这个示例并在文本上拖动一个文件,您会注意到当对象在文本上浮动时,ondragenter事件会不停地触发。这只发生在Firefox中。似乎更改innerHTML正在重置事件是否已引发的状态,从而导致事件陷入循环。这可

试图构建一些拖放功能,Firefox中出现了一个奇怪的bug。我将整个文档的正文作为一个拖放区,并希望在页面上拖动某个对象时更改
h1

看起来一点问题都没有:


它在任何地方都能正常工作,除了Firefox。当我在页面中拖动一个对象时——这没有问题,除了在文本上拖动对象的情况,如果您尝试这个示例并在文本上拖动一个文件,您会注意到当对象在文本上浮动时,
ondragenter
事件会不停地触发。这只发生在Firefox中。

似乎更改innerHTML正在重置事件是否已引发的状态,从而导致事件陷入循环。这可能是Firefox中的一个bug。添加一个仅在文本之前未被更改时才更改文本的标志,可防止其陷入此循环。然后,如果需要,您可以处理dragleave事件来清除此标志

var drop = document.getElementById('drop'),
text = document.getElementById('promo-text');
var textChanged = false;

drop.ondragenter = function () {
    console.log('dragged!');
    if (!textChanged) {
        text.innerHTML = 'Drop it here!';
        textChanged = true;
    }
    return false;
};

在JSFIDLE上运行的代码:

问题的根本原因是您的代码正在设置反馈循环。至少在Firefox中

当任何
ondragenter
事件传播到
body
元素时,您可以通过设置元素的
innerHTML
属性来修改显示的文本。浏览器更新DOM中的元素,如果是Firefox,则会看到您在更新的元素上拖动某些内容,并重新触发
ondragenter
事件(然后该事件会传播回您的
主体
元素,并重新启动整个过程)

要解决这个问题,你所要做的就是从链中拉出一个链接来打破反馈循环。例如,通过跟踪您是否已经为给定的“拖动”事件更改了文本(基本上如Adam Shaver所建议的),或者在指定给
innerHTML
属性之前检查文本是否已经显示“Drop it Here!”,等等

尽管如此,如果您想让处理程序跨多个“拖动”事件工作(即,每当用户启动“拖动”操作,然后取消/结束它而不删除文件时,让文本在“将文件放在此处某处”和“将其放在此处!”之间来回切换),请小心使用这种方法。如果你想这样做的话,你必须在两端正确地进行会计核算

打破反馈循环的另一个选项是取消由文本元素触发的事件,这样它们就不会首先传播到
body
。例如:

<h1 class="cover-heading" id="promo-text" ondragenter="cancelEvent(event);">Drop file somewhere here.</h1>

[...]

function cancelEvent(evt) {
    if (! evt) {
        evt = window.event;
    }

    if (evt) {
        console.log("Canceling event");
        evt.cancelBubble = true;
        if (evt.stopImmediatePropagation) {
            evt.stopImmediatePropagation();
        }
    }

    return false;
}
将文件放到这里的某个地方。
[...]
函数取消事件(evt){
if(!evt){
evt=window.event;
}
如果(evt){
console.log(“取消事件”);
evt.cancelBubble=真;
if(evt.停止即时复制){
evt.stopImmediatePropagation();
}
}
返回false;
}

根据您当前的设置,这样做可能会更好,因为不用担心手工记账


其他方法也可能起作用,例如检查事件的
目标
(或IE上的
srceelement
)。基本上,任何打破反馈循环的事情都可以

ondragcenter
看起来像是打字错误。也许你的意思是
ondragenter
?我可以通过删除所有HTML来解决这个问题,除了。因此,虽然浏览器可能能够处理这个问题,但也许您可以通过以不同的方式显示文本来解决这个问题,这样就不会干扰鼠标事件的冒泡。谢谢您的详细回答!嗨,亚当找到了你2011年的精彩截屏代码。从2011年开始,现在这仍然是最好的截屏方式吗?我们特别需要捕获UIView的内容,而不是整个屏幕。谢谢你的时间!问:@Crashalot-我最近没有尝试运行该代码,但考虑到它的年龄,我倾向于认为现在可能有其他/更好的方法来捕获视图内容。苹果经常更新iOS SDK,并且每次都会引入一些突破性的更改。最简单的事情可能是尝试一下,看看它是否仍然编译和运行。@aroth感谢Adam。你有Swift版本吗?你可以咨询吗?我们不需要代码,只需要关于类似问题的建议,因为我们是AVFoundation的新手。再次感谢!