【问题标题】:jQuery Tipsy won't work with jQuery.each() and live:truejQuery Tipsy 不适用于 jQuery.each() 和 live:true
【发布时间】:2012-03-02 09:31:18
【问题描述】:

注意:这个问题被标记为已解决一次,但它发现升级到最新的 jQuery 只修复了一个问题。有关剩余问题,请参阅下面的更新问题。

大家好,

我刚刚遇到了一个关于 jQuery.Tipsy 的奇怪问题。

这是一个简化的演示小提琴:http://jsfiddle.net/6nWtx/7/

如您所见,最后添加的 a.tipsy2 元素并没有得到提示。 .tipsy2 元素在 jQuery.each() 函数中被提示,此时我遇到了问题。没有each() 它可以工作。不幸的是,在调用tipsy() 之前,我需要.each() 遍历元素以执行其他操作。

有什么建议吗?

这里是Tipsy的源代码:https://github.com/jaz303/tipsy/blob/master/src/javascripts/jquery.tipsy.js

恕我直言,问题在于使用 jQuery.each() 和 Tipsy 选项 live:true 的组合

更新:

在调用.tipsy() 之前我想做的另一件事是检查一些可选配置。

例如:<a href="#" title="This is a tooltip" class="tipsyfy delayed">Help</a>"

在本例中,我将向 Tipsy 添加以下选项:delayIn:1000 如果没有与元素关联的 delayed 类,则此参数将为 delayIn:0

使用相同的逻辑,我还想指定以下类:show-top, show-left, show-right, show-bottom 用于名为 gravity 的 Tipsy 选项。

示例:<a href="#" title="This is a tooltip" class="tipsyfy delayed show-left">Help</a>"

完整代码:

$(".tipsyfy").each(function () {
    var a = "s",
        b = 0;
    if ($(this).hasClass("show-left")) a = "w";
    else if ($(this).hasClass("show-down")) a = "n";
    else if ($(this).hasClass("show-right")) a = "e";
    if ($(this).hasClass("delayed") && $(this).attr("data-delayIn") != null) b = $(this).attr("data-delayIn");
    $(this).tipsy({
        gravity: a,
        fade: true,
        live: true,
        delayIn: b
    })
})

这是一个完整 jsFiddle 演示,包含我想做的所有事情:http://jsfiddle.net/xmLBG/1/

【问题讨论】:

  • 我想你需要遍历这些元素
  • 是的,我想对每个元素做一些其他的事情。

标签: javascript jquery tipsy


【解决方案1】:

如果您使用 jQuery 1.7.1 而不是 1.6.4,它将起作用。也许该实时功能依赖于旧版本存在的错误,或者某些尚未实现的功能。

更新:据我了解,您希望 tipsy 插件被调用到具有 .tipsyfy 类的每个元素,现在存在或将来添加。您不想(或不能)在插入之前显式调用它。您正在尝试使用插件的 live 选项来完成此操作。对吗?

如果是这种情况,我可以提供一种解决方法。我尝试使用on(因为不推荐使用jQuery 的live)将一些代码绑定到 load 事件,但它不起作用,所以我将它绑定到 mouseenter 并检查插件是否已经为该元素构建。如果没有,它会构建它并重新触发事件。

$(document).on("mouseenter", ".tipsyfy", function(e) {
    if ( !$(this).data("tipsy") ) {
        e.preventDefault();
        var a = "s",
            b = 0;
        if ($(this).hasClass("show-left")) a = "e";
        else if ($(this).hasClass("show-down")) a = "n";
        else if ($(this).hasClass("show-right")) a = "w";
        if ($(this).hasClass("delayed") && $(this).attr("data-delayIn") != null) b = $(this).attr("data-delayIn");
        $(this).tipsy({
            gravity: a,
            fade: true,
            live: true,
            delayIn: b
        }).trigger("mouseenter");
        return false;
    }
});            

jsFiddle 上的实时示例。

为了一个小的优化,如果.tispsyfy类的唯一目的是指导插件创建,而你之后不需要它,你可以在重新触发mouseenter强>。这样就不会一遍又一遍地调用检查代码:

$(this).tipsy({...}).removeClass("tipsyfy").trigger("mouseenter");

