JQuery Tipsy не будет работать с jQuery.each () и live: true - PullRequest
2 голосов
/ 02 марта 2012

Примечание. Этот вопрос был помечен как решенный один раз, но выяснилось, что при обновлении до последней версии jQuery была устранена только одна проблема. Пожалуйста, см. Обновленный вопрос ниже для оставшейся проблемы.

Привет всем,

Я только что столкнулся со странной проблемой с jQuery.Tipsy.

Вот упрощенная демонстрационная скрипка: http://jsfiddle.net/6nWtx/7/

Как видите, последний добавленный элемент a.tipsy2 не получает подсказки. Элементы .tipsy2 в настоящее время настраиваются внутри функции jQuery.each(), и в этот момент у меня возникла проблема. Без each() это работает. К сожалению, мне нужно .each(), чтобы перебрать элементы, чтобы сделать другие вещи, прежде чем я вызову tipsy().

Есть предложения?

Вот исходный код 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 для опции Tipsy, которая называется gravity.

Пример: <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
    })
})

А вот демоверсия full jsFiddle со всеми вещами, которые я хочу сделать: http://jsfiddle.net/xmLBG/1/

Ответы [ 5 ]

1 голос
/ 02 марта 2012

Если вы используете 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");
0 голосов
/ 07 марта 2012

Я предполагаю, что Tipsy использует какое-то прямое сопоставление с результатом, не используя live (в 1.6) или on в более новых версиях jQuery.
Так что, когда вы пытаетесь применить плагинпо ссылкам с классом tipsy2 он не может их найти (потому что вы добавляете его в DOM на более позднем этапе в своем коде).Самое простое решение этой проблемы - просто запустить функцию tipy на более позднем этапе, например, на 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/)

0 голосов
/ 02 марта 2012

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>');
});

Это будет хорошо работать

0 голосов
/ 02 марта 2012

Разве вы не можете сделать это вместо этого? Это то, что вы спрашиваете.

$(".tipsy1,.tipsy2").tipsy({live:true,fade:true});
$(".tipsy2").each(function() {
    //do your stuff
});
0 голосов
/ 02 марта 2012

Насколько я вижу, вам не нужно повторять нодлист. Похоже, что tipsy делает это за вас (см. jsfiddle , где в первом списке каждый элемент получает собственную подсказку (1,2,3).

...