将jQuery插件应用于页面上当前不存在的元素

时间:2013-03-20 13:12:28

标签: jquery

我构建了这个非常令人兴奋的jQuery插件,它将元素变为蓝色。 http://jsfiddle.net/LpCav/

我希望将它应用于当前不在页面上的元素。

我知道一个选项是在我将新元素添加到页面后立即应用它。另一种选择是克隆其中一个现有元素并将其添加到页面而不是创建新元素。我不希望做这些选择。

相反,我可以使用on()将其应用于<li>内的任何当前或未来的<ul id="myNewList">元素吗?

如果没有,我可以修改插件,以便它执行此行为吗?

由于

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
        <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /> 
        <title>Future</title>  
        <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> 
        <script type="text/javascript">
            (function( $ ){
                $.fn.makeBlue = function() {  
                    return this.each(function() {
                        $(this).css('color','blue');
                    });
                };
            })( jQuery );

            $(function(){
                $('.myElement').makeBlue();
                $('#add').click(function(){
                    $('#myNewList').html('<li class="myElement">hello</li>')
                });
            });
        </script>
    </head>

    <body>
        <button id="add">Add</button>
        <ul id="myList">
            <li class="myElement">hello</li>
            <li class="myElement">hello</li>
        </ul>
        <ul id="myNewList">
        </ul>
    </body> 
</html> 

3 个答案:

答案 0 :(得分:0)

我通常使用$(document).ready(...)块来确保在每个页面加载时调用代码(甚至是ajax回调)。但是,您应该将插件实现为一个明确的插件 - 对同一元素的多次调用应该会产生相同的结果。

根据我对现有jquery插件和内置插件的经验,我观察到以下内容:

  • 如果同一个插件使用相同的配置多次调用相同的元素,则后续调用不会产生任何明显的差异

  • 如果在同一元素上使用不同的配置调用相同的插件,则效果是将配置与之前的调用合并。

也许如果你坚持使用你的插件这种行为,你将与现有的行为保持一致,并让他们在$(document).ready

的场景中工作

使用.on(...)可能会更好,因为它会在需要时更新相应的<ul>元素。但是,如果已有列表项,则插件应以幂等方式处理它们。


编辑:

关于代码中的幂等问题,它看起来像这样:

$.fn.makeBlue = function() {  
    return this.each(function() {
        var elem = $(this);
        if (elem.css('color') != 'blue') {
            // it is likely for the element not to have been processed yet.
            elem.css('color','blue');
        }
    });
};

更好的解决方案是将自定义css类添加到已处理的元素中 - 只是将它们标记为插件访问过的元素。然后,您可以使用$(this).hasClass('?')进行检查。这看起来像是:

$.fn.makeBlue = function() {  
    return this.each(function() {
        var elem = $(this);
        if (!elem.hasClass('makeBlueCalled')) {
            elem.css('color','blue');
            elem.addClass('makeBlueCalled');
        }
    });
};

在你的插件中,如果唯一的目的是为文本着色,我最好使用css定义

ul.myList > li.myElement.makeBlueCalled { color: blue !important; }

并删除elem.css('color','blue');行。

答案 1 :(得分:0)

有DOM2“突变事件”来捕获对DOM树的更改,但它们没有得到很好的支持,实际上已经被W3C弃用了。有新的“变异观察者”事件,但这些事件都在DOM4中,也没有完全支持。有关这些内容的详情,请参阅this question

在任何情况下(没有双关语)事实是JS是一种单线程语言,除非把它放在那里,否则页面上不会出现任何元素,所以它通常是微不足道的在插入时进行必要的更改。

否则,这个特定示例的正确答案是将其放在CSS样式表中:

.myElement {
    color: blue;
}

如果你真的在做一些比应用样式更复杂的事情,那么唯一可移植的选择就是在知道元素存在后调用插件。

答案 2 :(得分:0)

由于您放弃了最简单的(可能是最常见的解决方案),因此您可以捕获一些“DOM已更改”事件并绑定到该事件。从我发现的,有一些事件,但支持得很差..长话短说:这是一个图书馆,将为您提供所需的:

https://github.com/joelpurra/jquery-mutation-summary