【问题标题】:.on() not working for dynamically generated content.on() 不适用于动态生成的内容
【发布时间】:2012-08-04 23:31:01
【问题描述】:

我会尽可能清楚地解释我正在尝试做的事情,并希望人们能够理解这个问题。

$(document).ready(function() {
  $('body').on('click', '.mainNav', function() {
    var href = $(this).attr('href');
    $('body').load(href);
   });
});

这是给我带来麻烦的代码。基本上,它应该做的是从 div 中获取 'href' 属性,然后加载该属性以替换 body 标记的当前内容。

这是第一次工作,但是当通过 .load() 生成新内容时,div 停止响应。我对 JS 很陌生,所以如果答案很明显,我提前道歉。我一直在尝试自己寻找解决方案,但我发现的一切都告诉我 .on() 应该适用于动态生成的内容。

编辑:无法在小提琴中模拟问题,所以我发布了一个包含整个索引页面的 pastebin,希望它能澄清问题。

http://pastebin.com/xT5syd9j

编辑: 它使用 adeneo 的解决方案。非常感谢每个人的意见,并为没有从一开始就发布整个内容而道歉。我猜它会为每个人节省一些时间。

【问题讨论】:

  • .load 基于 Ajax,这意味着 href 只能是基于与脚本相同域的 URL。这称为同源策略。 href 可能是 http://google.com。这会破坏脚本。
  • 如果您在页面it should just work上没有收到错误。
  • @PeeHaa 您使用的是html() 方法,而不是load() 方法。这是不同的,所以不是证明案例。
  • @CSED: 你有<script> 标签来在<body> 中加载外部JS吗?最具体地说,您是否以这种方式加载 jQuery 本身?如果是这样,将 jQuery 移到 <head> 中,问题应该会得到解决。
  • 链接无效,它是一个带有 href 属性的水力压裂 div!

标签: javascript jquery dom event-handling dynamically-generated


【解决方案1】:

这里的问题可能是您调用$('body').load(href) 时真正加载的内容。如果你加载整个页面的HTML(包括<html><body>标签),那么你可能会遇到问题。您的浏览器通过使用不正确的 HTML(在您的情况下类似于 <html><body><html><body>...</body></html></body></html>)来处理此类问题 - 这可能会产生意想不到的结果。

更好的办法是:

  1. 正确组织 HTML(见下文)
  2. 仅加载上面生成的 HTML 的一部分,当您使用 $(...).load() 加载它时。

广告 1。确保您在 <body> 标签下方有一些元素,它有自己的 ID 并包含将位于 <body> 标签中的所有内容。它可能看起来像这样:

<html>
...
<body>
    <div id="main_div">
    <!-- all elements here -->
    </div>
</body>
</html>

广告 2。加载此类内容要容易得多,因为您可以附加一个选择器到传递给 .load() 的 URL(参见 jQuery .load() docs page 上的“加载页面片段”):

$('body').load(href + ' #main_div');

这样您将检索整个页面,但只获取 ID 为“#main_div”的元素并用它替换整个&lt;body&gt; 内容。

这种方式附加到主体的事件(即使是这些委托)应该仍然可以正常工作。

【讨论】:

  • 无需在body中添加其他元素。
  • @Purmou:你是对的,但是如果它应该像那样工作,那么以这种方式组织代码是件好事。按 ID 选择元素比使用例如快得多。 body &gt; *您提出的选择器。如果可以的话,您应该坚持仅通过 ID 选择元素(除非不合理)。
  • @Tadeck:我尝试加载的页面不包含 html/head/body 标签。结构与您指出的完全一样,一个包含我想要替换的所有内容的 div,所以当我替换 body 的内容时,我替换了一个大 div。我认为这就是您试图指出的可能问题。
  • @CSED:好的,你是说浏览器从服务器拉取的页面已经被裁剪为只有那个元素。 &lt;script&gt; 标签呢?它包含任何内容吗?没有响应的元素怎么办:他们有自定义的onclick(等)属性吗?还有一件事:您确定您使用的是.on() 而不是.one()?因为它会澄清很多;)
  • @Tadeck:没有脚本标签,但是 adeneo 的解决方案有效。问题是我对 href 属性的愚蠢使用。非常感谢所有的输入。
