随着 Web 应用程序的发展,对于更快速、更可靠和更具可维护性的开发效率的要求也会随之增加。在前端开发中一个通用的问题是如何避免不必要的网络请求并实现数据的异步展示。在这方面,Custom Elements 可作为一种解决方案。
Custom Elements 是什么?
Custom Elements 是 Web Components 的一个重要部分,它可以帮助我们创建自定义 HTML 元素。与默认的 HTML 标签不同,Custom Elements 可以被定义、绑定行为和样式,称为“自定义元素”。
在 Custom Elements 中,自定义元素被封装在自定义的 JavaScript 类中。这些类继承自 Web API 中的 HTMLElement 类,可以用一些钩子函数和方法自定义元素的行为。如 today 不仅使用了元素的自定义属性,还实现了一个连接外部 API 的模块化异步方法来获取远程数据。
实现异步数据加载并展示
下面将详细介绍如何在 Custom Elements 中实现异步数据加载并展示。
创建 Custom Elements
首先,我们需要定义一个自定义元素,并设定其原型链继承 HTMLElement 即可:
class AsyncData extends HTMLElement { constructor() { super(); } } customElements.define('async-data', AsyncData);
不管你在 HTML 中定义了多少次此标签,都只有一个类实现, 就像一个普通 JavaScript 类一样。
使用 Custom Elements 属性
创建 Custom Elements 类之后,我们可以为其添加属性来控制其展示。属性是 Custom Elements 构造函数中定义的“追加者函数”或“访问器函数”。
// javascriptcn.com 代码示例 constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); const wrapper = document.createElement('div'); wrapper.setAttribute('class', 'wrapper'); wrapper.innerHTML = ` <style> .wrapper { display: flex; align-items: center; justify-content: center; height: 150px; border-radius: 10px; box-shadow: 0 5px 10px rgba(0, 0, 0, 0.5); background-color: lightgray; } .content { text-align: center; font-size: 3rem; } </style> <div class="content"> <slot>Loading...</slot> </div> `; shadow.appendChild(wrapper); this.url = this.getAttribute('url'); this.selector = this.getAttribute('selector'); }
在上面的代码中,我们创建了一个具有 .wrapper
和 .content
样式的 div 容器,用于展示异步加载数据。同时,我们还将 url
和 selector
属性存储到了实例对象上。
其中,url 属性记录了异步请求的 URL,而 selector 属性则存放筛选异步请求获取到的数据的 CSS 选择器。
创建异步方法
接下来,我们需要创建一个异步方法,用于连接外部 API 并获取异步数据。
// javascriptcn.com 代码示例 async fetchData() { const resp = await fetch(this.url); const text = await resp.text(); const parser = new DOMParser(); const doc = parser.parseFromString(text, 'text/html'); return doc.querySelectorAll(this.selector); }
在上面的代码中,我们使用了 fetch
API 连接了 URL,并返回了一个 promises 对象。我们取得的文本数据是以 promises 对象的形式出现的。
我们还创建了一个 fetchData
方法,该方法连接外部 API 并获取异步数据。在这个方法中,我们首先使用了DOM解析器将文本数据解析为 HTML。接下来,我们筛选出符合条件的数据并返回其列表。
展示异步数据
接下来,我们需要通过调用 fetchData
方法来异步获取数据,并将其渲染到 Custom Elements 的容器中。
// javascriptcn.com 代码示例 connectedCallback() { this.fetchData().then(res => { if (res.length === 0) { this.querySelector('.content').textContent = 'No result'; } else { let text = ''; res.forEach(node => { text = `${text}<div>${node.textContent}</div>`; }); this.querySelector('.content').innerHTML = text; } }).catch(e => { this.querySelector('.content').textContent = e.message; }); }
在上面的代码中,我们使用了 Custom Elements 的钩子函数 connectedCallback
,以便在元素被连接到文档流之后,异步请求数据并渲染到 DOM 中。
如果没有获取到数据,我们将通过 textContent
属性将提示信息显示在 .content
中。如果有数据,我们则将其通过 innerHtml
属性渲染到 .content
容器中。
完整示例代码
在上述几个步骤完成后,我们已经能够异步展示数据了。下面是全部的源代码:
// javascriptcn.com 代码示例 class AsyncData extends HTMLElement { constructor() { super(); const shadow = this.attachShadow({ mode: 'open' }); const wrapper = document.createElement('div'); wrapper.setAttribute('class', 'wrapper'); wrapper.innerHTML = ` <style> .wrapper { display: flex; align-items: center; justify-content: center; height: 150px; border-radius: 10px; box-shadow: 0 5px 10px rgba(0, 0, 0, 0.5); background-color: lightgray; } .content { text-align: center; font-size: 3rem; } </style> <div class="content"> <slot>Loading...</slot> </div> `; shadow.appendChild(wrapper); this.url = this.getAttribute('url'); this.selector = this.getAttribute('selector'); } async fetchData() { const resp = await fetch(this.url); const text = await resp.text(); const parser = new DOMParser(); const doc = parser.parseFromString(text, 'text/html'); return doc.querySelectorAll(this.selector); } connectedCallback() { this.fetchData().then(res => { if (res.length === 0) { this.querySelector('.content').textContent = 'No result'; } else { let text = ''; res.forEach(node => { text = `${text}<div>${node.textContent}</div>`; }); this.querySelector('.content').innerHTML = text; } }).catch(e => { this.querySelector('.content').textContent = e.message; }); } } customElements.define('async-data', AsyncData);
总结
通过上述方法,我们可以很容易地实现异步加载数据并在 Custom Elements 中展示。使用 Custom Elements 带来的优点是我们能够自定义一个新的 HTML 标签,使得我们的代码更易于维护和实现。同时,Custom Elements 对异步请求和响应进行了高度封装,可以使得我们的代码更加优雅和高效。
想要了解更多Custom Elements的相关信息,可以参见 MDN Web Docs 上的相关文档,或者你也可以查看本篇文章涉及的全部示例代码。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6543a2907d4982a6ebd6f0e5