如何在元素插入时高效执行JavaScript函数?

3

初始加载页面时,我使用jQuery搜索以下内容:

<label for="first_name">name</label>
<input type="text" name="first_name" />

并将HTML变得更加漂亮。

问题在于当我尝试动态地将这些元素插入DOM时。由于没有绑定到新创建的元素,我不确定运行“调整”函数的正确方式是什么。我不想简单地对其进行黑客攻击,并且手动调用adjust_html1()adjust_html2()等。

运行代码以在HTML被插入后最有组织和有效的方法是什么?

(附注:如果有一种方法只在新HTML上运行它,那将是更酷的

编辑:添加了一个“for”循环

编辑2:这是我的示例jQuery代码,在文档准备就绪时运行:

$('label').each(function() {
  /* do stuff */
});

我用jQuery搜索这样的东西...... 这是一个名称错误,以下几行中没有jQuery。在问题的背景下,这意味着什么? - Jared Farrish
@JaredFarrish - 我想他的意思是“我使用jQuery 来搜索 这样的东西”。 - Justin ᚅᚔᚈᚄᚒᚔ
@Justin - 那完全有可能... - Jared Farrish
@JaredFarrish 我的意思是我用 jQuery 搜索那些元素。已编辑。 - Jon Derring
@Jon - 最好提供相关的底层代码。:) - Jared Farrish
@JaredFarrish 不错的主意,因为我有一个问题要问其中的一个答案 :) - Jon Derring
4个回答

2
你可以查看livequery插件
$('[name="first_name"]').livequery(function() {
    alert('A node with name=first_name was injected into the DOM');
    adjust(this);
});

1

按照以下方式创建您的HTML:

var elem = $('<p></p>').text('hello').appendTo(document.body);
adjust_html(elem);

1

使用live()绑定方法。

为所有与当前选择器匹配的元素附加事件处理程序,现在和将来。


注意:这允许将事件处理程序绑定到新元素。如果您希望在插入时运行操作,最好在可能的情况下在插入之前运行该代码,以便渲染引擎不必重新流动。 - Jon Adams
@JaredFarrish:是的,在某些情况下,delegate()可以更快,具体取决于选择器、DOM树、事件冒泡/传播需求和其他一些高级事项。但是,指出该方法也是一个好主意。 - Jon Adams
@Mufasa 那我应该这样做吗? $('label').live('load', function() {}); - Jon Derring
2
这并不是问题所要求的。.live() 不会通知它们新元素何时被添加。此外,.load() 事件与 .live() 不兼容。这个问题不是关于新对象的事件处理程序,而是关于知道何时添加了新对象以便可以进行样式/改进。 - jfriend00
@JonDerring:不,不要绑定到“load”处理程序。这是用于绑定“click”处理程序等的。是否这是正确的解决方案取决于您在函数中正在做什么。您是添加事件处理程序(如果是,则是),还是操作CSS、数据等(如果是,请参见我关于在插入时执行此操作的其他评论,或者@mre666的答案)?更多的代码将有助于提供上下文并帮助我们更具体地回答您。 - Jon Adams

0

好的,也许我没有正确解释我的意图。目的是基本上能够在新插入的html上运行一组函数 - 高效地,而不必手动调用它们。

现在,我将采用我下面写的代码。最初,您的页面上有模板,并且您为某些选择器(存在于模板中)绑定功能到所有模板。因此,当您将模板插入页面时,这些选择器尝试在模板内匹配,并运行绑定的函数。

下面的代码既不高效,也不经过优化或彻底测试。所以,我不会把它作为最终答案接受。这只是一个示例解决方案,而且有点破解。但它有效。我相信backbone.js或一些插件可以做得更好,所以我会等JS专家展示正确的方法。

顺便提一下:我意识到有两个缺点:a)设置HTML的方式必须通过模板对象完成,而不是自然的jQuery方式,b)模板被插入到DOM中,然后才开始运行函数。我的第一个版本确实在模板被插入之前就可以工作,但是一些函数(如.replaceWith())在字符串上与在DOM节点上的效果并不完全相同。好的一面是,代码很小,正好符合我的要求。

<html>
<body>
<head>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script type="text/javascript">

        window.template = {
            queue: {},
            set: function(container, content) {

                /* first insert content */
                container.html(content);

                /* now run a list of functions in the queue */
                $.each(this.queue, function(s, fs) {
                    var el = $(s, container);
                    for (var i = 0, len = fs.length; i < len; ++i)
                        el.each(fs[i]);
                });

            },
            bind: function(selector, func) {
                if (typeof this.queue[selector] === 'undefined')
                    this.queue[selector] = [];
                /* push function to queue for that specific selector */
                this.queue[selector].push(func);
            }
        };

        $(function() {

            var templateContents = $('#my-template').html();

            /* for each <label>, replace it with another <input> */
            template.bind('label[for="first_name"]', function() {
                $(this).replaceWith('<input type="text" name="last_name" value="last name" />');
            });

            $('a').click(function(e) {

                e.preventDefault();
                $('body').append('<div class="container"></div>');

                /* get the div that we just appended to body */
                var newDiv = $('.container').last();

                /* set that newDiv's html to templateContents, and run binded functions */
                template.set(newDiv, templateContents);

            });

        });

    </script>
</head>
<body>
    <script id="my-template" type="text/template">
        <label for="first_name">name</label>
        <input type="text" name="first_name" />
    </script>
    <a href="#">add dynamically</a>
</body>
</html>

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