【发布时间】:2011-06-09 13:18:49
【问题描述】:
我正在尝试在 jQuery 中创建一个“元素选择器”,就像 Firebug 一样。基本上,我想突出显示用户鼠标下方的元素。到目前为止,这是我得到的,但效果不是很好:
$('*').mouseover(function (event) {
var $this = $(this);
$div.offset($this.offset()).width($this.width()).height($this.height());
return false;
});
var $div = $('<div>')
.css({ 'background-color': 'rgba(255,0,0,.5)', 'position': 'absolute', 'z-index': '65535' })
.appendTo('body');
基本上,我将一个 div 注入到具有半透明背景的 DOM 中。然后我在每个元素上监听 mouseover 事件,然后移动 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 行)
还有这个 sn-p,我猜它检索适当的对象....虽然我不知道如何。他们正在寻找一个“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();
},
我在想,也许当为荧光笔节点触发 mousemove 或 mouseover 事件时,我可以以某种方式传递它?也许节点覆盖它...?
如果我在每个元素上方放置一个不可见元素,其 z-index 比我的荧光笔高,但给我的荧光笔一个比实际元素更高的 z-index...理论上,它应该可以工作。不可见元素会触发鼠标事件,但高亮效果看起来仍然像实际元素的覆盖。
这意味着我只是将 DOM 元素翻了一番,而且定位必须正确。 除非也许我只是“提升”荧光笔当前覆盖的元素?但这仍然可能是每个元素>。
【问题讨论】:
-
在尝试做这样的事情时有一个令人讨厌的 catch-22。基本上,一旦你在鼠标下画了一些东西,由于鼠标悬停在一个元素上,鼠标实际上离开了原始元素,现在悬停在 new 元素上。
-
@Matt:那么我们如何解决这个问题呢? Firebug 是否不操纵 DOM 来渲染这些框,还是它有自己的渲染引擎?
-
当您在 Firebug 中将鼠标悬停在网页上时,Firebug 会突出显示网页中的元素 - 这是单独的。或者那是累的想法?当您使用“点击检查”时,它只勾勒出元素,这可能是问题的症结所在 - Firebug 可以绘制 4 个单独的元素,一个用于框的每个边缘,在这种情况下,我提到的 catch-22 是根本不是问题。
-
+1 用于挖掘 Firebug 源代码 - 我打算这样做。
标签: jquery