【解决方案2】:

不太确定这是什么问题,但我猜它与加载到与处理程序所附加的相同元素有关,所以试试:

$(document).ready(function() {
    $(document).on('click', '.mainNav', function(e) {
        e.preventDefault();
        console.log('I just clicked : '+e.target.href);
        $('body').load(e.target.href);
    });
});

此外,您当然知道这将替换您页面上的所有内容,除非在加载的内容中存在具有相同类的新元素,否则不会发生任何事情。我建议也使用容器将内容加载到其中。当然,链接必须指向您服务器上的实际文件。

还要确保您加载的文件没有另一组 &lt;head&gt;&lt;body&gt; 等标签,因为这会让您搞砸,仅限 HTML 内容!

编辑:

如果 .mainNav&lt;a href="link_you_are_trying_to_load"&gt;&lt;/a&gt; 类型的元素,您还必须阻止默认操作,请参阅更新的代码。

新编辑:

您遇到的问题非常明显,您使用的元素如下:

<div class="mainNav" href="test.php" id="active">

div 元素没有属性 href,因此 JS 不会获取该值,因为它不是 &lt;a&gt; 元素以外的任何东西的有效属性

您可以将您的元素更改为 &lt;a&gt; 元素或将 href 属性更改为:

<div class="mainNav" data-href="test.php" id="active">

然后做:

var href = $(this).data('href');

至少那将是有效的 HTML!

此外,您似乎有一个类似“容器”的元素,称为 #site,所以您为什么不这样做:

$('#site').load(href); //using the data-href as above

【讨论】:

  • “我猜它与加载到与处理程序附加到的相同元素有关”-> 应该没关系
  • @ErikE:我同意 PeeHaa 的观点。为什么这很重要?重要的是文档说元素的 content 被替换,而不是元素本身。我实际上在这个页面上尝试了一个变体,并且 JS 控制台给我的错误提示 jQuery 在第一次 .load 调用之后被“卸​​载”。
  • 应该和它没有任何关系,但是奇怪的事情发生了,那几行代码并没有太多要调试的东西,要么是href错误,要么是负载发生了什么事情() 函数。
  • 这不起作用。 div 现在根本没有响应点击。 href是有效的,检查它。它指向的文件没有头部或身体标签。它从 body 之后的第一个 div 开始。我会尝试在小提琴中重新制作整个东西,因为我觉得这可能是我解释得很糟糕的情况。请给我几分钟时间,感谢您的快速回复。
  • @CSED 。我刚刚在我的答案中添加了一个 console.log,尝试使用它并检查浏览器控制台以查看单击元素时发生的情况以及返回的 href。纯 JS href 通常会包含域名,而 jQuery 通常会获取 HTML 等中给出的 href,但至少这会告诉您链接确实有效。
【解决方案3】:

试试这个:

$(document).ready(function(){
    $('body').on('click', '.mainNav', function() {
        var href = $(this).attr('href');
        $('body').load(href + " body > *");
    });
});

我们在这里所做的只是加载页面上 body 元素的内容 (href)。无需向该页面添加更多元素。只需像 Tradeck 提到的那样选择正文的内容。

问题很明显,如果href 处的页面是一个完整的 HTML 页面,那么您将加载一个 DOCTYPE、第二个 html 标签、第二个 headbody 标签等。

【讨论】:

  • 这正是我提出的,除了没有具有单独 ID 的元素。不过,它应该可以工作。
  • @Tadeck:是的,我的错——我在编写自己的答案时没有加载新答案。 :P 虽然我们在这里有非常不同的选择,所以我认为我们很好。 :)
  • 我对此没有意见。我只是说它应该和我自己的答案一样有效;)您的答案不需要更改页面 HTML,我提出了这样的更改并且工作得更快。无论如何,不​​要删除你自己的,它会增加一些价值。
  • @Purmou:不知道这个,谢谢。但这并不重要,因为通过href加载的页面不包含body标签,只有原始页面也包含的div,所以body的内容正在使用href链接的完整页面替换,不是身体。不过还是谢谢。
猜你喜欢
  • 2014-06-25
  • 1970-01-01
  • 1970-01-01
  • 2012-08-14
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
  • 1970-01-01
相关资源
最近更新 更多