简体   繁体   English

jQuery Tipsy不适用于jQuery.each()和live:true

[英]jQuery Tipsy won't work with jQuery.each() and live:true

Note: This question was marked as solved once, but it figured out that upgrading to the latest jQuery was fixed only one issue. 注意:这个问题曾经被标记为已解决,但是它发现升级到最新的jQuery仅解决了一个问题。 Please see the updated question below for the remaining issue. 请参阅下面的更新的问题以了解剩余的问题。

Hi all, 大家好,

I have just run into a weird issue with jQuery.Tipsy. 我刚遇到jQuery.Tipsy的怪异问题。

Here's a simplified demo fiddle: http://jsfiddle.net/6nWtx/7/ 这是一个简化的演示小提琴: http : //jsfiddle.net/6nWtx/7/

As you can see, the lastly added a.tipsy2 element does not get tipsyfied. 如您所见,最后添加的a.tipsy2元素不会被提示。 The .tipsy2 elements are being tipsyfied within a jQuery.each() function and at this point I have the problem. .tipsy2元素在jQuery.each()函数中被提示,这时我遇到了问题。 Without the each() it works. 没有each()它将起作用。 Unfortunately, I need .each() to iterate through the elements to do some other stuff before I call tipsy() . 不幸的是,我需要的.each()通过元素迭代做一些其他的东西之前,我打电话tipsy()

Any suggestion? 有什么建议吗?

Here's the source code of Tipsy: https://github.com/jaz303/tipsy/blob/master/src/javascripts/jquery.tipsy.js 这是Tipsy的源代码: https : //github.com/jaz303/tipsy/blob/master/src/javascripts/jquery.tipsy.js

IMHO the problem is using the combination of jQuery.each() and Tipsy option live:true 恕我直言,问题是使用jQuery.each()和Tipsy选项live:true

Update: 更新:

The other stuff I want to do before calling .tipsy() is checking for some optional configuration. 在调用.tipsy()之前,我想做的其他事情是检查一些可选配置。

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

In this example I will add the following option to Tipsy: delayIn:1000 If there is no delayed class associated to the element this parameter will be delayIn:0 . 在此示例中,我将向Tipsy添加以下选项: delayIn:1000如果没有与该元素关联的delayed类,则此参数将为delayIn:0

Using the same logic, I want to specify the following classes as well: show-top, show-left, show-right, show-bottom for the Tipsy option called gravity . 使用相同的逻辑,我也要指定以下类:Tipsy选项的gravity show-top, show-left, show-right, show-bottom

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

The full code: 完整代码:

$(".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
    })
})

And here is a full jsFiddle demo with all the stuffs I want to do: http://jsfiddle.net/xmLBG/1/ 这是一个完整的 jsFiddle演示,其中包含我想做的所有事情: http : //jsfiddle.net/xmLBG/1/

If you use jQuery 1.7.1 instead of 1.6.4 it will work. 如果您使用jQuery 1.7.1而不是1.6.4,它将起作用。 Maybe that live feature is relying on something buggy with the older versions, or some not-yet-implemented feature. 可能是实时功能依赖于旧版本中的某些错误,或者某些尚未实现的功能。

Update: from what I understood, you want the tipsy plugin to be called to every element with the .tipsyfy class, present now or added in the future. 更新:从我的理解,你想要的tipsy插件调用的每个元素与.tipsyfy类,现在是现在还是在将来添加。 You don't want to (or can't) call it explicitly before insertion. 您不想(或不能)在插入之前显式调用它。 You're trying to accomplish that using the live option of the plugin. 您正在尝试使用插件的live选项来实现。 Is that right? 那正确吗?

If that's the case I can offer a workaround. 如果是这样,我可以提供一种解决方法。 I tried to use on (since jQuery's live is deprecated) to bind some code to the load event, but it didn't work, so I bound it to mouseenter and checked whether or not the plugin was already built for that element. 我尝试使用on (因为jQuery的live被弃用了)将一些代码绑定到load事件,但是它没有用,所以我将其绑定到mouseenter并检查插件是否已针对该元素构建。 If not, it builds it and re-triggers the event. 如果不是,它将生成它并重新触发该事件。

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

Live example at jsFiddle . jsFiddle的实时示例。

For a small optimization, if the sole purpose of the .tispsyfy class is to instruct the plugin creation, and you don't need it afterwards, you can remove it prior to re-triggering the mouseenter . 对于小型优化,如果.tispsyfy类的唯一目的是指示插件的创建,并且此后不需要它,则可以在重新触发mouseenter之前将其删除。 This way the checking code won't be called over and over again: 这样,不会一遍又一遍地调用检查代码:

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

As far as I can see, you don't need to iterate the nodelist. 据我所知,您不需要迭代节点列表。 It looks like tipsy does that for you (see this jsfiddle , where in the first list every element gets its own tooltip (1,2,3). 它看起来像tipsy会替你(看到这的jsfiddle ,其中在第一列表中的每个元素都有自己的工具提示(1,2,3)。

Can't you do this instead? 您不能这样做吗? It is what you are asking. 这就是你要的。

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

KooiInc is right, 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">

And

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

That will work fine 那会很好

My guess is that Tipsy are uses some kind of direct mapping to the result, not using the live (in 1.6) or on in newer versions of jQuery. 我的猜测是,醉了都使用某种直接映射到结果,使用不live (1.6),或on jQuery中的较新版本。
So when your trying to apply the plugin to the links with the class tipsy2 it cant find any (cause your adding it to the DOM at a later stage in your code). 因此,当您尝试将插件应用于tipsy2类的链接时,它找不到任何插件(因为稍后在代码tipsy2其添加到DOM中)。 The easiest fix to this is just to run the tipsy function at a later stage, perhaps on document.ready . 最简单的解决方法是在稍后的阶段(可能在document.ready上)运行tipsy函数。

// 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/ ) http://jsfiddle.net/8dg6S/7/

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

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