移动端 滚动插件

做了一个仿照pc端滚动条的功能,用来解决移动端ios下 scroll卡顿的bug。
目前的参数配置只有id,考虑将高度、是否显示隐藏滑块、样式设置加进去,并且兼容到pc中去。

目前只支持touch事件,可打开chrome的移动端模式,进行操作。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta name="viewport" content="user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <meta charset="UTF-8">
  <title>移动端滚动条测试</title>
  <style>
  .z-scroll{
  width: 250px;
  height: 400px;
  padding: 10px;
  background-color: #f0865c;
  border-radius: 5px;
}
.z-scroll .z-scroll-box{
  background-color: #f2f7f9;
  border-radius: 5px;
  height: 100%;
  margin-right: 25px;
  overflow: hidden;
}
.z-scroll .z-scroll-shank{
  float: right;
  width: 20px;
  height: 100%;
  text-align: center;
}
.z-scroll .z-scroll-shank:before{
  display: inline-block;
  content: '';
  height: 100%;
  width: 5px;
  background-color: #6f2305;
}
.z-scroll .z-scroll-block{
  display: inline-block;
  width: 20px;
  height: 40px;
  border-radius: 4px;
  background-color: #f7f979;
  transform:translateY(-100px);
  cursor:pointer;
}
  .m-doc{
    padding: 10px;
  }
  .m-doc img{
    width: 100%;
    height: auto;
  }
  </style>
</head>
<body>
  <div>
    <h1>我是滚动的插件。</h1>
  </div>
  <div class="z-scroll" id="scroll">
    <div class="z-scroll-shank">
      <span class="z-scroll-block"></span>
    </div>
    <div class="z-scroll-box">
      <div class="z-scroll-content">
        <div class="m-doc">
          <p>世人都爱美女,但对美的态度却模棱两可。欣赏艳羡的同时,又不免在内心嘀咕一句:生得一副好皮囊,真是独得上天厚爱,难怪一生顺风顺水花团锦簇呢。说到美女,尤其是民国美女,林徽因便是其中名声最大的了,只是有人奉她为女神,有人觉得她也不过是个“绿茶婊”而已,挽着个梁思成,念念不忘徐志摩,甚至还让人家金岳霖为她终身不嫁。这些评说里,大家都只将她视为女人、长得漂亮的女人,却忽略了她所做的事情。</p>
          <p>林徽因曾说过:“真讨厌,什么美人、美人,好像女人没有什么事可做似的,我还有好些事要做呢!”在她看来,仅以“美人”来看待她,是对她的轻视。</p>
          <p>为什么人人视为“福利”的美好容颜,在林徽因这里却成了苦恼呢?因为对林徽因的生命历程来说,姣好的容貌却是她身上最不足称道的东西。</p>
          <strong>说到不忘初心,没有人比她做得更好</strong>
          <p>你还记得十几岁时的梦想吗?想必没有多少人能回答:我一直在坚守梦想。但林徽因,十六岁受邻居女建筑师影响,立下投身建筑事业的志愿后,一生都在为这个梦想,不懈耕耘。</p>
          <p>彼时,梁思成尚未确认志向,曾想子承父业学习西方政治,但被林徽因对建筑的高谈阔论改变了主意。甚至在谈婚论嫁时,她也以对方必须与自己到美国学习建筑为条件,对梁思成的一生的立志起了关键作用。她对自我理想和实现都有着清醒的认识,真让十点君汗颜。</p>
          <p>不远万里赴美国留学,却得知建筑系不招女生。她便“曲线救国”,在美术系注册,但选修了建筑学的全部课程。她全身心投入课业,优异的成绩使她成为课程助教。在接受美国一家报纸的采访时,她自信地说:“我要带回什么是中西方碰撞的真正含义。”——学成归国,她与梁思成受聘于东北大学,创建建筑系,将留学时的经验用于学校。林徽因还设计了东北大学“白山黑水”的校徽。</p>
          <img src="./images/img01.jpg" alt="">
          <p>林徽因早年患肺疾,抗战期间颠沛流离,病情加剧为肺结核。但哪怕身患重疾(肺结核在当时属于不治之症),她依然与梁思成一路餐风露宿、翻山越岭,走遍中国15个省、200多个县,考察测绘了200多处古建筑。尤其是骑着毛驴寻觅到佛光寺时,身体羸弱的林徽因,亲自爬上长梯测量。</p>
          <strong>不以诗人的美誉为荣,也不以被人恋爱为辱</strong>
          <p>十六岁时,林徽因在英国与诗人徐志摩相识,后者很快便陷入了她清亮的眼眸里,甚至不惜为了她与妻子张幼仪离婚。徐志摩坦言,自己是因为林徽因才走上了诗歌的道路,她是落在他心湖里的一朵云,甘愿做她裙边的一株草,哪怕只能在凝望中爱着她。</p>
          <p>林徽因最终选择了梁思成。她欣赏徐志摩的浪漫与飘逸,但睿智如她,并不任由感性来左右自己选择,就连张幼仪都评价她“是一位思想更复杂、长相更漂亮、双脚更自由的女士”。</p>
        </div>
      </div>
    </div>
  </div>
  <script>
  /** [zScroll description]constructor */
