在现代 Web 应用中,骨架屏(Skeleton Screen)已经成为了一种常见的 UI 设计模式。骨架屏可以在页面加载时快速展示占位符,使用户感知到页面正在加载中,从而提高用户体验。在本文中,我们将介绍如何使用 Custom Elements 技术构建骨架屏,并提供详细的代码示例和指导意义。
Custom Elements 简介
Custom Elements 是 Web Components 标准的一部分,它允许开发者自定义 HTML 元素并对其进行扩展。通过 Custom Elements,我们可以创建具有自定义行为和样式的 HTML 元素,并将其封装为独立的组件,方便在应用程序中复用和管理。
Custom Elements 由两部分组成:元素定义和元素实例。元素定义定义了一个新的 HTML 元素,包括元素的标签名、属性和方法等;元素实例则是元素定义的一个实例,可以通过 JavaScript 代码进行创建、修改和销毁。
构建骨架屏的思路
在使用 Custom Elements 构建骨架屏时,我们的思路是利用元素定义来定义一个自定义的骨架屏元素,并在元素实例化时动态生成骨架屏的 HTML 结构和样式。具体来说,我们可以按照以下步骤来实现:
- 定义骨架屏元素:我们可以使用
class关键字和extends关键字来定义一个新的 HTML 元素,并将其扩展为HTMLElement类。在元素定义中,我们可以定义元素的标签名、属性和方法等。
// www.javascriptcn.com code example
class SkeletonElement extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
// 元素实例化时的回调函数
}
}
customElements.define('skeleton-element', SkeletonElement);- 生成骨架屏结构:在元素实例化时,我们可以动态生成骨架屏的 HTML 结构,并将其添加到元素中。骨架屏的结构可以根据实际需求进行设计,例如可以使用占位符文本、占位符图片或者简单的颜色填充等方式来表示正在加载中的状态。
// www.javascriptcn.com code example
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
const title = document.createElement('h2');
title.classList.add('title');
title.innerText = 'Loading...';
const content = document.createElement('div');
content.classList.add('content');
for (let i = 0; i < 3; i++) {
const item = document.createElement('div');
item.classList.add('item');
const image = document.createElement('div');
image.classList.add('image');
const text = document.createElement('div');
text.classList.add('text');
item.appendChild(image);
item.appendChild(text);
content.appendChild(item);
}
wrapper.appendChild(title);
wrapper.appendChild(content);
shadow.appendChild(wrapper);
}- 添加骨架屏样式:最后,我们需要为骨架屏元素添加样式,以便使骨架屏的结构和外观符合设计要求。样式可以通过 CSS 文件、内联样式或者 JavaScript 代码等方式进行添加。
// www.javascriptcn.com code example
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
const style = document.createElement('style');
style.textContent = `
.wrapper {
width: 100%;
max-width: 600px;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
background: #fff;
border-radius: 5px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.title {
margin: 0 0 20px;
font-size: 24px;
font-weight: bold;
color: #333;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item {
width: calc(33.33% - 10px);
margin-bottom: 20px;
box-sizing: border-box;
border-radius: 5px;
overflow: hidden;
}
.image {
width: 100%;
height: 0;
padding-bottom: 75%;
background: #f5f5f5;
}
.text {
margin: 10px;
background: #f5f5f5;
height: 20px;
}
`;
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
const title = document.createElement('h2');
title.classList.add('title');
title.innerText = 'Loading...';
const content = document.createElement('div');
content.classList.add('content');
for (let i = 0; i < 3; i++) {
const item = document.createElement('div');
item.classList.add('item');
const image = document.createElement('div');
image.classList.add('image');
const text = document.createElement('div');
text.classList.add('text');
item.appendChild(image);
item.appendChild(text);
content.appendChild(item);
}
wrapper.appendChild(title);
wrapper.appendChild(content);
shadow.appendChild(style);
shadow.appendChild(wrapper);
}示例代码
下面是一个完整的骨架屏元素的示例代码:
// www.javascriptcn.com code example
class SkeletonElement extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
const style = document.createElement('style');
style.textContent = `
.wrapper {
width: 100%;
max-width: 600px;
margin: 0 auto;
padding: 20px;
box-sizing: border-box;
background: #fff;
border-radius: 5px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.title {
margin: 0 0 20px;
font-size: 24px;
font-weight: bold;
color: #333;
}
.content {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item {
width: calc(33.33% - 10px);
margin-bottom: 20px;
box-sizing: border-box;
border-radius: 5px;
overflow: hidden;
}
.image {
width: 100%;
height: 0;
padding-bottom: 75%;
background: #f5f5f5;
}
.text {
margin: 10px;
background: #f5f5f5;
height: 20px;
}
`;
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
const title = document.createElement('h2');
title.classList.add('title');
title.innerText = 'Loading...';
const content = document.createElement('div');
content.classList.add('content');
for (let i = 0; i < 3; i++) {
const item = document.createElement('div');
item.classList.add('item');
const image = document.createElement('div');
image.classList.add('image');
const text = document.createElement('div');
text.classList.add('text');
item.appendChild(image);
item.appendChild(text);
content.appendChild(item);
}
wrapper.appendChild(title);
wrapper.appendChild(content);
shadow.appendChild(style);
shadow.appendChild(wrapper);
}
}
customElements.define('skeleton-element', SkeletonElement);指导意义
使用 Custom Elements 构建骨架屏具有以下优点:
可复用性:骨架屏元素可以作为独立的组件进行复用和管理,方便在应用程序中进行集成和扩展。
可维护性:通过将骨架屏的结构和样式封装在元素定义中,可以使代码更加清晰和易于维护。
可扩展性:通过定义自定义属性和方法,可以使骨架屏元素具有更多的功能和特性,例如动态加载数据、自定义样式等。
总之,使用 Custom Elements 构建骨架屏是一种简单、高效和可维护的方式,可以提高 Web 应用的用户体验和开发效率。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d444c3a941bf713480a066