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.

War es hilfreich?

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 .

Ü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);

codepen Demo

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;
}

Demo


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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top