function zScroll(options) {
  this.options = options || {};
  if (this.options.id) {
    this.container = document.getElementById(this.options.id);
    //render ...
    this.swiperPanel = this.container.children[1].children[0];
    this.shank = this.container.children[0];
    this.swiperBlock = this.shank.children[0];
    this.initBlockPosition();
  } else {
    console.log('add the id of element');
  }
};
/** [initBlockPosition description]初始化滑块位置 */
zScroll.prototype.initBlockPosition = function() {
  if (this.shank && this.swiperBlock) {
    var shank_ht = this.shank.offsetHeight;
    this.swiperBlock.style.webkitTransform = 'translateY(-' + shank_ht + 'px)';
    this.swiperPanel.style.webkitTransform = 'translateY(0px)';
    this.moveBlock(shank_ht);
  }
};
/** [moveBlock description]移动滑块位置 */
zScroll.prototype.moveBlock = function(shank_ht) {
  var _this = this;
  this.startY = 0;
  this.y = 0;
  this.startPanelY = 0;
  this.panelY = 0;
  this.aboveY = -shank_ht;
  this.abovePanelY = 0;
  if (_this.container) {
    _this.container.addEventListener('touchstart', function(e) {
      var target = e.target || e.srcElement;
      if (target.className == _this.swiperBlock.className) {
        _this.touchStart.call(_this, e);
      } else if (_this.swiperPanel.contains(target)) {
        _this.touchStartPanel.call(_this, e);
      }
    });
    _this.container.addEventListener('touchmove', function(e) {
      var target = e.target || e.srcElement;
      if (target.className == _this.swiperBlock.className) {
        _this.touchMove.call(_this, e);
      } else if (_this.swiperPanel.contains(target)) {
        _this.touchMovePanel.call(_this, e);
      }
    });
    _this.container.addEventListener('touchend', function(e) {
      var target = e.target || e.srcElement;
      if (target.className == _this.swiperBlock.className) {
        _this.touchEnd.call(_this, e);
      } else if (_this.swiperPanel.contains(target)) {
        _this.touchEndPanel.call(_this, e);
      }
      return true;
    });
  }
};
zScroll.prototype.touchStart = function(e) {
  var touch = e.touches[0];
  this.startY = touch.pageY;
  e.preventDefault();
};
zScroll.prototype.touchMove = function(e) {
  var touch = e.touches[0],
    shank_ht = this.shank.offsetHeight,
    block_ht = this.swiperBlock.offsetHeight;
  this.y = parseInt(this.aboveY + touch.pageY - this.startY);
  if (this.y <= -block_ht && this.y >= -shank_ht) {
    this.swiperBlock.style.webkitTransform = 'translateY(' + this.y + 'px)';
    this.moveSwipePanel();
  } else {
    if (this.y < -shank_ht) {
      this.y = -shank_ht;
      this.swiperBlock.style.webkitTransform = 'translateY(' + this.y + 'px)';
      this.moveSwipePanel();
    } else if (this.y > -block_ht) {
      this.y = -block_ht;
      this.swiperBlock.style.webkitTransform = 'translateY(' + this.y + 'px)';
      this.moveSwipePanel();
    }
  }
  e.preventDefault();
};
zScroll.prototype.touchEnd = function(e) {
  var cssPanel = this.swiperPanel.style.webkitTransform,
    cssBlock = this.swiperBlock.style.webkitTransform;
  this.aboveY = cssBlock ? parseInt(cssBlock.split('(')[1].split(')')[0].replace('px', '')) : -this.shank.offsetHeight;
  this.abovePanelY = cssPanel ? parseInt(cssPanel.split('(')[1].split(')')[0].replace('px', '')) : 0;
  e.preventDefault();
};
/** [moveSwipePanel description]移动内容 */
zScroll.prototype.moveSwipePanel = function() {
  var shank_ht = this.shank.offsetHeight;
  var x1 = this.swiperPanel.offsetHeight - shank_ht,
    x2 = shank_ht - this.swiperBlock.offsetHeight;
  if (x2 != 0) {
    var y2 = parseInt(x1 / x2 * (this.y + shank_ht));
    this.swiperPanel.style.webkitTransform = 'translateY(' + -y2 + 'px)';
  }
};


