【问题标题】:jQuery hover on stacked elements (with 'tipsy')jQuery悬停在堆叠的元素上(带有'tipsy')
【发布时间】:2012-08-19 07:34:13
【问题描述】:

我目前正在使用 jquery 的 tipsy 插件来显示轻量级工具提示。效果很好,适用于非嵌套元素。

假设我有:

<span>
    abc
    <span>def</span>
    ghi
</span>

并且我在每个跨度标签上都有一个悬停事件,当我尝试将鼠标悬停在内部跨度标签上时会得到奇怪的结果。我只希望它显示实际悬停的元素。没有别的了。

我该怎么做?

【问题讨论】:

    标签: javascript jquery popup hover tooltip


    【解决方案1】:

    Tipsy 被设计成一个开箱即用的简单插件。尽管有一些可配置的设置,但它们可能无法涵盖所有​​用例。
    但是,它确实提供了一个 api ($(el).tipsy(methodName)),这使它在某种程度上具有可扩展性。
    通过使用它的 api,您可以根据自己的规则强制执行某种行为(例如 show/hide)。

    以下是我将如何编写此解决方法:

    $('span')
        // init tipsy
        .tipsy({
            title : function(){
                return $(this).data('tipsy-title');
            }        
        })
       // overwrite the triggering logic
       .on('mousemove', function(e){
           // prevent the event from bubbling up
           e.stopPropagation();
    
           // force a hide on other targeted elements (suchas the span parent)
           $('span').not(this).tipsy('hide');
    
           // force a show on this element (such as thespan parent)
           $(this).tipsy('show');
        });​
    

    您可以通过clicking on this fiddle 看到上面的代码。

    更新
    我已经更新了代码以适应您的 html 标记:

    var $tips = $('.backref_hover')
           .tipsy()
           .on('mousemove', function(e){
               // prevent the event from bubbling up
               e.stopPropagation();
    
               // force a hide on other targeted elements (such as the span parent)
               $tips.not(this).trigger('mouseleave');
    
               // force a show on this element (such as thespan parent)
               $(this).tipsy('show');
            });​
    

    here 是在线演示。

    更新 #2 这是一个适用于动态添加跨度的演示:

    $('.backref_hover').tipsy({live:true});
    
    $('body').on('mousemove', '.backref_hover', function(e){
       // prevent the event from bubbling up
       e.stopPropagation();
       e.stopImmediatePropagation();
    
       // force a hide on other targeted elements (such as the span parent)
       $('.backref_hover').not(this).trigger('mouseleave');
    
       // force a show on this element (such as thespan parent)
       $(this).tipsy('show');
    });
    

    @Lindrian:我在评论中所说的只是(取自jQuery docs):

    从 jQuery 1.7 开始,不推荐使用 .live() 方法。使用 .on() 附加事件处理程序。

    这个例子说明了如何使用on而不是live来委托事件。
    也可以在行动中看到here

    【讨论】:

    • 感谢您的回复,但它对我不起作用。这是html:&lt;span class="backref_hover match0" original-title=""&gt;&lt;span class="backref_hover match1" original-title="Backreference 1: abc"&gt;a&lt;span class="backref_hover match2" original-title="Backreference 2: b"&gt;b&lt;/span&gt;c&lt;/span&gt;&lt;/span&gt;。我只是将“跨度”更改为“.backref_hover”
    • 仍然无法让它在我这边工作。如果元素是动态创建的,这有关系吗?我在醉酒选项中添加了“live:true”,这使它显示弹出窗口,但它们仍然堆叠。
    • 天啊!当然很重要!我使用了您的代码,只是也将 mousemove 事件更改为实时事件。现在它完美无缺。非常感谢!
    • 没有 porb。顺便说一句,您可能仍应使用 on 方法(与已弃用的 $(mainWrapper).on(event, $tips, handler) jQuery 方法略有不同:$(mainWrapper).on(event, $tips, handler)
    • 我尝试使用您的代码,带有on 的代码,但没有奏效。当我更改为live 时,它起作用了。我将您的第一个示例与我提到的更改一起使用。一个合适的代码示例应该是什么样子的?
    【解决方案2】:

    如果您控制 html,如何标记您想要工具提示的特定 span?您可以使用class 来做到这一点:

    <span>
        [unknown number of spans]
        <span class="use-tooltip" title="Backreference x: y">def</span>
        [unknown number of close spans]
    </span>
    

    您的插件调用将是:

    $('.use-tooltip').tipsy();
    

    【讨论】:

      【解决方案3】:

      据我了解您的问题,您可以通过修改 Tipsy 插件来解决此问题。您可以将自己的自定义选项添加到参数(例如hideParentTip: true),即:

      $('span span').tipsy({hideParentTip: true});
      

      然后你需要修改插件本身。在153这一行,你需要在function enter() {之后放置下一个代码,即:

      function enter() {
          if (options.hideParentTip) $(this).parent().trigger(eventOut);
      

      希望对您有所帮助。如果不会,请告诉我

      【讨论】:

      • 修改插件有点过激。如果您希望在以后更新插件,则必须重新应用您的更改。
      • @Spolto 是的,实际上,如果内部元素也不是直接后代,这也不能解决问题。或许去掉答案会更好,你怎么看?
      • 查看我更新的答案以获得不涉及更改插件的简单代码示例。
      • 嵌套标签的数量可能是无限的,所以我猜这不起作用。
      • @Lindrian 插件修改是否足以满足您的需求?如果可能的话,我会发明smth。如果没有,那么您可能必须使用其他插件,因为 tipsy 似乎没有任何适用的选项
      【解决方案4】:

      你可以试试这样的..

      $(function(){   
          $('body').children('span').tipsy( 
          });​
      

      看看它是否有效。我认为它会选择所有留下它的孩子的跨度标签。

      【讨论】:

        【解决方案5】:

        我使用了一段时间的 gion_13s 解决方案。但事实证明,对较大数据集的浏览器/cpu 要求很高。根据他的代码,我想出了一个更好的解决方案:

            $('body').on('mousemove', '.backref_hover', function(e){
            // prevent the event from bubbling up
            e.stopPropagation();
            e.stopImmediatePropagation();
        
            // force a hide on other targeted elements (such as the span parent)
            $(this).parent().children('.backref_hover').not(this).trigger('mouseleave');
        
            // force a show on this element (such as thespan parent)
            $(this).tipsy('show');
        });
        

        【讨论】:

          猜你喜欢
          • 2021-09-26
          • 2010-11-18
          • 1970-01-01
          • 1970-01-01
          • 2011-06-02
          • 1970-01-01
          • 2010-12-08
          • 2010-11-22
          • 2015-04-01
          相关资源
          最近更新 更多