原生JS:滚动屏案例

381 阅读4分钟

原生JS:滚动屏案例

  • 用ES6方式 实现一个自动滚屏的简单应用
  • 为了阅读方便 js部分有些工具函数没有进行抽离

第一部分

index.html

 <!-- 需要导入初始化样式normal.css 与 common.css -->
    <div class='wrap'> 
      <div class='list-hd'> 
          <h2> 书籍列表 </h2>
       </div>
       
       <div class='container'>
         <ul class='bk-list'>
             <li class='list-item'>
               <a href="./detail.html" class="item-lk">
               
               <!-- 左侧图片 图片自己随便找张 -->
              <div class="bk-pic">
                <img src="./img/前1.jpg" alt="" />
              </div>

            <!-- 右侧信息 -->
              <div class="bk-info">
                <h2>完美世界</h2>
                <p class="author">作者: 他乡的灯火</p>
                <p class="intro">
                  李照冷酷无情,杀人如麻浑身散发着戾气,一个眼神就能让小儿夜啼不止。人人都道定国公府那位娇弱美人,嫁入将军府后撑不了一个月就要吓破了胆……
                  掉马小剧场 婚后,李照大气不敢喘,眉头不敢皱,生怕吓坏了美人。
                  直到这一日,李照得知穆清瑜去了贤王妃设的鸿门宴,手提长剑凶神恶煞赶过去。
                  他的夫人纯良柔弱,进了贤王府那个狼窝岂不是要被啃得连渣都不剩?
                  赶到贤王府,只见贤王妃的寝殿冒着窜天的火光,王妃被火熏得狼狈不堪,痛骂着毫发无损的穆清瑜。
                  穆清瑜柔柔弱弱陪着不是,暗中却把手里的火折子丢了出去,瞬间偏殿也起了火。
                  见到李照,穆清瑜扑到其怀里小声啜泣:“着火了我好害怕~”
                  目睹一切的李照:“……”
                </p>
                <p>更新时间: 2022-03-03</p>
              </div>
            </a>
             </li>
             
             <!-- li元素可以自行复制多个 直到页面产生滚动条 -->
          </ul>
          
        </div>
        
        <!-- 按钮图 -->
        <a href="javascript:;" class="s-stop-btn"> </a>
    </div>
    <script src='./js/index.js'></script>

CSS-初始化样式

  • normal.css
    body{
    margin: 0;
    }
    
    div {
     box-sizing: border-box;
    }
    
    ul{
    list-style: none;
    margin: 0;
    padding: 0;
    }
    
    a{
    text-decoration:none;
    }
    h1,h2,h3,h4,p{
     margin: 0;
     font-weight: normal;
    }
    
    img{
    height: 100%;
    width: 100%;
    }
    
    /* 书籍列表和书籍详情-公共部分样式*/
    .list-hd{
     position: fixed;
     top:0;
     left: 0;
     
     width:100%;
     height: 44px;
     line-height: 44px;
     text-align: center;
     color: #fff;
     z-index: 2;
     background-color: orange;
    }
    
    .container {
     margin-top: 44px;
     }   
    

common.css

.bk-list .list-item{
  position: relative;
  height: 150px;
  border-bottom: 1px solid #000;
}

.bk-list .list-item .item-lk{
  display: block;
  height: 100%;
}

.bk-list .list-item .item-lk .bk-pic{
  position: absolute;
  top: 0;
  left: 0;
  height: 150px;
  padding: 10px;
}

.bk-list .list-item .item-lk .bk-info{
  height: 100%;
  margin-left: 118px;
  color: #424242;
}

.list-item .item-lk .bk-info .author{
  margin: 10px 0 10px 0;
}

.list-item .item-lk .bk-info .intro{
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: red;
  margin-bottom: 10px;
}
.s-stop-btn{
 /* 默认隐藏 */
  display: none;
  position: fixed;
  bottom: 25px;
  right: 15px;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  /* 图片下面找 */
  background: url(../img/rocket.png) no-repeat 0 0/100% 100%;
  opacity: .7;
}
 
  • 图片 rocket.png rocket.png

index.js

 let scrollBtn = (function() {
     class Per {
       constructor(options) {
           this.sTopBtn = options.sTopBtn
       }
       
       // 监听函数
       addEvent(el, type, fn, bl) {
           if(el.addEventListener) {
             el.addEventListener(type, fn, bl)
           }else {
            el['on' + type] = fn;
           }
       }
       
       // 工具函数-计算滚动距离
       getScrollOffset() {
        return {
           left: window.scrollX || document.documentElement.scrollLeft,
           top: window.scrollY || document.documentElement.scrollTop
         }
       }
       
       // 滚动事件处理函数
       showBtn(){
          let sTop = this.getScrollOffset().top;
          
          // 触发滚动且滚动距离有实际值时-显示按钮-反之隐藏
          sTop ? (this.sTopBtn.style.display = 'block')
           : (this.sTopBtn.style.display = 'none')
       }
       
       // 启动函数
       init() {
           this.addEvent(window, 'scroll', this.showBtn.bind(this), false);
           
           // 点击按钮回到顶部
           this.addEvent(this.sTopBtn, 'click', function() {
               window.scrollTo(0, 0);
           }, false)
       }
     }
 
  return Per;
 })();
 
 // 实例
 new scrollBtn({
     sTopBtn: document.querySelector('.s-stop-btn')
 }).init();

