首页 > 文章列表 > 使用纯JavaScript加载和动画化内容的方法

使用纯JavaScript加载和动画化内容的方法

加载 动画化 纯JavaScript
219 2023-09-04

我们在 Tuts+ 上流行的教程之一教读者如何使用 jQuery 加载内容并制作动画。

虽然使用 jQuery 允许我们编写更少的代码来实现所需的功能,但它也会增加页面加载时间并引入不必要的依赖项。

除非您正在处理的网站已经加载 jQuery,否则您可能需要考虑使用纯 JavaScript 加载内容并为其设置动画。最初的教程是很久以前写的,这段时间浏览器支持以及原生 JavaScript 能力已经有了很大的提高。

网页标记和样式

由于我们试图复制原始教程的效果,因此为我们的网页使用相同的标记和样式是有意义的。以下是我们在原始教程中使用的标记以供参考:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Home</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <nav>
      <ul>
        <li><a href="index.html">Home</a></li>
        <li><a href="about.html">About Us</a></li>
        <li><a href="team.html">Our Team</a></li>
        <li><a href="contact.html">Contact</a></li>
      </ul>
    </nav>
    <span class="loader"></span>
    <section id="content">
        <img src="dog.svg" />
        <h1>Embrace Pawsitivity, Transform Lives!</h1>
        <p>Welcome to Pawsitive Care Foundation, a dedicated organization working towards the well-being and protection of animals.</p>
        <p>Our animal Welfare NGO provides a range of services to support animal welfare:</p>
        <ol>
            <li>Rescue and rehabilitation of abused and abandoned animals</li>
            <li>Adoption programs to find loving homes for animals in need</li>
            <li>Education and awareness campaigns to promote responsible pet ownership</li>
            <li>Lobbying and advocacy for stronger animal protection laws</li>
            <li>Collaboration with local communities to implement spay/neuter programs</li>
        </ol>
    </section>
    <script src="load-content.js"></script>
</body>
</html>

唯一的区别是我们已经摆脱了 jQuery,并且我们的 load-content.js 文件现在将使用普通 JS 而不是 jQuery。

这是我们将用于加载程序的 CSS 以及内容:

.loader {
   background: white;
   width: 30px;
   height: 30px;
   display: inline-block;
   position: absolute;
   right: 2rem;
   top: 1.2rem;
   animation: 0.5s infinite spin;
   border-radius: 50%;
   border-top: 5px solid black;
   border-bottom: 5px solid gray;
}
@keyframes spin {
   0% {
     transform: rotate(0deg);
   }
   100% {
      transform: rotate(360deg);
   }
}
 
section#content {
   width: 100% !important;
}

为了避免重复,如果有任何内容看起来令人困惑,我建议您可以仔细阅读原始帖子,了解为什么我使用这个特定的标记结构和 CSS 规则。

下图显示了应用所有 CSS 后我们的网页的外观:

使用纯JavaScript加载和动画化内容的方法

在开始操作 DOM 之前,确保 HTML 文档已被完全解析非常重要。我们通过监听 DOMContentLoaded 事件来做到这一点。我们将一个回调函数附加到该事件侦听器,该函数在 DOMContentLoaded 事件触发时立即执行。这是我们的初始代码:

document.addEventListener("DOMContentLoaded", () => {
  const loader = document.querySelector(".loader");
  const content = document.getElementById("content");
  const navLinks = document.querySelectorAll("nav li a");

  loader.style.display = "none";
});

此时,我们只需使用 querySelector()getElementById()querySelectorAll() 方法来选择所需的 DOM 元素。您可以阅读我们有关通过类、ID、标签名称或其他选择器获取元素的教程,以了解这些方法的工作原理。

最初,我们希望加载程序保持隐藏。我们只需将 display 属性的值设置为 none 即可实现此目的。

现在将以下代码放入回调函数中:

const handleClick = (event) => {
    event.preventDefault();
    
    const loadURL = `${event.target.getAttribute("href")}`;
    
    content.style.display = "none";
    loader.style.display = "block";
    
    loadContent(loadURL);
    
    window.location.hash = event.target.getAttribute("href").slice(0, -5);
};

navLinks.forEach((link) => {
    link.addEventListener("click", handleClick);
});

我们首先定义我们的点击处理程序。在 handleClick 内部,我们要做的第一件事是通过调用 event.preventDefault() 来阻止默认操作的发生。我们使用箭头函数来定义点击处理程序,因此我们必须使用 event.target 而不是 this 才能访问我们的链接元素。

我们获取导航链接的 href 属性的值,因为稍后我们必须将其传递给 loadContent() 函数。此时,我们要隐藏网页上当前可见的内容并开始显示加载程序。我们通过更改显示属性的值来做到这一点。

之后,我们循环遍历 navLinks 中存储的所有链接,并向它们添加单击事件侦听器。 handleClick 回调同时附加到每个事件侦听器。每次单击其中一个链接时都会调用此函数。

定义 loadContent() 方法

现在,我们需要定义 loadContent() 函数。它将接受我们的 URL 作为其唯一参数,然后使用 Fetch API 发出 AJAX 请求。

const loadContent = (url) => {
    content.innerHTML = "";
    fetch(url)
      .then((response) => {
        if (response.ok) {
          return response.text();
        }
      })
      .then((html) => {
        const tempElement = document.createElement("div");
        tempElement.innerHTML = html;
        const extractedContent = tempElement.querySelector("#content").innerHTML;
        content.innerHTML = extractedContent;
        content.style.display = "block";
        loader.style.display = "none";
      });
};

调用 fetch() 方法会返回一个 Promise 对象,一旦服务器响应标头,该对象就会解析为我们请求的 Response 。我们通过检查 response 对象的 ok 属性的值来检查请求是否成功。如果一切正常,我们使用 text() 方法以字符串形式返回网页 HTML。

如果这一切对您来说都是新的,您应该考虑阅读我们有关 Promise 基础知识的教程。

现在我们有了 HTML,我们再次调用 then(),将返回的 HTML 作为参数传递。此时,我们只想提取 section 元素中 id 为 content 的内容。为此,我们创建一个包含所有 HTML 的临时元素,然后在此元素上调用 querySelector() 方法来提取我们想要的 HTML。

最后,我们将内容部分的 display 属性设置为 block ,并将加载程序的 display 属性设置为 none

向内容添加动画

您可能已经注意到,我们只是将 #content 元素的 display 属性的值更改为 blocknone。不涉及动画。

您现在将学习如何为内容制作动画。最简单的方法是使用 CSS。将以下行添加到您的 style.css 文件中:

 #content.fade-in {
   overflow: hidden;
   animation: fadeInAnimation 0.4s forwards;
 }

 @keyframes fadeInAnimation {
   from {
     opacity: 0;
     max-height: 0;
   }
   to {
     opacity: 1;
     max-height: 100vh;
   }
 }

我们简单地定义了一个关键帧动画,它对 opacitymax-height 属性进行动画处理,以提供与我们原始教程相同的效果。这里要注意的重要一点是 forwards 关键字,这将使我们的 #content 元素保留最终的计算值。

现在,您只需使用以下行将 fade-in 类添加到 #content 元素:

content.classList.add("fade-in");

只需将其添加到将内容 display 属性设置为 block 的行下方即可。

同样,您需要使用以下行从内容元素中删除 fade-in 类:

content.classList.remove("fade-in");

最终想法

在本教程中,我们学习了如何使用一点 CSS 和普通 JavaScript 加载网页内容并为其制作动画。这比使用 jQuery 有点棘手。但是,您可以消除下载整个库的开销。

现在,发挥创意,按照您想要的方式为页面内容添加动画效果。