jQuery: Highlight element under mouse cursor?

Posted by Ralph on Stack Overflow See other posts from Stack Overflow or by Ralph
Published on 2011-01-15T05:57:48Z Indexed on 2011/01/16 1:53 UTC
Read the original article Hit count: 390

Filed under:

I'm trying to create an "element picker" in jQuery, like Firebug has. Basically, I want to highlight the element underneath the user's mouse. Here's what I've got so far, but it isn't working very well:

$('*').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');

Basically, I'm injecting a div into the DOM that has a semi-transparent background. Then I listen for the mouseover event on every element, then move the div so that it covers that element.

Right now, this just makes the whole page go red as soon as you move your mouse over the page. How can I get this to work nicer?

Edit: Pretty sure the problem is that as soon as my mouse touches the page, the body gets selected, and then as I move my mouse around, none of the moments get passed through the highligher because its overtop of everything.


Firebug

Digging through Firebug source code, I found this:

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

Looks like they're using a standard div + css to draw it..... just have to figure out how they're handling the events now... (this file is 28K lines long)

There's also this snippet, which I guess retrieves the appropriate object.... although I can't figure out how. They're looking for a class "objectLink-element"... and I have no idea what this "repObject" is.

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

},

I'm thinking that maybe when the mousemove or mouseover event fires for the highlighter node I can somehow pass it along instead? Maybe to node it's covering...?

© Stack Overflow or respective owner

Related posts about jQuery