Javascript: permitir al usuario seleccionar un elemento HTML como Firebug?
-
25-09-2019 - |
Pregunta
Quiero escribir un navegador extensión (Cromo / FF) que las necesidades para seleccionar un elemento en una página web. Me gustaría que se comporte como interventor elemento de Firebug hace. Hace clic en el inspeccione la flecha y se puede entonces libración / elementos de relieve. Al hacer clic en el elemento que desea, se inspecciona el elemento. Sólo estoy interesado en el código para permitir que un usuario seleccione un elemento -. No en realidad inspeccionarlo o algo similar
Debido a que estoy escribiendo una extensión, que podría ser bueno si pudiera proporcionar no jQuery / Prototype / etc .. código de modo que no tengo que distribuir.
Solución
Me escribió una implementación de este usando jQuery como un componente de otro proyecto. La fuente y la documentación están disponibles aquí: https://github.com/andrewchilds/jQuery.DomOutline
Otros consejos
He requerido recientemente una característica de este tipo para un proyecto que estaba trabajando, resultó que tenía que usar para los lados para crear un cuadro, porque de lo contrario el event.target
cuando se mueve el ratón terminaría siendo el selector, y si fuera a utilizar z-index: -1
sería un poco a pescado cuando se tiene una gran cantidad de elementos que se superponen ... etc.
Esta es una versión que he convertido de mi proyecto para su beneficio, se trata de jQuery, pero es extremadamente sencilla para la conversión vainilla que sólo se usan los métodos mousemove
y css
de jQuery.
Instrucciones paso a paso.
En primer lugar crear el 5 HTMLElements que se requieren.
<div id="selector">
<div id="selector-top"></div>
<div id="selector-left"></div>
<div id="selector-right"></div>
<div id="selector-bottom"></div>
</div>
En segundo lugar crear un evento mousemove
en la document
(o su envase)
$(document).mousemove(function(event) { ... });
A continuación, dentro de la mousemove
vamos a hacer algunas comprobaciones básicas para evitar la selección de la HTML, BODY, selector
var id = event.target.id, tagName = event.target.tagName;
if(id.indexOf('selector') !== -1 || tagName === 'BODY' || tagName === 'HTML') {
return;
}
A continuación, tenemos que crear un objeto para almacenar nuestros elementos como tal.
var elements = {
top: $('#selector-top'),
left: $('#selector-left'),
right: $('#selector-right'),
bottom: $('#selector-bottom')
};
Después de que almacenamos algunas variables que contienen alguna información sobre el elemento objetivo como tal.
var $target = event.target;
targetOffset = $target.getBoundingClientRect(),
targetHeight = targetOffset.height,
targetWidth = targetOffset.width;
A continuación, todo lo que hacemos es calcular el Posición & Altura para todos 4 lados del selector como tal.
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)
});
Todo el +aFewPixels
es sólo un poco de optimización de modo que no es como la brecha en 2px
entre el selector y el objetivo.
Para el CSS
esto es lo que han llegado con.
#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;
}
El transition
da el selector de un muy buen efecto de deslizamiento.
Pruebe una demo http://jsfiddle.net/rFc8E/9/
Nota: Esto también funciona para
transform: scale(2);
por ejemplo. cuando un elemento se escala de tamaño.
Editar He acaba de actualizar esto, me di cuenta de que el objeto era elements
dentro de el controlador de eventos, me he movido fuera de la demo, esto es toda una importante mejora en el rendimiento porque ahora, el objeto elements
sólo se crea una vez en lugar de Cientos de miles si no millones de veces dentro del evento mousemove
.
Una forma sencilla de hacerlo es utilizar un esquema en lugar de una frontera:
.highlight { outline: 4px solid #07C; }
Sólo tiene que añadir y quitar esa clase a cualquier elemento que desea seleccionar / Suprimir (código de abajo no se ha probado adecuadamente):
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";
});
Desde que está utilizando un esquema, (que es apoyado por Chrome) en lugar de una frontera, los elementos no saltar alrededor. Estoy usando algo similar en mi EasyReader Extensión .
terminé preguntando en el grupo de Firebug y de algunos de gran ayuda:
También comprobar éste hacia fuera:
http://rockingcode.com/tutorial / elemento-dom-árbol-jquery-plugin-incendiario-como-funcionalidad /
Me pareció bastante perspicaz .. y hay una demo aquí:
http://rockingcode.com/demos/elemtree/
Espero que esto ayude.
Selector de elementos HTML (vainilla JS)
Seleccionar y resaltar cualquier elemento HTML en una página con solamente vainilla JS! Probado en Chrome, FF y Opera, no funciona en IE.
¿Cómo funciona?:
Lo que necesita es realmente muy simple. Usted sólo puede crear un cuadro de div vacío con un fondo en JS y moverlo a más destacado en la parte superior de los elementos rondado. Aquí está el código 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";
});
Ver demostración de
También hice un NPM paquete para el selector de elemento con muchas configuraciones más usuarios como color de fondo, el ancho del borde, de transición, etc.
Aquí está el GitHub página .
Hubo una pregunta similar se le preguntó sobre Stackoverflow y tenía un montón de buenas respuestas: ¿Alguien sabe de una biblioteca DOM Inspector JavaScript o plug-in / a>
Para aquellos que están buscando una solución rápida y sucia:
http://userscripts.org/scripts/review/3006 es la más fácil. Sólo hay que poner el código dentro de las etiquetas <script></script>
y que son buenos para ir.
https://github.com/josscrowcroft /Simple-JavaScript-DOM-Inspector/blob/master/inspector.js es ligeramente mejor y siendo muy fácil de integrar en.
En un inspector elemento más sofisticado, es posible que desee revisar la SelectorGadget como se ha señalado por la UDI. El código de selección inspector es en http://www.selectorgadget.com/stable/lib/ interface.js
Aquí es una biblioteca que escrito en JavaScript puro como una alternativa.
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);
Lo que hay que hacer es crear 4 elementos para el resaltado. Ellos formarán un cuadrado vacío , y así sus eventos de ratón son libres de fuego. Esto es similar a este ejemplo de superposición que he hecho.
La diferencia es que sólo necesita los cuatro elementos (no hay marcadores de cambio de tamaño), y que el tamaño y la posición de las 4 cajas son un poco diferentes (para imitar el borde rojo). A continuación, puede utilizar event.target
en el controlador de eventos, porque se pone el elemento real superior de forma predeterminada.
Otro enfoque es ocultar el elemento exra, obtener elementFromPoint
, calcular luego la puso de nuevo.
Son más rápidos que la luz, que puede decir. Incluso Einstein estaría de acuerdo:)
.1) elementFromPoint Superposición / fronteras - [ Demo1 ] < em> FF necesita 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) fronteras mouseover - [ 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);
}
Una aplicación muy básica se puede hacer muy fácilmente sin el uso de jQuery .onmouseover
y 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");
}
}
Con el CSS a continuación si desea que los niños para cambiar el fondo, así:
.hovered,
.hovered * {
cursor: pointer;
color: black;
background-color: red;
}
Si desea seleccionar sólo los elementos cercanos a los bordes (o seleccione la matriz cerca de los bordes y el elemento en sí en cualquier otro lugar) se puede utilizar .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;
}
});
Junto con algunas fronteras, esto puede ser muy útil para la selección. Demostración