关于 JavaScript 你需要了解的一件事

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

自从我发布了文章 动态页面/替换内容 以来,我收到了很多邮件,这些邮件来自尝试将其与其他一些 JavaScript 代码一起使用并遇到问题的人。大多数情况下,这是一种某种形式的灯箱效果。他们的其中一个页面上有一堆缩略图,当他们在其中加载该页面时,灯箱效果不起作用。

问题在于,当缩略图加载到页面上时(通过 Ajax,即 jQuery 的 .load() 函数),它们没有任何事件绑定到它们。

/* Your lightbox plugin */
$("photos a").ceebox();  

/* Basics of Ajax */
$("nav a").click(function(e) {
    e.preventDefault();
    $("#main-content").load(this.href);  /* Thumbnails loaded from here */
});

灯箱插件(可能)的工作方式是,当页面加载时,它会将点击事件绑定到您在该选择器(缩略图)中传递的元素,并且这些点击事件会执行灯箱操作。由于新加载的缩略图没有点击事件,因此灯箱操作不起作用。

一种解决方法是在内容加载后,在 load 函数的回调函数中调用灯箱插件

$("photos a").ceebox();  

$("nav a").click(function(e) {
    e.preventDefault();
    $("#main-content").load(this.href, function() {

              /* Callback function */
              $("photos a").ceebox();  /* Call this again */

    });
});

有点重复,但这可以解决问题。

使用委托的更好方法

虽然这是“JavaScript 的工作方式”,但它确实让人很头疼。由于 jQuery 是一个旨在缓解此类问题的库,当然它有更好的方法。这种方法是 .delegate() 函数,它不是将事件绑定到各个元素,而是将事件绑定到 DOM 树中较高层次的元素,该元素不太可能通过 Ajax 替换,并且会监视这些点击事件。

这依赖于称为事件冒泡的东西,这是 JavaScript 中一个巧妙且重要的概念(实际上:DOM 模型)。如果您点击缩略图,它将触发该元素上的点击事件,然后触发其父元素上的点击事件,以及其父元素的父元素上的点击事件,一直到根元素。因此,我们可以从上层元素监视更深层元素上的点击事件。

不幸的是,在我们的灯箱示例中,您必须更改插件本身才能使其使用委托而不是直接绑定到元素。绝对可以做到,但比较棘手,因为您可能不像处理自己的代码那样熟悉该插件的代码。

听听 Remy Sharp 的讲解

在撰写本文时,Remy Sharp 发布了一个关于此确切主题的视频屏幕录制。他比我更擅长解释它,所以请 观看该视频