如何使用叠加效果高亮显示鼠标光标下的元素?

仍然试图回答这个问题 ,我想我终于找到了一个解决方案,但它运行得太慢了。

var $div = $('
') .css({ 'border': '1px solid red', 'position': 'absolute', 'z-index': '65535' }) .appendTo('body'); $('body *').live('mousemove', function(e) { var topElement = null; $('body *').each(function() { if(this == $div[0]) return true; var $elem = $(this); var pos = $elem.offset(); var width = $elem.width(); var height = $elem.height(); if(e.pageX > pos.left && e.pageY > pos.top && e.pageX < (pos.left + width) && e.pageY topElement.zIndex) { topElement = { 'node': $elem, 'zIndex': zIndex }; } } }); if(topElement != null ) { var $elem = topElement.node; $div.offset($elem.offset()).width($elem.width()).height($elem.height()); } });

它基本上遍历页面上的所有元素,并找到光标下方的最顶层元素。

是否有某些方法可以使用四叉树或其他东西并对页面进行分段以使循环运行得更快?

是否有某些方法可以使用四叉树或其他东西并对页面进行分段以使循环运行得更快?

稍微退一步,意识到问题有多小,并且你尝试的答案越难,你将使用更复杂的答案。

现在您需要做的是为突出显示创建4个元素。 它们将形成一个空方块 ,因此您的鼠标事件可以自由发射。 这类似于我所做的叠加示例 。

不同之处在于您只需要四个元素(没有resize标记),并且4个框的大小和位置有点不同(模仿红色边框)。 然后你可以在事件处理程序中使用event.target ,因为它默认获得真正的最顶层元素。

另一种方法是隐藏exra元素,获取elementFromPoint ,然后计算然后将其放回去。

我可以告诉你,它们比光更快。 甚至爱因斯坦也同意:)

1.)elementFromPoint overlay / borders – [ Demo1 ] FF需要v3.0 +

 var box = $("
").css({ display: "none", position: "absolute", zIndex: 65000, background:"rgba(255, 0, 0, .3)" }).appendTo("body"); var mouseX, mouseY, target, lastTarget; // in case you need to support older browsers use a requestAnimationFrame polyfill // eg: https://gist.github.com/paulirish/1579671 window.requestAnimationFrame(function frame() { window.requestAnimationFrame(frame); if (target && target.className === "outer") { box.hide(); target = document.elementFromPoint(mouseX, mouseY); } box.show(); if (target === lastTarget) return; lastTarget = target; var $target = $(target); var offset = $target.offset(); box.css({ width: $target.outerWidth() - 1, height: $target.outerHeight() - 1, left: offset.left, top: offset.top }); }); $("body").mousemove(function (e) { mouseX = e.clientX; mouseY = e.clientY; target = e.target; });

2.)鼠标hover边框 – [ 演示2 ]

 var box = new Overlay(); $("body").mouseover(function(e){ var el = $(e.target); var offset = el.offset(); box.render(el.outerWidth(), el.outerHeight(), offset.left, offset.top); });​ /** * This object encapsulates the elements and actions of the overlay. */ function Overlay(width, height, left, top) { this.width = this.height = this.left = this.top = 0; // outer parent var outer = $("
").appendTo("body"); // red lines (boxes) var topbox = $("
").css("height", 1).appendTo(outer); var bottombox = $("
").css("height", 1).appendTo(outer); var leftbox = $("
").css("width", 1).appendTo(outer); var rightbox = $("
").css("width", 1).appendTo(outer); // don't count it as a real element outer.mouseover(function(){ outer.hide(); }); /** * Public interface */ this.resize = function resize(width, height, left, top) { if (width != null) this.width = width; if (height != null) this.height = height; if (left != null) this.left = left; if (top != null) this.top = top; }; this.show = function show() { outer.show(); }; this.hide = function hide() { outer.hide(); }; this.render = function render(width, height, left, top) { this.resize(width, height, left, top); topbox.css({ top: this.top, left: this.left, width: this.width }); bottombox.css({ top: this.top + this.height - 1, left: this.left, width: this.width }); leftbox.css({ top: this.top, left: this.left, height: this.height }); rightbox.css({ top: this.top, left: this.left + this.width - 1, height: this.height }); this.show(); }; // initial rendering [optional] // this.render(width, height, left, top); }

首先,我不认为做$('body *').live是一个非常好的主意,它似乎非常昂贵(想想每次移动鼠标时浏览器必须做的计算)

也就是说,这是一个忽略这方面的优化版本

 var $div = $('
') .css({ 'border': '1px solid red', 'position': 'absolute', 'z-index': '65535' }) .appendTo('body'); $('body *').live('mousemove', function(e) { var topElement = null; var $bodyStar = $('body *'); for(var i=0,elem;elem=$bodyStar[i];i++) { if(elem == $div[0]) continue; var $elem = $(elem); var pos = $elem.offset(); var width = $elem.width(); var height = $elem.height(); if(e.pageX > pos.left && e.pageY > pos.top && e.pageX < (pos.left + width) && e.pageY < (pos.top + height)) { var zIndex = document.defaultView.getComputedStyle(this, null).getPropertyValue('z-index'); if(zIndex == 'auto') zIndex = $elem.parents().length; if(topElement == null || zIndex > topElement.zIndex) { topElement = { 'node': $elem, 'zIndex': zIndex }; } } } if(topElement != null) { var $elem = topElement.node; $div.offset($elem.offset()).width($elem.width()).height($elem.height()); } });

如果您需要性能,请不要使用jQuerys循环机制。 它们都是围绕每次迭代的函数调用构建的,与普通循环相比这是非常慢的,因为在执行函数调用时发生的调用堆栈启动对于您需要执行的大多数迭代操作来说是一个巨大的开销。

代码已更新以修复错误,并允许动态插入元素。