简体   繁体   English

盘旋在Raphaeljs的一组元素

[英]Hovering over a set of elements in Raphaeljs

I have a set that only contains a rectangle. 我有一个只包含一个矩形的集合。

var hoverTrigger = this.paper.set();
var outline = this.paper.rect();
outline.attr({
...
hoverTrigger.push(outline)
this.sprite.push(hoverTrigger);

Upon hover, the rectangle is supposed to expand, and some links are added to it, and upon mouse off, the links disappear and the rectangle becomes small again. 悬停时,矩形应该展开,并添加一些链接,鼠标关闭后,链接消失,矩形再次变小。

hoverTrigger.hover(function () {
  var link = this.paper.text();
  hoverTrigger.push(link);
  outline.animate({
  ...
}, function() {
  link.remove();
  outline.animate({
  ...
});

However, it seems like the hover function is being applied to each item in the set individually, and not the whole set, because when you go to mouse over a link, the hover off function fires and the link disappears. 但是,似乎悬停功能单独应用于集合中的每个项目,而不是整个集合,因为当您将鼠标悬停在链接上时,悬停功能将触发,链接将消失。 Sometimes the box gets hover on and hover off events in quick succession and spazzes. 有时盒子会悬停在快速连续和spazzes上的事件中。

Is there a way to apply a hover to a set of things, so that mousing between two things in the set doesn't trigger hover off? 有没有办法将悬停应用于一组事物,以便在集合中的两件事之间进行鼠标悬停不会触发悬停?

Having faced this limitation myself recently, I decided to write a small extension to Raphael called hoverInBounds that resolves it. 我最近自己面对这个限制,我决定给Raphael写一个小扩展名为hoverInBounds来解决它。

Simply, once the mouse enters the element we keep track of when it actually moves outside its bounds - executing the hover out function then, not before. 简单地说,一旦鼠标进入元素,我们就会跟踪它实际移动到其边界之外的时间 - 然后执行悬停功能,而不是之前。

Demo: http://jsfiddle.net/amustill/Bh276/1 演示: http//jsfiddle.net/amustill/Bh276/1

Raphael.el.hoverInBounds = function(inFunc, outFunc) {
    var inBounds = false;

    // Mouseover function. Only execute if `inBounds` is false.
    this.mouseover(function() {
        if (!inBounds) {
            inBounds = true;
            inFunc.call(this);
        }
    });

    // Mouseout function
    this.mouseout(function(e) {
        var x = e.offsetX || e.clientX,
            y = e.offsetY || e.clientY;

        // Return `false` if we're still inside the element's bounds
        if (this.isPointInside(x, y)) return false;

        inBounds = false;
        outFunc.call(this);
    });

    return this;
}

Place the above block of code before you create your Raphael paper object. 在创建Raphael纸张对象之前放置上面的代码块。

I hit on this problem before. 我之前遇到过这个问题。 I found 2 solutions. 我找到了2个解决方案

Create a rectangle over other elements with opacity set to 0 在不透明度设置为0的其他元素上创建一个矩形

var paper = new Raphael( 0, 0, 100, 100 );
var rect = paper.rect( 0, 0, 100, 100 ).attr({ opacity: 0 });
rect.hover( func_in, func_out );

This only works for elements that have 1 overall action like click. 这仅适用于具有单击操作等1个整体操作的元素。

The other option is to cancel the hover function when hovering over a set of elements 另一种选择是在将鼠标悬停在一组元素上时取消悬停功能

var funcOutTimer;

set.hover( function( ) {
    if( funcOutTimer ) { // Hovered into this element in less than 100 milliseconds => cancel
        window.clearTimeout( funcOutTimer);
    } else {
    // do stuff
    }
},
function( ) {
    funcOutTimer = setTimeout( function( ) {
        // do stuff
    }, 100 ); // wait for 100 milliseconds before executing hover out function
});

Basically the hover in function is only executed when first entering a set of elements for the first time and the hover out function will only execute once when finally the element you have hovered into is not part of that set. 基本上,函数中的悬停仅在第一次首次输入一组元素时执行,而悬停输出函数只会执行一次,因为最后您悬停的元素不是该组的一部分。

I found that this works with the following 我发现这适用于以下内容

myCircleElement.hover (
    function(e) { myTextElement.animate({opacity:1}, 800); },
    function(e) {
        var x = e.layerX || e.x,
        y = e.layerY || e.y;
        // Return `false` if we're still inside the element's bounds                                        
        if (this.isPointInside(x, y)) return false;
        // otherwise do something here.. eg below
        myTextElement.animate({opacity:0}, 800); //
    }
);

The method Bruno details have this minor issue: Bruno详细信息的方法有这个小问题:

If you create a rectangle over the other elements, if the other elements are text then those texts can't be selected in the web page. 如果在其他元素上创建矩形,如果其他元素是文本,则无法在网页中选择这些文本。 But it works. 但它的确有效。

By the way the attribute "opacity": 0 is not enough, I had to add the "fill": "white" attribute in my case. 顺便说一下属性“不透明度”:0是不够的,我不得不在我的情况下添加“填充”:“白色”属性。

You need to bring the object to the front like this: obj.toFront(); 您需要将对象放在前面,如下所示:obj.toFront(); obj is a raphael shape like "rect", etc. obj是像“rect”等的raphael形状。

I tested it on a mouseover and mouseout event and it works. 我在mouseover和mouseout事件上测试了它并且它可以工作。

Check my fiddle here: link to fiddle 在这里查看我的小提琴: 链接到小提琴

function withArray(x,y){
    var rect = paper.rect(x, y, 100, 60).attr({
        fill: "green"
    });
    rect.text = paper.text(x+(100/2), y + 30, 'rect w/array').attr({
        'font-size': 12,
        "fill": "white"
    });
    var rectover = paper.rect(x,y,100,60).attr({
        fill: "white",
        opacity: 0
    });
    var myArray = paper.set();
    myArray.push(rect, rect.text, rectover);
    myArray.mouseover(function() {
    var anim = Raphael.animation({
    transform: ['S', 1.5, 1.5, (rect.attr("x")), (rect.attr("y"))]
        }, 100, "backOut", function() {
    });
    myArray.animate(anim);
    }).mouseout(function() {
        var anim = Raphael.animation({
            transform: [""]
        }, 50, "backOut", function() {
   });
   myArray.stop().animate(anim);
});
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM