如何使用叠加效果高亮显示鼠标光标下的元素? [英] How do I efficiently highlight element under mouse cursor with an overlay?

查看:147
本文介绍了如何使用叠加效果高亮显示鼠标光标下的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

仍在尝试回答这个问题,我想我终于找到了一个解决方案,但运行速度太慢。

Still trying to answer this question, and I think I finally found a solution, but it runs too slow.

var $div = $('<div>')
    .css({ 'border': '1px solid red', 'position': 'absolute', 'z-index': '65535' })
    .appendTo('body');

$('body *').live('mousemove', function(e) {
    var topElement = null;
    $('body *').each(function() {
        if(this == $div[0]) return true;
        var $elem = $(this);
        var pos = $elem.offset();
        var width = $elem.width();
        var height = $elem.height();
        if(e.pageX > pos.left && e.pageY > pos.top
            && e.pageX < (pos.left + width) && e.pageY < (pos.top + height)) {
            var zIndex = document.defaultView.getComputedStyle(this, null).getPropertyValue('z-index');
            if(zIndex == 'auto') zIndex = $elem.parents().length;
            if(topElement == null || zIndex > topElement.zIndex) {
                topElement = {
                    'node': $elem,
                    'zIndex': zIndex
                };
            }

        }
    });
    if(topElement != null ) {
        var $elem = topElement.node;
        $div.offset($elem.offset()).width($elem.width()).height($elem.height());
    }
});

它基本上循环遍历页面上的所有元素,并找到光标下方的最顶层元素。

It basically loops through all the elements on the page and finds the top-most element beneath the cursor.

是否有某些方法可以使用四叉树或其他东西并对页面进行分段以使循环运行得更快?

Is there maybe some way I could use a quad-tree or something and segment the page so the loop runs faster?

推荐答案


是否有某种方法可以使用四叉树或其他东西并对页面进行分段以使循环运行得更快?

Is there maybe some way I could use a quad-tree or something and segment the page so the loop runs faster?

稍微退一步,意识到问题有多小,并且你尝试的答案越难以使用。

Just step back a bit, realize how small the problem is, and that the harder your try the more complicated answer you will use.

现在你需要做的是为突出显示创建4个元素。它们将形成一个空方,因此您的鼠标事件可以自由发射。这类似于我所制作的叠加示例

Now what you need to do is to create 4 elements for the highlighting. They will form an empty square, and so your mouse events are free to fire. This is similar to this overlay example I've made.

区别在于你只需要四个元素(没有调整大小标记),并且4个盒子的大小和位置有点不同(模仿红色)边界)。然后你可以在你的事件处理程序中使用 event.target ,因为它默认获得真正的最顶层元素。

The difference is that you only need the four elements (no resize markers), and that the size and position of the 4 boxes are a bit different (to mimick the red border). Then you can use event.target in your event handler, because it gets the real topmost element by default.

另一种方法是隐藏exra元素,得到 elementFromPoint ,然后计算然后把它回来了。

Another approach is to hide the exra element, get elementFromPoint, calculate then put it back.

我告诉你,它们比光更快。甚至爱因斯坦也会同意:)

They're faster than light, I can tell you. Even Einstein would agree :)

1。)elementFromPoint overlay / borders - [演示1 ] 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。)mouseover borders - [ Demo2 ]


2.) mouseover borders - [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);
}

这篇关于如何使用叠加效果高亮显示鼠标光标下的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