DEMO:http://jsfiddle.net/2FWZD/
这是jsfiddle代码,因为它迫使我添加代码:
$(document).ready(function () {
$('.test').on('mousemove', function (e) {
counter++;
$('.counter').text(counter);
$(this).hide();
// Comment out the following line and counter will stop increasing
document.elementFromPoint(e.clientX, e.clientY);
$(this).show();
});
});
这种情况发生在chrome中,无论如何都要阻止这个或另一种方法来解决elementFromPoint?
此处详细说明了Bug:https://code.google.com/p/chromium/issues/detail?id=333623
编辑1:
我只想注意,虽然答案是对jsfiddle演示的破解者,它实际上并没有解决我的潜在问题。
我正在使用Leap Motion在网站上模拟鼠标,该网站发送模拟的mousedown和mouseup事件以及mousemoves。我使用画布将光标绘制在所有内容的顶部,并使用此处显示的技术访问画布下方的元素。这样做的鼠标移动是在REAL鼠标位置触发而不是我的模拟鼠标,有效地给了我奇怪的问题。
这对FireFox来说不是问题。
编辑2:
问题解决。见答案。使用hide()之外的其他隐藏方法似乎可以在不触发的情况下工作
答案 0 :(得分:5)
保持最后的位置,就像这样:
var counter = 0;
var last='';
$(document).ready(function () {
$('.test').on('mousemove', function (e) {
var cur=e.screenX+':'+e.screenY;
if (cur == last) return;
last = cur;
counter++;
$('.counter').text(counter);
$(this).hide();
// Comment out the following line and counter will stop increasing
document.elementFromPoint(e.clientX, e.clientY);
$(this).show();
});
});
其他方式似乎是通过使用css:
使其“隐形”来隐藏元素var counter = 0;
$(document).ready(function () {
$('.test').on('mousemove', function (e) {
counter++;
$('.counter').text(counter);
$(this).addClass('hidden');
// Comment out the following line and counter will stop increasing
console.log(document.elementFromPoint(e.clientX, e.clientY));
$(this).removeClass('hidden');
});
});
的CSS:
.test.hidden {
overflow: hidden;
width: 0;
height: 0;
margin: 0;
padding: 0;
}
答案 1 :(得分:2)
elementFromPoint()
将返回特定坐标的元素。在这种情况下,指针/光标下的元素。在示例代码中,elementFromPoint()
函数返回<html>
,因为隐藏了.test
。出于某种原因,这导致Chrome认为鼠标正在移动。但是,您可以使用querySelectorAll(":hover")
代替elementFromPoint()
。
var counter = 0;
$(document).ready(function () {
$('.test').not( "body" ).on('mousemove', function (e) {
counter++;
$('.counter').text(counter);
$(this).hide();
// Comment out the following line and counter will stop increasing
var el=document.querySelectorAll( ":hover" ); //el = html not .test because it is hidden
console.log(el);
$(this).show();
});
});
答案 2 :(得分:1)
以下是问题发生的可能原因:
浏览器优化尽可能少的重绘,以提供更流畅的观看体验。这意味着在可能的情况下,像这样的块
$(this).hide();
$(this).show();
在可能的情况下优化为无操作。然而,当在两个操作之间强制重绘时不是这种情况,例如,您的代码
$(this).hide();
document.elementFromPoint(e.clientX, e.clientY);
$(this).show();
或者,有时用作黑客以避免在不需要时进行优化
$(this).hide();
this.offsetHeight;
$(this).show();
在某些情况下,似乎再次显示该元素会在Chrome上触发mousemove
。
答案 3 :(得分:1)
不要使用$(元素).hide()。 Chrome存在问题(并成为我们的新IE6)。
而不是那只是简单的讲义,你试图做一个getElementFromPoint
,你不想显示.test - 元素此时Chrome无法处理&#39; display:none&#39;在CSS中,将重绘总元素。这将引发mousemove事件,因此它将成为一个永恒的循环。
除了使用display:none之外,您还可以将&#39; height&#39; 设为零,这对于选择正确的元素具有相同的效果。 出于这个原因,我创建了一个函数fastDraw
.hide()变为fastDrawfunction fastDraw($box, show){
if(show){
$box.css({'height': $box.data('height')});
} else {
$box.data('height', $box.height());
$box.css({'height': 0});
}
}
现在你得到相同的结果
fastDraw($box); //hides the element by setting the height zero
var element = document.elementFromPoint(e.clientX, e.clientY); //fetches the element
fastDraw($box, true); //return it back to the previous height
由于您正在使用mouseMove事件,因此它将被调用很多次,并且最好尽可能少地执行。我已经重构了一些东西,所以它的计算量会减少。