上一篇分析:【青训营】- 分析一个 Component (juejin.cn)
书接上回,我们上一次分析的 Slider 大部分依然是静态的,包括轮播图片、控制器、翻页等,都需要静态写入 HTML 文件中,这样会导致我们修改的时候一点也不优雅,添加图片要重新写标签,修改控件也要修改 HTML 和 JS,各种意义上的麻烦。所以我们能不能优化一下,让整个 Slider 都是动态生成的呢?来看一下本次的 Slider 代码分析 <-- 可点
分析 HTML
<div class="slider-list" id="my-slider"></div>
本次 HTML 部分没啥需要分析的,使用了一个 div#my-slider.slider-list 作为 Slider 容器
分析 CSS
来分析一个垂直居中吧,核心代码以下几句
.slide-list__next,
.slide-list__previous {
...
position: absolute;
top: 50%;
margin-top: -25px;
height: 50px;
...
}
这里使用子绝父相(子元素绝对定位父元素相对定位),top: 50%; 使这个元素的高度在父元素高度一半的位置,但是因为 .slide-list__next 和 .slide-list__previous 自身的高度,所以位置会比较偏下,使用margin-top: -25px; 让元素位置向上走自身的一半回到预想的位置。
提供另外一种方法 transform: translate(0,-50%); 替换 margin-top: -25px;可以实现相同效果。
分析 JavaScript
| Slider |
|---|
| +render() |
| +registerPlugins(...plugins) |
| +getSelectedItem() |
| +getSelectedItemIndex() |
| +slideTo(idx) |
| +slideNext() |
| +slidePrevious() |
| +start() |
| +stop() |
-
首先可以看到
Slider构造器有了很大改变:- 构造器多一个图片地址列表的参数
- 容器内
HTML由render()函数生成
render() {
const images = this.options.images;
const content = images.map(image => `
<li class="slider-list__item">
<img src="${image}"/>
</li>
`.trim());
return `<ul>${content.join('')}</ul>`;
}
-
render()函数:- 获取
images并用map()遍历,并返回一个新数组给content - 使用
模板字符串将遍历项image赋值给img的src属性 - 最后使用
join()拼接,放在<ul></ul>之内 - 返回
ul的HTML代码
trim()的作用没咋看懂,去掉也能有同样效果 - 获取
registerPlugins(...plugins) {
plugins.forEach(plugin => {
const pluginContainer = document.createElement('div');
pluginContainer.className = '.slider-list__plugin';
pluginContainer.innerHTML = plugin.render(this.options.images);
this.container.appendChild(pluginContainer);
plugin.action(this);
});
}
-
registerPlugins(...plugins)也产生的较大改变:forEach()遍历plugins- 对于遍历项
plugin生成一个div.slider-list__plugin div.slider-list__plugin的innerHTML由plugin.render()生成- 向
div#my-slider.slider-list中添加div.slider-list__plugin - 执行
plugin.action(),这里的action()做了类似上一篇中构造函数的事情
这次我们的 controller,previous,next 都写成了 const 对象,需要时只需要在 slider.registerPlugins() 中传入相应的变量名即可,就可以直接在 Slider 容器中生成 HTML代码,不需要时直接删除相应的参数即可,不需要手动修改任何的静态 HTML 代码。
将 HTML 模板化来解耦,好处是更易于扩展,比如我需要一个返回一张图片的按钮,可以在 JS 写一个组件,后续用或者不用就看传还是不传参数。
个人总结
不知道分析对大家有没有帮助,在我看来这就像是给小黄鸭讲代码(笑),形成笔记也可以帮助我们理解或者复习。分析不少还是直接练练来得快,下次我写一个插件分析分析。