JavaScript API简介:MutationObserver、IntersectionObserver 和 History API

现代 Web 应用程序需要响应能力、效率和动态交互性。原生 JavaScript API(例如 MutationObserver、IntersectionObserver 和 History API)使开发人员能够直接应对这些挑战,而无需外部库。让我们详细探索这些 API,了解它们的用例,并学习如何有效地利用它们的强大功能。

突变观察者

**概述:**

`MutationObserver` 接口监控 DOM 树的变化,取代现已弃用的 Mutation 事件。它可以检测节点的添加、删除或修改时间,使其成为动态应用程序的必备工具。

**主要特点:**

  • 监视 DOM 树的变化。
  • 检测对属性、子节点和文本内容的修改。
  • 异步操作,确保最小的性能影响。
  • **问:MutationObserver 如何工作?**

    使用回调函数创建一个 `MutationObserver` 实例,只要 DOM 中发生指定的更改就会触发该函数。

    **MutationObserver 中的选项**

  • 子树:观察目标节点及其所有后代。
  • childList:监视子节点的添加或删除。
  • 属性:跟踪目标节点属性的变化。
  • attributeFilter:将监控限制在指定的属性上。
  • attributeOldValue:捕获属性改变之前的先前值。
  • characterData:观察节点文本内容的变化。
  • characterDataOldValue:捕获修改前的文本内容的先前值。
  • **HTML 语法**

    Something

    **JS 语法**

    const target = document.querySelector('#something')
    
    const observer = new MutationObserver(function(mutations){
        mutations.forEach(function(mutation){
        console.log('Mutation detected:', mutation)
      })
    })
    
    const config = {attributes:true, childList:true, characterData:true, subtree:true}
    
    observer.observe(target,config)
    
    //observer.disconnect() - to stop observing

    **用例:**

  • 动态更新 UI 元素。
  • 实现 DOM 改变的自定义行为。
  • 监控第三方库的修改。
  • 交叉口观察者

    **概述:**

    `IntersectionObserver` 是一个接口,它异步观察目标元素相对于根容器或视口的可见性变化。它通常用于延迟加载、无限滚动和分析。

    **主要特点:**

  • 有效地跟踪元素可见性。
  • 减少对滚动事件监听器的依赖。
  • 提供对阈值的细粒度控制。
  • **问:交叉口观察器如何工作?**

    当以下任一情况发生时,Intersection Observer API 会触发回调:

  • 目标元素与设备的视口或指定的根元素相交。
  • 观察者第一次开始观察目标元素。
  • **交叉口观察器中的选项**

  • root:用于检查可见性的视口的元素。如果未指定,则默认为浏览器的视口。
  • rootMargin:根部周围的边距,指定为字符串(例如“10px 20px”)。扩大或缩小可观察区域。
  • 阈值:0 到 1 之间的值(或值数组),表示触发回调所需的可见性百分比。
  • **问:如何计算交点?**

    Intersection Observer API 使用矩形来计算交叉点面积:

  • 不规则形状的元素被视为适合完全包围它们的最小矩形。
  • 对于部分可见的元素,使用包含所有可见部分的最小矩形。无论元素形状或可见性如何,这都能确保测量的一致性。
  • 基本语法

    const observer = new IntersectionObserver((entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          console.log('Element is visible in the viewport.')
          // Optionally stop observing
          observer.unobserve(entry.target)
        }
      })
    })
    
    // Target elements to observe
    const targetElement = document.querySelector('.lazy-load')
    
    // Start observing
    observer.observe(targetElement)

    **用例:**

  • 延迟加载图像或视频。
  • 实现无限滚动。
  • 跟踪用户与特定元素的互动。
  • **高级功能:**

  • 多重阈值:使用阈值数组观察部分可见性。
  • 根边缘:扩展视口的边界以便于早期检测。
  • 历史 API

    **概述:**

    History API 使 Web 应用程序能够操纵浏览器的会话历史记录。它允许添加、替换或修改条目而无需重新加载页面,这是单页应用程序 (SPA) 的基础。

    **主要特点:**

  • 使用 pushState 和 replaceState 管理历史堆栈。
  • 使用 popstate 监听导航事件。
  • 更新浏览器的地址栏,无需重新加载整个页面。
  • **基本语法:**

    // Add a new entry to the history stack
    history.pushState({ page: 1 }, 'Title 1', '/page1')
    
    // Replace the current entry
    history.replaceState({ page: 2 }, 'Title 2', '/page2')
    
    // Handle back/forward navigation
    window.addEventListener('popstate', (event) => {
      console.log('Location: ' + document.location + ', State: ' + JSON.stringify(event.state))
    })

    使用案例:

  • 使用动态路由构建 SPA。
  • 使用浏览器导航管理应用程序状态。
  • 创建自定义导航体验。
  • 重要说明:
  • 确保旧版浏览器能够正确回退。
  • 与 URL 参数结合以获得更好的 SEO。
  • **组合这些 API**

    这些 API 可以协同工作以创建复杂的 Web 应用程序。例如:

  • 使用 MutationObserver 监控动态 DOM 变化。
  • 实现 IntersectionObserver 来延迟加载因 DOM 更改而添加的内容。
  • 利用历史 API 在应用程序内提供无缝导航。
  • **示例用例:**

    博客应用程序会在用户向下滚动时动态加载帖子(无限滚动)。它还会更新 URL 以反映当前帖子,而无需重新加载页面,从而确保更好的用户体验和改进的 SEO。

    const loadMorePosts = () => {
      // Simulate loading posts
      const post = document.createElement('div')
      post.textContent = 'New Post'
      document.body.appendChild(post)
    };
    
    const postObserver = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          loadMorePosts()
        }
      })
    })
    
    const monitorHistory = () => {
      document.querySelectorAll('.post').forEach(post => {
        post.addEventListener('click', () => {
          history.pushState({}, '', `/post/${post.id}`)
        })
      })
    }
    
    const target = document.querySelector('#loadTrigger')
    postObserver.observe(target)
    monitorHistory()

    结论

    `MutationObserver`、`IntersectionObserver` 和 History API 为动态和交互式 Web 应用程序提供了强大的原生解决方案。通过了解它们的功能并有效地集成它们,开发人员可以构建高性能且功能丰富的应用程序,而无需过度依赖外部库。