【青训营】- 代码分析 分析一个 模板化的 Slider 代码

388 阅读2分钟

上一篇分析:【青训营】- 分析一个 Component (juejin.cn)

书接上回,我们上一次分析的 Slider 大部分依然是静态的,包括轮播图片、控制器、翻页等,都需要静态写入 HTML 文件中,这样会导致我们修改的时候一点也不优雅,添加图片要重新写标签,修改控件也要修改 HTMLJS,各种意义上的麻烦。所以我们能不能优化一下,让整个 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()
  1. 首先可以看到 Slider 构造器有了很大改变:

    1. 构造器多一个图片地址列表的参数
    2. 容器内 HTMLrender() 函数生成
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>`;
}
  1. render() 函数:

    1. 获取 images 并用 map() 遍历,并返回一个新数组给 content
    2. 使用模板字符串将遍历项 image 赋值给 imgsrc 属性
    3. 最后使用 join() 拼接,放在 <ul></ul> 之内
    4. 返回 ulHTML 代码

    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);
  });
}
  1. registerPlugins(...plugins) 也产生的较大改变:

    1. forEach() 遍历 plugins
    2. 对于遍历项 plugin 生成一个 div.slider-list__plugin
    3. div.slider-list__plugininnerHTMLplugin.render() 生成
    4. div#my-slider.slider-list 中添加 div.slider-list__plugin
    5. 执行 plugin.action(),这里的 action() 做了类似上一篇中构造函数的事情

这次我们的 controllerpreviousnext 都写成了 const 对象,需要时只需要在 slider.registerPlugins() 中传入相应的变量名即可,就可以直接在 Slider 容器中生成 HTML代码,不需要时直接删除相应的参数即可,不需要手动修改任何的静态 HTML 代码。

HTML 模板化来解耦,好处是更易于扩展,比如我需要一个返回一张图片的按钮,可以在 JS 写一个组件,后续用或者不用就看传还是不传参数。

个人总结

不知道分析对大家有没有帮助,在我看来这就像是给小黄鸭讲代码(笑),形成笔记也可以帮助我们理解或者复习。分析不少还是直接练练来得快,下次我写一个插件分析分析。