jQuery live与ready或load事件的结合使用

8

我正在使用jQuery Tools提示插件,它通过$('selector').tooltip()进行初始化。我想在任何当前或未来的.tooltipper元素上调用它。我认为以下代码可以实现:

$('.tooltipper').live('ready', function(){
  $(this).tooltip()
}

但是它并没有成功——ready事件没有触发。load也一样。我读过livequery可以产生我想要的结果,但肯定有一种方法可以使用jQuery的.live()来完成,因为文档说它适用于所有jQuery事件,其中我相信ready是其中之一。


如果元素在准备好时存在,为什么要使用.live()?我认为最好尝试将其绑定到可能创建新的selector的事件上。这不是直接的答案,但在ready上使用.live()似乎有点像散弹枪式的方法。只是我的两分钱。 - HurnsMobile
我这样想。某些元素应始终表现出特定的行为。例如,带有href属性的链接在单击时应始终带您到一个URL。大多数带有 title属性的元素应在鼠标悬停时将参数显示为工具提示。对于像自定义工具提示这样的高级行为,启用此类功能对我来说是有意义的。 - Steven
1
我最终使用了$('.tooltipper').livequery(function(){$(this).tooltip()}),这对我来说是最语义化的解决方案(相比于下一个最佳解决方案,即将回调添加到创建工具提示元素的函数中),因为工具提示行为与元素相关联——它与创建过程无关。 - Steven
Steven - 在所有方面都提出了有价值的观点。对于一个全面信息化的问题和答案,我给予+1的支持。 - HurnsMobile
3个回答

12

引自 jQ API (http://api.jquery.com/live/):

在 jQuery 1.3.x 中,除了自定义事件之外,只有以下 JavaScript 事件可以使用 .live() 进行绑定:click、dblclick、keydown、keypress、keyup、mousedown、mousemove、mouseout、mouseover 和 mouseup。

自从 jQuery 1.4 开始,.live() 方法支持所有 JavaScript 事件以及自定义事件。

自从 jQuery 1.4.1 开始,即使是 focus 和 blur 也能与 live 一起使用(映射到更合适的冒泡事件 focusin 和 focusout)。

自从 jQuery 1.4.1 开始,hover 事件也可以被指定(映射到 "mouseenter mouseleave")。

.live() 看起来不支持 ready 事件。


5

在HurnsMobile的优秀回答中,我想补充一点; 查看bindReady(),这是jQuery在每次调用$(some_function)$(document).ready(some_function)时内部调用绑定文档加载事件的方法,我们可以看到为什么不能绑定"ready"事件:

bindReady: function() {
        if ( readyBound ) {
            return;
        }

        readyBound = true;

        // Catch cases where $(document).ready() is called after the
        // browser event has already occurred.
        if ( document.readyState === "complete" ) {
            return jQuery.ready();
        }

        // Mozilla, Opera and webkit nightlies currently support this event
        if ( document.addEventListener ) {
            // Use the handy event callback
            document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

            // A fallback to window.onload, that will always work
            window.addEventListener( "load", jQuery.ready, false );

        // If IE event model is used
        } else if ( document.attachEvent ) {
            // ensure firing before onload,
            // maybe late but safe also for iframes
            document.attachEvent("onreadystatechange", DOMContentLoaded);

            // A fallback to window.onload, that will always work
            window.attachEvent( "onload", jQuery.ready );

            // If IE and not a frame
            // continually check to see if the document is ready
            var toplevel = false;

            try {
                toplevel = window.frameElement == null;
            } catch(e) { //and silently drop any errors 
                    }
                    // If the document supports the scroll check and we're not in a frame:    
            if ( document.documentElement.doScroll && toplevel ) {
                doScrollCheck();
            }
        }
    }

总结一下,$(some_function) 调用一个绑定到以下事件的函数:
  • DOMContentLoaded
  • onreadystatechange (DOMContentLoaded)
  • window.load / onload
你最好绑定那些可能会创建新的 .tooltipper 元素的操作,而不是尝试监听 ready 事件(这只会发生一次)。

太棒了!感谢Sean提供的额外细节! - HurnsMobile
感谢您深思熟虑的回答。我以前也像您一样将jQuery工具调用绑定到“构造函数”中,但这条探究线的想法是尝试完全避免这样做。我的理由是,提示工具的提示性与提示工具的构建无关,而是内在于提示工具本身。 - Steven

1
HurnsMobile 是正确的。JQuery live 不支持 ready 事件。
这就是我创建一个插件来结合两者的原因。您只需注册一次回调函数,然后需要为您手动添加的内容调用插件一次即可。
$.liveReady('.tooltipper', function(){
  this.tooltip()
});

然后在创建新内容时:

element.html(somehtml);
element.liveReady();

或者

$('<div class="tooltipper">...').appendTo($('body')).liveReady();

这里提供一个演示:http://cdn.bitbucket.org/larscorneliussen/jquery.liveready/downloads/demo.html 请查看介绍文章:http://startbigthinksmall.wordpress.com/2011/04/20/announcing-jquery-live-ready-1-0-release/
还可以看一下http://docs.jquery.com/Plugins/livequery,它监听dom的变化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接