Javascript: Let Benutzer ein HTML-Element wie Firebug wählen?
-
25-09-2019 - |
Frage
Ich möchte einen Browser (Chrome / FF) Erweiterung schreiben, dass Bedürfnisse ein Element auf einer Web-Seite zu wählen. Ich möchte es verhalten wie Firebug Element Inspektor tut. Sie auf die Schaltfläche überprüfen Pfeil und Sie können dann schweben / markieren Elemente. Wenn Sie auf das Element klicken Sie möchten, wird das Element kontrolliert. Ich bin nur in dem Code interessiere einem Benutzer zu ermöglichen, ein Element wählen -. Nicht in tatsächlich oder ähnliche Inspektion
Weil ich eine Erweiterung ich schreibe, könnte es schön, wenn Sie nicht-jQuery / Prototype / etc .. Code zur Verfügung stellen könnte, so muss ich das nicht verteilen.
Lösung
Ich schrieb eine Implementierung dieses mit jQuery als Bestandteil eines anderen Projektes. Die Quelle und Dokumentation finden Sie hier: https://github.com/andrewchilds/jQuery.DomOutline
Andere Tipps
Ich habe vor kurzem ein solches Feature für ein Projekt, das ich arbeitete, stellte sich heraus, erforderlich, dass ich musste für Seiten ein Feld zu erstellen, da sonst die event.target
, wenn Sie die Maus bewegen, die Wähler zu sein, würde am Ende, und wenn ich zur Verwendung z-index: -1
wurden wäre es ein bisschen fischig , wenn Sie viele Elemente haben, dass Überlappung ... etc.
Hier ist eine Version, die ich von meinem Projekt zu Ihrem Vorteile umgewandelt habe, geht es um jQuery, aber es ist extrem einfach zu Vanille zu konvertieren, da nur die mousemove
& css
Methoden von jQuery verwendet werden.
Schritt für Schritt Anleitung.
Erstellen Sie zunächst die 5 HTMLElements die erforderlich sind.
<div id="selector">
<div id="selector-top"></div>
<div id="selector-left"></div>
<div id="selector-right"></div>
<div id="selector-bottom"></div>
</div>
erstellen Zweitens ein mousemove
Ereignis auf dem document
(oder Container)
$(document).mousemove(function(event) { ... });
Dann in der mousemove
werden wir einige grundlegende Überprüfung tun die HTML, BODY, selector
zu verhindern Auswahl
var id = event.target.id, tagName = event.target.tagName;
if(id.indexOf('selector') !== -1 || tagName === 'BODY' || tagName === 'HTML') {
return;
}
Dann brauchen wir ein Objekt zu erstellen, unsere Elemente zu speichern, wie so.
var elements = {
top: $('#selector-top'),
left: $('#selector-left'),
right: $('#selector-right'),
bottom: $('#selector-bottom')
};
Danach werden wir einige Variablen speichern, die einige Informationen über das Zielelement halten wie so.
var $target = event.target;
targetOffset = $target.getBoundingClientRect(),
targetHeight = targetOffset.height,
targetWidth = targetOffset.width;
Dann alles, was wir tun, ist die Position berechnen & Höhe für alle 4 Seiten des Wählers wie so.
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)
});
Alle des +aFewPixels
ist nur eine wenig Optimierung, so dass es wie 2px
Lücke zwischen dem Wähler und dem Ziel.
Für die CSS
das ist, was ich habe kommen mit.
#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;
}
Die transition
gibt dem Wähler eine sehr schöne Gleitwirkung.
Probieren Sie eine Demo http://jsfiddle.net/rFc8E/9/
Hinweis: Dies funktioniert auch für
transform: scale(2);
zB. wenn ein Element in der Größe skaliert.
Edit: Ich habe das gerade aktualisiert, bemerkte ich, dass das elements
Objekt war innerhalb der Event-Handler, habe ich es draußen in der Demo bewegt, ist dies durchaus eine wichtige Leistungsverbesserung, denn jetzt wird das elements
Objekt nur erstellt einmal statt Hunderttausende , wenn nicht Millionen mal innerhalb der mousemove
Veranstaltung .
Eine einfache Möglichkeit, es zu tun ist, einen Umriss statt einer Grenze zu verwenden:
.highlight { outline: 4px solid #07C; }
Just hinzufügen und entfernen diese Klasse zu jedem Element, das Sie auswählen möchten / Ausschluss (Code unten ist nicht richtig getestet):
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";
});
Da Sie eine Übersicht verwenden, (die von Chrome unterstützt wird) anstelle einer Grenze, Elemente werden nicht herumspringen. Ich verwende etwas ähnliches in meiner Easyreader Erweiterung .
Ich landete in der Firebug-Gruppe gefragt und bekam einige große Hilfe:
Überprüfen Sie auch dieses heraus:
http://rockingcode.com/tutorial / Element-dom-tree-jquery-Plugin-Firebug-like-Funktionalität /
Ich fand es ziemlich aufschlussreich .. und es gibt eine Demo hier:
http://rockingcode.com/demos/elemtree/
Hope, das hilft.
HTML-Element Picker (Vanilla JS)
Wählen und markieren Sie einen beliebigen HTML-Element auf einer Seite mit nur Vanille JS! Getestet in Chrome, FF und Opera nicht funktioniert im Internet Explorer.
Wie es funktioniert:
Was Sie brauchen, ist eigentlich sehr einfach. Sie können nur eine leere div-Box mit einem Hintergrund in JS erstellen und um zu Höhepunkt auf der Spitze schwebten Elemente bewegen. Hier ist der JS-Code:
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";
});
Siehe Demo
Ich habe auch ein npm Paket für das Element Picker mit vielen weiteren Benutzerkonfigurationen gemacht wie Hintergrundfarbe, Randbreite, Übergangs-, usw.
Hier ist die GitHub Seite .
Es gab eine ähnliche Frage auf Stackoverflow gefragt und es gab viele gute Antworten: Hat eine DOM-Inspektoren Javascript-Bibliothek oder Plugin jemand wissen?
Für diejenigen, die für eine schnelle und schmutzige Lösung suchen:
http://userscripts.org/scripts/review/3006 ist die einfachste. Einfach den Code innerhalb <script></script>
Tags und Sie sind gut zu gehen.
https://github.com/josscrowcroft /Simple-JavaScript-DOM-Inspector/blob/master/inspector.js ist etwas besser und immer noch sehr leicht in integrieren.
Für eine anspruchsvollere Element Inspektor, möchten Sie vielleicht die SelectorGadget überprüfen, wie Udi hingewiesen. Der Inspektor Auswahlcode ist in http://www.selectorgadget.com/stable/lib/ interface.js
Hier ist eine Bibliothek, die als Alternative in reinem Javascript geschrieben.
Theroom JS: https://github.com/hsynlms/theroomjs
// theroom information template for target element
var template="";
template += "<div id=\"theroom-info\">";
template += " <span id=\"theroom-tag\"><\/span>";
template += " <span id=\"theroom-id\"><\/span>";
template += " <span id=\"theroom-class\"><\/span>";
template += "<\/div>";
template += "";
template += "<style>";
template += " #theroom-info {";
template += " position: fixed;";
template += " bottom: 0;";
template += " width: 100%;";
template += " left: 0;";
template += " font-family: \"Courier\";";
template += " background-color: #ffffff;";
template += " padding: 10px;";
template += " color: #333333;";
template += " text-align: center;";
template += " box-shadow: 0px 4px 20px rgba(0,0,0,0.3);";
template += " }";
template += "";
template += " #theroom-tag {";
template += " color: #C2185B;";
template += " }";
template += "";
template += " #theroom-id {";
template += " color: #5D4037;";
template += " }";
template += "";
template += " #theroom-class {";
template += " color: #607D8B;";
template += " }";
template += "<\/style>";
var options = {
template: template,
showInfo: true
};
// initialize
theRoom.start(options);
Was Sie tun müssen, ist 4 Elemente für die Hervorhebung zu erstellen. Sie werden ein leeres Quadrat bilden und so Ihre Mausereignisse Feuer frei sind. Dies ist ähnlich wie dieses Overlay Beispiel ich gemacht habe.
Der Unterschied ist, dass Sie nur die vier Elemente müssen (kein Resize-Marker), und dass die Größe und die Position der vier Boxen ein bisschen anders ist (die rote Grenze mimick). Dann können Sie event.target
in Ihrem Ereignishandler verwenden, da es die reale oberste Element standardmäßig wird.
Ein weiterer Ansatz ist die exra Element zu verstecken, bekommen elementFromPoint
, berechnen sie dann zurück setzen.
Sie sind schneller als das Licht, das kann ich Ihnen sagen. Auch Einstein zustimmen würde:)
.1) elementFromPoint Overlay / Grenzen - [ Demo1 ] < em> FF muss 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) Mouseover Grenzen - [ 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);
}
Eine sehr einfache Implementierung sehr einfach und ohne jQuery getan werden kann, mit .onmouseover
und e.target
:
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");
}
}
Mit dem CSS unten, wenn Sie die Kinder zu ändern Hintergrund wollen auch:
.hovered,
.hovered * {
cursor: pointer;
color: black;
background-color: red;
}
Wenn Sie Elemente wollen in der Nähe der Ränder nur wählen (oder wählen Sie den Eltern in der Nähe der Kanten und das Element selbst überall sonst) Sie .getBoundingClientRect
nutzen könnten.
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;
}
});
mit einigen Grenzen Gepaart, kann dies für die Auswahl ziemlich verwendbar sein. Demo