每次在jQuery中加载元素时如何调用.ready?

时间:2012-10-12 16:13:50

标签: javascript jquery dom domready

我希望每次初始化Dom元素时都会触发一个事件,如下所示:

HTML

<div id="container">
    <div id="data">data!</div>
</div>

<div id="clickme">Click me!</div>​

的Javascript

$(function() {
    var i = 0;
    $('#clickme').click(function() {
        $('#container').html('<div id="data">data '+i+'</div>');
        i++;
    });

    // this event gets called only the first time #data element is ready
    // I want it to be called each time #data comes into being
    $('#data').ready(function() {
        alert('element data ready!');
    });
});

我试过了:

// doesn't work
$('#data').live('ready', function() {
    alert('element data ready (live)');
});

编辑:我有兴趣为ajax插入的元素执行此操作。例如:

$.post('/myaction/', {
     param: 'value'
  },
  function(data) {
      $('#someContainer').replaceWith(data);
  });

  // this function operates on elements returned by the ajax call, so they are not available at this point.
  myFunction();

  // so I'd better call myFunction() when the ajax data is inserted
});

在这里摆弄:http://jsfiddle.net/nf8CP/

4 个答案:

答案 0 :(得分:2)

对于您的更新问题,只需将您的功能移至回调即可。

$.post('/myaction/', {
     param: 'value'
  },
  function(data) {
      $('#someContainer').replaceWith(data);

      myFunction(); // Call it right here.
  });

 // myFunction();  // Not here!!!

});

有DOM Mutation事件,但我相信它们已被弃用,并且没有完整的浏览器支持。

还有livequery插件,但实在是太过分了。

.ready()处理程序不处理单个元素的加载事件。仅适用于DOM加载的事件。这三个例子都有相同的行为:

  • $(document).ready(...
  • $('document').ready(...
  • $("#data").ready(...
  • $().ready(...

没有区别。传递给$的参数将被忽略。

正确的解决方案是在创建元素时调用所需的代码。

$(function() {
    var i = 0;
    $('#clickme').click(function() {
        $('#container').html('<div id="data">data '+i+'</div>');
        dataReady();
        i++;
    });

    function dataReady() {
        alert('element data ready!');
    }
});

另外,根据您的示例,更好且破坏性更小的解决方案是简单地修改#data中的文字,而不是使用.html()销毁该元素。

答案 1 :(得分:1)

ready(或更准确地说DOMContentLoaded)仅在页面完全解析后触发一次。没有干净的方法来做你想要的事情,所以你需要手动安装你的事件处理程序。 (有DOM突变事件,但是这些都是如此嘈杂,你的页面会吃掉它自己试图处理它们,除非你真的知道你在做什么,否则这通常是一个坏主意。)

但是,我怀疑你真正想要的是事件授权。您需要在#container而不是#data上安装事件,因为调用ready函数时,现有的#data节点将从DOM中删除!

例如:

$('#container').on('click', '#data', function() {
  alert('#data element was clicked!');
});

这样做是在#container上安装一个处理程序(永远不会改变),该处理程序使用选择器click侦听发起(或冒泡)子元素的#data事件。这意味着即使您不断更换#container的内容,也无需在其内容上安装新的事件处理程序。

答案 2 :(得分:1)

您可以使用DOMNodeInserted

$(document).on('DOMNodeInserted', function() {
    alert('element data ready (live)');
});

只要将节点添加到DOM,就会触发它。

您还可以过滤触发此事件的节点,如下所示:

$(document).on('DOMNodeInserted', '#data', function() {
    ...
}

现在只有在添加ID为data的节点时才会触发。

答案 3 :(得分:1)

为什么不把你的.ready放在你的按钮点击内,这样你每次点击它时都可以看到它是否准备就绪:

$(function() {
    var i = 0;
    $('#clickme').click(function() {
        $('#container').html('<div id="data">data ' + i + '</div>');
        i++;
        $('#data').ready(function() {
            alert('element data ready!');
        });
    });
});​