案例总结【原生js置顶插件】

前两天写了个置顶,并封装成插件,体会了一遍自己封装插件的过程,深有感触。
完整代码放在GitHub上:https://github.com/HiJackLi/demo/tree/master/

| 1.

第一就是封装这种功能插件不能扯上外界样式等等界面上的复杂要求,只提供主要功能即可,并且是具有普遍性,能够应用到多种场景中去。

| 2.

第二,封装函数的参数传递什么、如何传递问题:
参数传递如下:

  function scroll(ele,scrollPosition,duration,interval){}

ele(针对哪个元素的滚动条滚动,默认是文档自身滚动条滚动)
scrollPositon(滚动条滚动到哪,默认是文档最顶部)
duration(滚动条滚动的总时间,默认1秒钟)
interval(滚动条滚动的帧率,也就是每一帧运动时间)

如何传递:
如果就这样传递也可以,但未免太过繁琐,在参数较多的情况下,可以传递一个对象进去,把配置选项放在对象中传递,如下:

function scroll( option = {
  ele: document.documentElement,
  scrollPosition: 0,
  duration: 1000,
  interval: 16.7
} ){}

这样,在功能调用时,如果没穿,默认就是这些参数。

但是如果用户传递了参数,并且传递不全,那么这样写最后option对象的默认值就会被替代,最终起不到作用,所以这样写不行。如下引入Object.assign方法进行修改。

function scroll(option={}) {
  defOption = {
ele: document.documentElement,
scrollPosition: 0,
interval: 16.7
  }
  var options = Object.assign(option,defOptions);
}

这样不管用户如何传递参数,都能够正常运行。

| 3.

第三,滚动条滚动需要依托setInterval计时器,但是还得知道每一帧运动的距离,如下是求运动的总距离、运动每一帧的距离的方程
总距离 = 目标距离 - 当前距离
帧距 = 总距离 / 总帧数 = 总距离 / ( 总时间 / 帧率 )
所以代码如下:

// 滚动功能部分
options.distance = options.targetScroll - options.ele.scrollTop; // 总距离
options.times = Math.ceil(options.duration / options.interval); // 总帧数
options.perDistance = options.distance / options.times; // 帧距
var curTimes = 0; // 声明一个参数用于记载运动次数
var timer = setInterval(function () {
  if (curTimes == options.times) {
    clearInterval(timer);
  }
  options.ele.scrollTop += options.perDistance;
  curTimes++;
}, options.interval);

如上,基本上功能就已经实现了。

| 4.

如果只做到上面这种可能一些功能就能实现,但是遇到如下需求就不能够实现了。
需求1:滚动之前置顶按钮需要处理一些事情,希望等我处理完插件在进行滚动
需求2:同需求1,如果我要处理的事情是异步的,希望也能够正常

解决需求1:只要把在传参时设置一个回调函数,并在插件适当位置执行回调,比如在滚动定时器之前插入onscrollBefore() 如下:

// 页面js
scroll({  
   onscrollBefore:function() {  
    // 同步操作  
   }, 
   onscrollAfter:function() {
   }
})

解决需求2:如果onscrollBefore中处理的操作是异步的,那么上面的回调做法并不能解决异步问题,比如等待3秒再滚动,那么点击置顶按钮时,滚动会立即执行,并不会等待3秒,这原因是因为异步操作是要放在事件队列中等待同步操作结束才能够执行的。那么,我们可以在onscrollBefore回调函数中再传入一个参数start,用来控制插件是否执行运动,也就是希望这个参数start把插件的运动能力掌握在自己手中,那么,插件就需要把运动功能部分封装成一个函数,这个函数就是start,代码如下:

// 页面js

scroll({
  onscrollBefore:function(start) {
  // 异步操作
    setTimeout(()=>{
      console.log("等待3秒打印完这句就执行滚动!");
      start();
    },3000)
  }
// 插件js
function scroll(){
  onscrollBefore(start);
function start() {
    // 运动功能部分封装到这个start函数中
  }
}

如上,就解决了异步处理问题。把控制权通过参数交给了用户自己,让用户决定是否和何时滚动。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 我们分手吧。 趁宝宝还没出生,趁我还未曾体会到产床上的撕心裂肺,趁我还不知哺育的辛苦。让我断了念想,此后无人倾诉心...
    三少布甫阅读 2,688评论 0 0
  • 1、今天开了一个小单38万,一个民营医院中央空调项目。 但这次开单和以往的套路完全不同,现在回忆一个过程,感慨万千...
    文小梦阅读 3,077评论 0 1
  • 些小蝥贼窥旧屋, 来去从容未得足。 四壁萧萧何所有? 半床明月半床书。
    青简书阅读 2,688评论 3 3
  • 藤 想长成一棵开花的树, 却成了一地纠结的藤。 无力生长, 无意攀援。 太阳, 是遥远的光亮; 大地, 是无奈的相...
    兰心_e12b阅读 1,823评论 0 1
  • 今天是丧的一天~ 上午第二节课没有课,趁着空闲的时候出去销户,竟然出去还要签字,这该死的坐班制度,把人困在单位,有...
    不在进行的ing阅读 2,939评论 0 0

友情链接更多精彩内容