第二部分

detail.html

  <!-- 需要导入初始化样式normal.css 和 detail.css -->

  <div class="list-hd">
    <h2>小说详情</h2>
  </div>
  
  <div class='container'>
      <!--这里可以自行多放点文字 把滚动条高度多撑开些就行 -->
  </div>
  
    <!-- 暂停按钮 -->
   <a href="javascript:;" class="round s-stop-btn"></a>

   <!-- 播放按钮 -->
   <a href="javascript:;" class="round play-btn"></a>
   
    <script src="./js/delte.js"></script>

detail.css

.container {
  margin-top: 20px;
  padding: 10px;
}

.round {
  display: block;
  position: fixed;
  right: 25px;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background-color: #000;
}
.round:hover {
  opacity: 1;
}

.s-stop-btn {
  display: none;
  bottom: 100px;
  background: url(../img/rocket.png) no-repeat 0 0/100% 100%;
  opacity: 0.7;
}

.play-btn {
  bottom: 25px;
  background: orange url(../img/play.png) no-repeat 12px   12px/60% 60%;
  text-align: center;
  line-height: 50px;
}
  • 图片 图片是透明色的

pause.png

play.png

detail.js

let scrollBtn = (function () {
  let playing = false,
     t = null;
  // 工具函数
  let toolFn = function () {
    return {
      /**
       * 分别对应:
       * 滚动卷入像素数
       * 视口高度
       * 整个文档高度 包括滚动卷入和不可见区域
       */
      scrollTop: window.scrollY || document.documentElement.scrollTop,
      viewHeight: window.innerHeight || document.documentElement.clientHeight,
      scrollHeight: document.body.scrollHeight || document.documentElement.scrollHeight,
    };
  };

  class Per {
    constructor(options) {
      this.sTopBtn = options.sTopBtn;   // 返回顶部按钮
      this.playBtn = options.playBtn;   // 播放按钮
      this.playImg = options.playImg;   // 播放图标
      this.pauseImg = options.pauseImg; // 暂停图标
    }

    // 事件监听函数
    addEvent(el, type, fn, bl) {
      el.addEventListener ? el.addEventListener(type, fn, bl) : (el["on" + type] = fn);
    }

    // sTopBtn 功能:显隐 && 返回顶部
    showBtn() {
      toolFn().scrollTop ? (this.sTopBtn.style.display = "block") 
      : (this.sTopBtn.style.display = "none");
    }  

    // 播放功能
    setPlay() {
        let sTop = toolFn().scrollTop, // 滚动卷入距离
            vHeight = toolFn().viewHeight, // 视口高度
            dHeight = toolFn().scrollHeight, // 文档高度
            _self = this;

          // 先计算一次
          if(dHeight === sTop + vHeight) {
            return
          }

        // 如果上面逻辑不成立-设置播放
        if(!playing) {
          t = setInterval(() => {
            sTop = toolFn().scrollTop;
            
            if(dHeight <= sTop + vHeight) {
              clearInterval(t)
              _self.playBtn.style.backgroundImage = 'url('+ _self.playImg +')'
              playing = false
            }else {
              window.scrollBy(0, 1)
              _self.playBtn.style.backgroundImage = 'url(' + _self.pauseImg + ')';
            }
          }, 20)

          // 保证播放过程中 点击按钮走下面的逻辑
          playing = true
        }else {
          clearInterval(t);
          _self.playBtn.style.backgroundImage = 'url(' + _self.playImg + ')';
          playing = false
        }
    }

    // 启动函数
    init() {
      let _self = this;
      // 返回顶部按钮的显示 || 隐藏
      this.addEvent(window, "scroll", this.showBtn.bind(this), false);
      // 返回顶部功能
      this.addEvent(this.sTopBtn, 'click', function() {
        window.scrollTo(0, 0)
        clearInterval(t);
        playing = false
        _self.playBtn.style.backgroundImage = 'url(' + _self.playImg + ')';
      },false)

      // 播放按钮
      this.addEvent(this.playBtn, 'click', this.setPlay.bind(this), false)
    }
  }

  return Per;
})();

// 实例
new scrollBtn({
  sTopBtn: document.querySelector(".s-stop-btn"),
  playBtn: document.querySelector(".play-btn"),
  playImg: "./img/play.png",
  pauseImg: "./img/pause.png",
}).init();