jQuery:在鼠标光标下突出显示元素?

可能重复:
如何使这个JavaScript更快?

我正在尝试在jQuery中创建一个“元素选择器”,就像Firebug一样。 基本上,我想突出显示用户鼠标下方的元素。 这是我到目前为止所得到的,但效果并不好:

$('*').mouseover(function (event) { var $this = $(this); $div.offset($this.offset()).width($this.width()).height($this.height()); return false; }); var $div = $('
') .css({ 'background-color': 'rgba(255,0,0,.5)', 'position': 'absolute', 'z-index': '65535' }) .appendTo('body');

基本上,我正在为具有半透明背景的DOM注入div。 然后我在每个元素上侦听鼠标hover事件,然后移动div以覆盖该元素。

现在,只要您将鼠标移到页面上,这只会使整个页面变红。 我怎样才能让它更好地工作?

编辑:非常确定问题是,只要我的鼠标触摸页面,身体就会被选中,然后当我移动鼠标时,没有任何一个瞬间通过高点,因为它超越了一切。


萤火

通过Firebug源代码挖掘,我发现了这个:

 drawBoxModel: function(el) { // avoid error when the element is not attached a document if (!el || !el.parentNode) return; var box = Firebug.browser.getElementBox(el); var windowSize = Firebug.browser.getWindowSize(); var scrollPosition = Firebug.browser.getWindowScrollPosition(); // element may be occluded by the chrome, when in frame mode var offsetHeight = Firebug.chrome.type == "frame" ? FirebugChrome.height : 0; // if element box is not inside the viewport, don't draw the box model if (box.top > scrollPosition.top + windowSize.height - offsetHeight || box.left > scrollPosition.left + windowSize.width || scrollPosition.top > box.top + box.height || scrollPosition.left > box.left + box.width ) return; var top = box.top; var left = box.left; var height = box.height; var width = box.width; var margin = Firebug.browser.getMeasurementBox(el, "margin"); var padding = Firebug.browser.getMeasurementBox(el, "padding"); var border = Firebug.browser.getMeasurementBox(el, "border"); boxModelStyle.top = top - margin.top + "px"; boxModelStyle.left = left - margin.left + "px"; boxModelStyle.height = height + margin.top + margin.bottom + "px"; boxModelStyle.width = width + margin.left + margin.right + "px"; boxBorderStyle.top = margin.top + "px"; boxBorderStyle.left = margin.left + "px"; boxBorderStyle.height = height + "px"; boxBorderStyle.width = width + "px"; boxPaddingStyle.top = margin.top + border.top + "px"; boxPaddingStyle.left = margin.left + border.left + "px"; boxPaddingStyle.height = height - border.top - border.bottom + "px"; boxPaddingStyle.width = width - border.left - border.right + "px"; boxContentStyle.top = margin.top + border.top + padding.top + "px"; boxContentStyle.left = margin.left + border.left + padding.left + "px"; boxContentStyle.height = height - border.top - padding.top - padding.bottom - border.bottom + "px"; boxContentStyle.width = width - border.left - padding.left - padding.right - border.right + "px"; if (!boxModelVisible) this.showBoxModel(); }, hideBoxModel: function() { if (!boxModelVisible) return; offlineFragment.appendChild(boxModel); boxModelVisible = false; }, showBoxModel: function() { if (boxModelVisible) return; if (outlineVisible) this.hideOutline(); Firebug.browser.document.getElementsByTagName("body")[0].appendChild(boxModel); boxModelVisible = true; } 

看起来他们正在使用标准div + css来绘制它……只需要弄清楚他们现在如何处理事件……(这个文件长28K行)

还有这个片段,我猜测它会找到合适的对象….虽然我无法弄清楚如何。 他们正在寻找一个类“objectLink-element”……我不知道这个“repObject”是什么。

 onMouseMove: function(event) { var target = event.srcElement || event.target; var object = getAncestorByClass(target, "objectLink-element"); object = object ? object.repObject : null; if(object && instanceOf(object, "Element") && object.nodeType == 1) { if(object != lastHighlightedObject) { Firebug.Inspector.drawBoxModel(object); object = lastHighlightedObject; } } else Firebug.Inspector.hideBoxModel(); }, 

我想也许当鼠标移动或鼠标hover事件为突击显示节点触发时,我可以以某种方式传递它吗? 也许节点它覆盖……?


如果我在一个z-index比我的荧光笔更高的z-index元素上面放置一个不可见元素,但是给我的荧光笔提供比实际元素更高的z-index …理论上,它应该可以工作。 隐形元素将触发鼠标事件,但高亮效果仍然看起来像它的实际元素的超越。

这意味着我只是将DOM元素加倍,并且定位必须正确。 除非我可能只“提升”荧光笔目前覆盖的元素? 但那可能仍然是每个元素>。<有人帮助我!

所有这些答案都太复杂了……简单的解决方案:

使用Javascript:

 prevElement = null; document.addEventListener('mousemove', function(e){ var elem = e.target || e.srcElement; if (prevElement!= null) {prevElement.classList.remove("mouseOn");} elem.classList.add("mouseOn"); prevElement = elem; },true); 

CSS:

 .mouseOn{ background-color: #bcd5eb !important; outline: 2px solid #5166bb !important; } 

修改大卫的答案,以便在之后正确地恢复背景颜色……

 $('body *').live('mouseover mouseout', function(event) { if (event.type == 'mouseover') { $(this).data('bgcolor', $(this).css('background-color')); $(this).css('background-color','rgba(255,0,0,.5)'); } else { $(this).css('background-color', $(this).data('bgcolor')); } return false; }); 

我可以建议一种替代方法吗?

如何简单地为页面的所有子元素指定background-color ,然后在hover()调整该元素的background-color以增加其对比度?

 $('html').children().css('background-color','rgba(0,0,0,0.2)'); $('body').children().hover( function(){ $(this).css('background-color','#fff'); }, function(){ $(this).css('background-color','rgba(0,0,0,0.2)'); }); 

JS小提琴演示 。

鼠标hover后整个页面变红的原因是您的代码与body元素的mouseover事件匹配。 你可以通过选择body孩子来阻止这种情况的发生。

 $('body *').bind( //... 

您将在具有大量元素的页面上遇到性能问题,但是因为bind将为每个匹配的元素附加一个侦听器。 试着看看jQuery的事件委托api( .delegate() , http: .delegate() ,它允许你监听传播到根元素的事件,也适用于鼠标事件。

►这有点不那么烦躁,但是如果没有先将鼠标完全移所述父级,它就无法检测从父元素移动到其中一个子元素。

 var $div = $('
').css({ 'background-color': 'rgba(255,0,0,.5)', 'position': 'absolute', 'z-index': '65535' }).hide().prependTo('body'); var $highlit; $('*').live('mousemove', function(event) { if (this.nodeName === 'HTML' || this.nodeName === 'BODY') { $div.hide(); return false; } var $this = this.id === 'highligher' ? $highlit : $(this), x = event.pageX, y = event.pageY, width = $this.width(), height = $this.height(), offset = $this.offset(), minX = offset.left, minY = offset.top, maxX = minX + width, maxY = minY + height; if (this.id === 'highlighter') { if (minX <= x && x <= maxX && minY <= y && y <= maxY) { // nada } else { $div.hide(); } } else { $highlit = $this; $div.offset(offset).width($this.width()).height($this.height()).show(); } return false; });

希望这有助于让球滚动。 您可以调整我编写的内容以使用document.elementFromPoint(x, y)来检查鼠标是否已移动到当前突出显示的元素的子元素中。 我现在还不清楚这个问题。

或者,如果概述与突出显示一样好,您可以尝试我在评论中提到的方法来解决原始问题。 在当前hover的元素周围绘制4个div * - 这是轮廓框每个边缘的一个div。 您和实际内容之间不再有绘图元素!


* 我敢打赌, document.elementFromPoint(x, y)会让你的鼠标下的元素更加容易