【讨论】:

  • 天哪!太容易了。非常感谢!
  • 因为我使用类来微调特定元素的醉酒行为。例如:<a class="tipsyfy top delayed" href="#">Tipsy showed delayed at the top</a><a class="tipsyfy" href="#">Tipsy default</a>
  • 嗨。再次感谢您的建议,但它发现升级到最新的 jQuery 并不能解决所有问题。请参阅我更新的问题和更新的 jsFiddle 演示。如果你能帮助我,请提前谢谢。
  • 我用一个应该做你想做的解决方法更新了答案。 AFAIK 无法在 load 事件中使用liveon,所以这是我能想到的唯一方法(在ajax 回调中手动调用.tispy() 的不足)。
  • 这是一个解决方案!赏金是你的。多谢! :)
【解决方案2】:

据我所知,您不需要迭代节点列表。看起来tipsy 为你做了这件事(参见jsfiddle,在第一个列表中,每个元素都有自己的工具提示 (1,2,3)。

【讨论】:

  • 那是因为tipsy会为你做迭代,所以如果你“手动”迭代,它会干扰它。查看编辑后的 ​​jsfiddle (jsfiddle.net/KooiInc/B2qDN)
  • 谢谢,但它是旧版本的 jQuery。更新到最新版本解决了这个问题。
  • 我不认为这是版本,而是醉酒的内部运作。为了演示,我更新了 jsfiddle 以证明 each 与 jQuery 1.6.4 一起使用
  • 好的,再一次。我想遍历每个具有.tipsyfy 类的项目。然后在我打电话给$(this).tipsy(...); 之前,我想在每个项目上做一些其他的事情,但这不适用于 jQuery 1.6.x
  • 在这种情况下,删除 each 内分配中的 live 属性将解决 1.6.4 的问题。 Jsfiddle 再次更新,仅供参考。
【解决方案3】:

KooiInc 是对的,

<a class="tipsy1" href="#" title="Tipsy">TipsyLink</a>
<a class="tipsy1" href="#" title="Tipsy">TipsyLink</a>
<a class="tipsy1" href="#" title="Tipsy">TipsyLink</a>
<br />
<div id="container"></div>
<input id="add" type="button" value="ok">

还有

$(".tipsy1").tipsy({live:true,fade:true});
$(".tipsy2").tipsy({live:true});
$("#add").click(function() {
    $("#container").append('<a class="tipsy2" href="#" title="Tipsy">TipsyLink</a>');
});

这样就好了

【讨论】:

    【解决方案4】:

    我的猜测是,Tipsy 使用某种直接映射到结果,而不是在较新版本的 jQuery 中使用 live(在 1.6 中)或 on
    因此,当您尝试将插件应用到类 tipsy2 的链接时,它找不到任何(导致您在代码的后期将其添加到 DOM)。最简单的解决方法是在稍后阶段运行小费函数,也许在 document.ready 上。

    // this works
    $(".tipsy1").tipsy({live:true,fade:true});
    
    // add new tipsy element (ok)
    $(document.body).append('<a class="tipsy1" href="#" title="TipsyAjax">AjaxTipsy1</a><br/>');
    
    // add new tipsy element (not ok)
    $(document.body).append('<a class="tipsy2" href="#" title="Tipsy">TipsyLink</a>');
    
    $(document).ready(function () {
        $(".tipsy2").each(function(){
           // I'm doing some other logic here before I call .tipsy()
           $(this).tipsy({live:true,fade:true});
        })
    });
    

    (http://jsfiddle.net/8dg6S/7/)

    【讨论】:

    • 好的,更进一步。但是,新元素将通过一些 ajax 调用添加,因此在 document.ready 回调运行之后。如果我添加新元素之后它仍然无法正常工作,请参阅:jsfiddle.net/8dg6S/8
    • 您能否在您将从 ajax 调用返回的每个结果集上运行 Tipsy 插件?
    • 我不应该那样做。这就是引入 live 方法的原因。但当然,如果没有合适的解决方案,我会这样做。
    • 我想不出更好的解决方案:\。也许您可以研究 Tipsy 插件是如何编写的,并对其进行分叉并根据您的需要进行修改?这可能需要更多的工作,但也许最终会得到回报......
    • 是的,我现在就在做。试图弄清楚它是如何工作的以及问题出在哪里......这就是 50 赏金的原因。也许有人能找到它。
    【解决方案5】:

    你不能这样做吗?这就是你要问的。

    $(".tipsy1,.tipsy2").tipsy({live:true,fade:true});
    $(".tipsy2").each(function() {
        //do your stuff
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-12
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 2016-08-09
      • 2014-02-09
      相关资源
      最近更新 更多