我想编写一个浏览器(Chrome / FF)扩展程序,需要在网页上选择一个元素。我希望它表现得像Firebug的元素检查员那样。单击检查箭头,然后可以悬停/突出显示元素。单击所需的元素时,将检查该元素。我只是对允许用户选择元素的代码感兴趣 - 而不是实际检查它或类似的东西。
因为我正在写一个扩展,如果你能提供非jQuery / Prototype / etc ..代码可能会很好,所以我不必分发它。
答案 0 :(得分:18)
我使用jQuery作为另一个项目的组件编写了一个实现。源代码和文档可在此处获取:https://github.com/andrewchilds/jQuery.DomOutline
答案 1 :(得分:17)
我最近为我正在处理的项目需要这样的功能,原来我必须使用双方来创建一个盒子,否则当你移动鼠标时event.target
最终会成为选择器,如果我使用z-index: -1
,当你有很多重叠的元素等等时,它会有点 fishy 。
这是我为了您的利益从我的项目转换而来的版本,它涉及jQuery,但转换为 vanilla 非常简单,只有mousemove
&使用了来自jQuery的css
方法。
分步说明。
首先创建所需的 5 HTMLElements。
<div id="selector">
<div id="selector-top"></div>
<div id="selector-left"></div>
<div id="selector-right"></div>
<div id="selector-bottom"></div>
</div>
其次在mousemove
(或您的容器)上创建document
事件
$(document).mousemove(function(event) { ... });
然后在mousemove
内,我们会进行一些基本检查,以防止选择HTML, BODY, selector
var id = event.target.id, tagName = event.target.tagName;
if(id.indexOf('selector') !== -1 || tagName === 'BODY' || tagName === 'HTML') {
return;
}
然后我们需要创建一个对象来存储我们的元素。
var elements = {
top: $('#selector-top'),
left: $('#selector-left'),
right: $('#selector-right'),
bottom: $('#selector-bottom')
};
之后我们存储一些变量,这些变量包含有关目标元素的一些信息,如此。
var $target = event.target;
targetOffset = $target.getBoundingClientRect(),
targetHeight = targetOffset.height,
targetWidth = targetOffset.width;
然后我们所做的就是计算位置&amp;选择器的所有 4 侧的高度,如此。
elements.top.css({
left: (targetOffset.left - 4),
top: (targetOffset.top - 4),
width: (targetWidth + 5)
});
elements.bottom.css({
top: (targetOffset.top + targetHeight + 1),
left: (targetOffset.left - 3),
width: (targetWidth + 4)
});
elements.left.css({
left: (targetOffset.left - 5),
top: (targetOffset.top - 4),
height: (targetHeight + 8)
});
elements.right.css({
left: (targetOffset.left + targetWidth + 1),
top: (targetOffset.top - 4),
height: (targetHeight + 8)
});
所有+aFewPixels
只是一点点优化,因此选择器与目标之间存在2px
差距。
对于CSS
这是我的想法。
#selector-top, #selector-bottom {
background: blue;
height:3px;
position: fixed;
transition:all 300ms ease;
}
#selector-left, #selector-right {
background: blue;
width:3px;
position: fixed;
transition:all 300ms ease;
}
transition
为选择器提供了非常好的滑动效果。
注意:这也适用于
transform: scale(2);
,例如。当元素按比例缩放时。
修改:我刚刚更新了这个,我注意到elements
对象里面事件处理程序,我把它移到了外面演示,这是非常重要的性能提升,因为现在elements
对象只创建一次而不是数百个,如果不是数百万在mousemove
事件中强烈>次。
答案 2 :(得分:10)
一种简单的方法是使用轮廓而不是边框:
.highlight { outline: 4px solid #07C; }
只需在要选择/取消选择的任何元素上添加和删除该类(下面的代码未经过正确测试):
document.body.addEventListener("mouseover", function(e) {
e.stopPropagation();
e.target.addEventListener("mouseout", function (e) {
e.target.className = e.target.className.replace(new RegExp(" highlight\\b", "g"), "");
});
e.target.className += " highlight";
});
由于您使用的是轮廓(Chrome支持)而不是边框,因此元素不会跳转。我在我的EasyReader Extension中使用了类似的东西。
答案 3 :(得分:7)
我最后在Firebug小组中询问并得到了一些很好的帮助:
答案 4 :(得分:3)
还要检查一下:
http://rockingcode.com/tutorial/element-dom-tree-jquery-plugin-firebug-like-functionality/
我发现它很有见地..这里有一个演示:
http://rockingcode.com/demos/elemtree/
希望这有帮助。
答案 5 :(得分:3)
仅使用Vanilla JS选中并突出显示页面上的任何HTML元素!在Chrome,FF和Opera中进行了测试,在IE中不起作用。
您实际上需要的很简单。您可以在JS中创建一个带有背景的空div框,然后将其四处移动以在悬停的元素上方突出显示。 这是JS代码:
const hoverBox = document.createElement("div");
console.log("hoverBox: ", hoverBox);
hoverBox.style.position = "absolute";
// change to whatever highlight color you want
hoverBox.style.background = "rgba(153, 235, 255, 0.5)";
// avoid blocking the hovered element and its surroundings
hoverBox.style.zIndex = "0";
document.body.appendChild(hoverBox);
let previousTarget;
document.addEventListener("mousemove", (e) => {
let target = e.target;
if (target === hoverBox) {
// the truely hovered element behind the added hover box
const hoveredElement = document.elementsFromPoint(e.clientX, e.clientY)[1];
if (previousTarget === hoveredElement){
// avoid repeated calculation and rendering
return;
} else{
target = hoveredElement;
}
} else{
previousTarget = target;
}
const targetOffset = target.getBoundingClientRect();
const targetHeight = targetOffset.height;
const targetWidth = targetOffset.width;
// add a border around hover box
const boxBorder = 5;
hoverBox.style.width = targetWidth + boxBorder * 2 + "px";
hoverBox.style.height = targetHeight + boxBorder * 2 + "px";
// need scrollX and scrollY to account for scrolling
hoverBox.style.top = targetOffset.top + window.scrollY - boxBorder + "px";
hoverBox.style.left = targetOffset.left + window.scrollX - boxBorder + "px";
});
See Demo
我还为元素选择器制作了一个npm package,具有更多用户配置,例如背景色,边框宽度,过渡效果等。
这是GitHub page。
答案 6 :(得分:2)
在Stackoverflow上有一个类似的问题,它有很多好的答案: Does anyone know a DOM inspector javascript library or plugin?
对于那些正在寻找快速而肮脏的解决方案的人:
http://userscripts.org/scripts/review/3006是最简单的。只需将代码放在<script></script>
代码中,就可以了。
https://github.com/josscrowcroft/Simple-JavaScript-DOM-Inspector/blob/master/inspector.js稍微好一些,但仍然很容易整合。
对于更复杂的元素检查器,您可能想要检查Udi指向的SelectorGadget。检查员选择代码位于http://www.selectorgadget.com/stable/lib/interface.js
答案 7 :(得分:2)
这是一个用纯JavaScript编写的库作为替代。
TheRoom JS:https://github.com/hsynlms/theroomjs
RecyclerViewBackground bg = new RecyclerViewBackground();
bg.attachRecyclerView(recyclerView);
recyclerView.setBackground(bg);
答案 8 :(得分:1)
您需要做的是为突出显示创建4个元素。它们将形成一个空方,因此您的鼠标事件可以自由发射。这类似于我所做的overlay example。
不同之处在于您只需要四个元素(没有调整大小标记),并且4个框的大小和位置有点不同(模仿红色边框)。然后,您可以在事件处理程序中使用event.target
,因为默认情况下它会获得真正的最顶层元素。
另一种方法是隐藏exra元素,获取elementFromPoint
,然后计算然后将其放回去。
我告诉你,它们比光更快。甚至爱因斯坦都会同意:)
1。)elementFromPoint overlay / borders - [Demo1] FF需要v3.0 +
var box = $("<div class='outer' />").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
// e.g: 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。)鼠标悬停边框 - [Demo2]
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 = $("<div class='outer' />").appendTo("body");
// red lines (boxes)
var topbox = $("<div />").css("height", 1).appendTo(outer);
var bottombox = $("<div />").css("height", 1).appendTo(outer);
var leftbox = $("<div />").css("width", 1).appendTo(outer);
var rightbox = $("<div />").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);
}
答案 9 :(得分:1)
使用.onmouseover
和e.target
jQuery可以非常轻松地完成非常基本的实现:
var last,
bgc;
document.onmouseover = function(e) {
var elem = e.target;
if (last != elem) {
if (last != null) {
last.classList.remove("hovered");
}
last = elem;
elem.classList.add("hovered");
}
}
如果您希望孩子们也改变背景,请使用下面的CSS:
.hovered,
.hovered * {
cursor: pointer;
color: black;
background-color: red;
}
如果您只想选择边缘附近的元素(或选择边缘附近的父元素和其他地方的元素本身),您可以使用.getBoundingClientRect
。
var last;
window.addEventListener("mousemove", function(e) {
if(last) {
last.style.background = ''; // empty is enough to restore previous value
}
var elem = e.target;
if(elem === document.body || elem === document.documentElement) {
return;
}
var bb = elem.getBoundingClientRect();
var xr = e.pageX - bb.left; // x relative to elem
var yr = e.pageY - bb.top; // y relative to elem
var ew = 10; // edge width
if(
xr <= ew
|| xr >= bb.width - ew
|| yr <= ew
|| yr >= bb.height - ew
){
elem.style.background = 'red';
last = elem;
}
});
与某些边框配对,这可用于选择。 Demo