/** [touchStartBlock description]面板滑动事件 */
zScroll.prototype.touchStartPanel = function(e) {
  var touch = e.touches[0];
  this.startPanelY = touch.pageY;
  e.preventDefault();
};
zScroll.prototype.touchMovePanel = function(e) {
  var touch = e.touches[0],
    shank_ht = this.shank.offsetHeight,
    panel_ht = this.swiperPanel.offsetHeight;
  this.panelY = parseInt(this.abovePanelY + touch.pageY - this.startPanelY);
  if (this.panelY <= 0 && this.panelY >= -(panel_ht - shank_ht)) {
    this.swiperPanel.style.webkitTransform = 'translateY(' + this.panelY + 'px)';
    this.moveSwipeBlock();
  } else {
    if (this.panelY > 0) {
      this.panelY = 0;
      this.swiperPanel.style.webkitTransform = 'translateY(' + this.panelY + 'px)';
      this.moveSwipeBlock();
    } else if (this.panelY < -(panel_ht - shank_ht)) {
      this.panelY = -(panel_ht - shank_ht);
      this.swiperPanel.style.webkitTransform = 'translateY(' + this.panelY + 'px)';
      this.moveSwipeBlock();
    }
  }
  e.preventDefault();
};
zScroll.prototype.touchEndPanel = function(e) {
  var cssPanel = this.swiperPanel.style.webkitTransform,
    cssBlock = this.swiperBlock.style.webkitTransform;
  this.aboveY = cssBlock ? parseInt(cssBlock.split('(')[1].split(')')[0].replace('px', '')) : -this.shank.offsetHeight;
  this.abovePanelY = cssPanel ? parseInt(cssPanel.split('(')[1].split(')')[0].replace('px', '')) : 0;
  e.preventDefault();
};
/** [moveSwipePanel description]移动内容 */
zScroll.prototype.moveSwipeBlock = function() {
  var shank_ht = this.shank.offsetHeight;
  var x1 = this.swiperPanel.offsetHeight - shank_ht,
    x2 = shank_ht - this.swiperBlock.offsetHeight;
  if (x1 != 0) {
    var y2 = parseInt(x2 * this.panelY / x1 + shank_ht);
    this.swiperBlock.style.webkitTransform = 'translateY(' + -y2 + 'px)';
  }
};
// ----  其他 -------//
/** [addStyle description]添加样式 */
zScroll.prototype.addStyle = function(el, classStyle) {
  if (typeof classStyle == 'object' && el) {
    for (var name in classStyle) {
      el.style[name] = classStyle[name];
    }
  }
};
  </script>
  <script>
    var scroll=new zScroll({
      id:'scroll'
    });
  </script>
</body>
</html>

欢迎分享本文,转载请保留出处:前端ABC » 移动端 滚动插件

分享到:更多 ()

发表评论 0