JS - DOM特效封装 -07

DOM特效封装


注意:为了达到各个浏览器之间的兼容问题,下面的Js文件是已经封装好了的方法,下面的某些案例为了避免重复代码,故有的文件则会引用如下几个JS文件.

L.js

(function(w){
  var L = w.L ? w.L : {}; // 定义L框架的根。
  // 我们占用了全局的L变量名。
  L.Dialog = function(selector) {

    // 先判断选择器对应之前已经创建过了吗?如果创建过了直接返回对象。
    if(L.Dialog.cache[selector]) {
      return L.Dialog.cache[selector];
    }
    // 接受用户传来的选择器
    // 1、要有一个 show方法, 弹出对话框。
    // 2、 关闭方法 close
    // 3、动态解析用户的输入信息。
    var dialogDiv = document.querySelector(selector);
    if(!dialogDiv) {
      return null;
    }
    // 拿到用户给的标题文本。
    var title = dialogDiv.getAttribute('title');

    // 初始化遮罩层。
    var dialogCover = document.createElement('div');
    dialogCover.className = "dialog-cover";
    dialogCover.style.display = "none";
    document.body.appendChild(dialogCover);
    var strHTML = "";
    strHTML += '<div class="dialog">';
    strHTML +='   <div class="dialog-h">';
    strHTML +='     <h3>' + title + '</h3>';
    strHTML +='     <i class="btn-close" id="">X</i>'
    strHTML +='   </div>'
    strHTML +='   <div class="dialog-b">'
    strHTML +=      dialogDiv.innerHTML;
    strHTML +='   </div>'
    strHTML +=' </div>'
    dialogDiv.innerHTML = strHTML;

    var dialog = {
      dialogDiv: dialogDiv, // 用户的dialog的div
      title: title,  // 用户的标题
      dialogCover: dialogCover,  // 遮罩层属性。
      show: function() {
        // 弹出层
        // 第一个显示 遮罩层, 第二个显示对话框  第三个,给关闭按钮绑定点击事件。
        this.dialogCover.style.display = "block";
        this.dialogDiv.style.display = "block";
        var self = this;
        var btnClose = dialogDiv.querySelector('.btn-close');
        btnClose.onclick = function() {
          self.close();
        }
      },
      close: function() {
        // 关闭层
        // 第一个不显示 遮罩层, 第二个不显示对话框  第三个,给关闭按钮去掉绑定点击事件。
        this.dialogCover.style.display = "none";
        this.dialogDiv.style.display = "none";
        var self = this;
        var btnClose = dialogDiv.querySelector('.btn-close');
        btnClose.onclick = null;
      }
    };

    L.Dialog.cache[selector] = dialog;
    return dialog;
  }

  // 在函数上创建一个缓存。 放 selector 对应的  dialog对象。
  L.Dialog.cache = {};
  w.L = L;
})(window || {});

/* 封装 动画的效果方法  */
(function(w){
  var L = w.L ? w.L : {}; // 定义L框架的根。
  // 我们占用了全局的L变量名。
  /**
   * @description 进行slideDown动画的方法
   * @param {HTMLElemnet} element 要进行动画的元素
   * @param {number} duration 持续的事件
   * @return {undefined}
   */
  L.slideDown = function(element, duration) {
    var start = Date.now(); // 开始动画的时间。
    element.style.display = "block";
    var originH = element.clientHeight;
    element.style.height = '0px';

    var timer = setInterval(function(){
      var now = Date.now();
      element.style.height = (now-start)/duration * originH + 'px';
      if(now-start >= duration) {
        element.style.height = originH + 'px';
        clearInterval(timer);
      }
    }, 1000/60);
  };
  w.L = L;
})(window || {});

 

案例:65-模态对话框-面向对象封装

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>65-模态对话框.html</title>
  <style>
    html,
    body,
    div,
    h3 {
      padding: 0;
      margin: 0;
    }
    .dialog-wrap {
      display: none;
    }

    .dialog {
      position: absolute;
      left: 50%;
      top: 50%;
      margin-top: -151px;
      margin-left: -151px;
      background-color: #eee;
      border: 1px solid #ccc;
      width: 300px;
      /* display: none; */
      z-index: 1000;
    }

    .dialog .dialog-h {
      border-bottom: 1px solid #ccc;
      height: 30px;
      position: relative;
    }

    .dialog-b {
      height: 269px;
    }

    .dialog-h .btn-close {
      position: absolute;
      right: 15px;
      top: 5px;
      cursor: pointer;
    }

    .dialog-cover {
      /* 如果一个div的父容器为body,而且是绝对定位,那么left和top、bottom、right都为0
      的时候就会铺满正个屏幕 */
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: #ccc;
      z-index: 100;
      /* 设置透明 */
      filter: alpha(opacity=70);
      opacity: 0.7;
    }
  </style>
  <script src="../js/L.js"></script>
</head>

<body>
  <input type="button" value="弹出对话框" id="btn">

  <!-- 规定: 用户要使用dialog对话框,必须 -->
  <!-- 1、div 的class = dialog-wrap -->
  <!-- 2、需要给div增加 title属性,如果没有增加,那么标题就是空的 -->
  <!-- 3、div的innerHTML就是显示在对话框上的信息 -->
  <div id="mDialog" class="dialog-wrap" title="弹出来的对话框">
    在对话框里面显示的内容
    <p>好样的!!</p>
    <input type="button" value="关闭">
  </div>

  <script>
    window.onload = function () {
      var btn = document.getElementById('btn');
      btn.onclick = function () {
        var dialog = new L.Dialog("#mDialog");// 如果用户没有用new,也不会报错。
        // 在 #mDialog上进行创建一个模态对话框。
        // var dialog = new Dialog("#mDialog");
        // 可能框架有多个 组件。要兼容扩展其他的组件。 L框架
        dialog.show(); // 弹出对话框了。
      }
    }
  </script>
  <h1>1</h1>
  <h1>2</h1>
  <h1>3</h1>
  <h1>4</h1>
  <h1>5</h1>
  <h1>6</h1>
  <h1>7</h1>
  <h1>8</h1>
  <h1>9</h1>
  <h1>10</h1>
  <h1>11</h1>
  <h1>12</h1>
  <h1>13</h1>
  <h1>14</h1>
  <h1>15</h1>
  <h1>16</h1>
  <h1>17</h1>
  <h1>18</h1>
  <h1>19</h1>
  <h1>20</h1>
  <h1>21</h1>
  <h1>22</h1>
  <h1>23</h1>
  <h1>24</h1>
  <h1>25</h1>
  <h1>26</h1>
  <h1>27</h1>
  <h1>28</h1>
  <h1>29</h1>
  <h1>30</h1>

</body>

</html>

DOM特效封装

案例:66-slideDown

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>slideDown</title>
  <style>
    html, body, div {
      padding: 0;margin: 0;
    }

    .box {
      border: 1px solid #ccc;
      width: 300px;
      height: 300px;
      background-color: #eee;
    }

    .wrap {
      width: 960px;
      margin: 0 auto;
    }
  </style>
</head>
<body>
  <div class="wrap">
    <input type="button" value="折叠" id="btnSlideUp">
    <input type="button" value="展开" id="btnSlideDown">
    <div class="box" id="box">
      我是box
    </div>
  </div>
  <script>
    (function(){
      window.onload = function(){
        var btnSlideUp = document.getElementById('btnSlideUp'),
            btnSlideDown = document.getElementById('btnSlideDown'),
            box = document.getElementById('box');

        btnSlideDown.onclick = function() {
          slideDown(box, 100);

          // var start = Date.now(); // 最开始的的事件。
          // // 如果div的display为none那么 clientHeight 0
          // box.style.display = "block";
          // var originH = box.clientHeight;// 最开始的高度
          // box.style.height = "0px";
          // var timer = setInterval(function(){
          //   var now = Date.now();
          //   box.style.height = (now - start) / 500 * originH + 'px';
          //   if(now - start >= 500) {
          //     box.style.height = originH + 'px';
          //     clearInterval(timer);
          //   }
          // }, 1000/60);
        }

        // 点击 折叠按钮后,让div一点一点进行向上折叠。
        btnSlideUp.onclick = function(e) {
          var start = Date.now(); // 返回当前时间的utc时间,1970 毫秒数
          // 随着时间的推移,让div的高度一直减小。到最后为0. display:none
          var originH = box.clientHeight;// 拿到显示的高度。div height
          
          // 1秒钟后,div消失。1000ms
          var timer = setInterval(function(){
            // var now = Date.now();
            // console.log(now - start);// 两个事件相差的毫秒数。16
            // start = now;
            // 思路一: 当前事件和上一次执行的相隔事件执行div的减少高度操作。

            // 思路二: 当前事件跟最一开始的时间进行计算。把相差总时间换算成
            // 应该减少的高度,然后设置div的高度。
            var now = Date.now();

            // 要减少的高度
            var nowH = (now - start) * originH / 1000;
            // 当前div的高度 = 原来的高度 -  要减少的高度
            box.style.height = (originH - nowH) + 'px';
            if(originH <= nowH) {
              // 停止折叠,并且把当前div 隐藏起来。并且把时钟去掉。
              box.style.height = originH + "px"; // 隐藏之后还要把它恢复到原来的状态。
              box.style.display = "none";
              clearInterval(timer);
            }

          },1000/60);
          //问题1:  1000/60 ,setInterval执行 的不是严格按照时间间隔去执行。
        };
      };
    })();

    /**
     * @description 进行向下展开的函数
     * @param {HTMLElement} element - 要进行动画的标签
     * @param {number} duration - 动画持续的事件
     * @return {undefined}  
     **/
    function slideDown(element, duration) {
      var start = Date.now(); // 开始动画的时间。
      element.style.display = "block";
      var originH = element.clientHeight;
      element.style.height = '0px';

      var timer = setInterval(function(){
        var now = Date.now();
        element.style.height = (now-start)/duration * originH + 'px';
        if(now-start >= duration) {
          element.style.height = originH + 'px';
          clearInterval(timer);
        }
      }, 1000/60);
    }
  </script>

</body>
</html>

DOM特效封装 - 68-轮播图效果

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>轮播图</title>
  <style>
    html,
    body,
    div,
    ul,
    li {
      padding: 0;
      margin: 0;
    }

    ul,
    ol {
      list-style: none;
    }

    a {
      text-decoration: none;
      color: #000;
    }

    .slideshow {
      width: 500px;
      height: 300px;
      border: 1px solid #ccc;
      margin: 100px auto;
      overflow: hidden;
      position: relative;
    }

    .slideshow .slide-img-wrap {
      width: 2000px;
      position: absolute;
      left: 0;
      top: 0;
      z-index: 1;
    }

    .slideshow .slide-img-wrap li {
      float: left;
      width: 500px;
    }

    .slideshow .slide-img-wrap li img {
      width: 500px;
      height: 300px;
    }
    /* 设置下一个和上一个的按钮 */

    .slideshow .slide-btn-wrap {
      position: absolute;
      z-index: 100;
      top: 50%;
      left: 0;
      width: 500px;
      height: 30px;
      margin-top: -15px;
    }

    .slideshow .slide-btn-wrap a {
      color: #999;
      font-size: 30px;
      line-height: 30px;
      font-weight: bold;
      background-color: rgba(99, 99, 99, .5);
      margin: 5px;
    }

    .slideshow .slide-btn-wrap a:hover {
      background-color: rgba(99, 99, 99, .8);
    }

    .slideshow .slide-btn-wrap .next {
      float: right;
    }

    .slideshow .slide-btn-wrap .prev {
      float: left;
    }
    /* 设置圆点选择 */

    .slideshow .slide-sel-btn {
      position: absolute;
      top: 80%;
      left: 50%;
      margin-left: -28px;
      height: 10px;
      width: 64 px;
      z-index: 100;
    }

    .slideshow .slide-sel-btn a {
      border-radius: 50%;
      background-color: #fff;
      width: 8px;
      height: 8px;
      margin-right: 8px;
      float: left;
    }

    .slideshow .slide-sel-btn a.on {
      background-color: #666;
    }
  </style>
</head>

<body>
  <div class="slideshow">
    <!-- 滑动的图片 -->
    <ul class="slide-img-wrap">
      <li index="0" class="on">
        <a href="#">
          <img src="../img/1.jpg" alt="">
        </a>
      </li>
      <li index="1">
        <a href="#">
          <img src="../img/2.jpg" alt="">
        </a>
      </li>
      <li index="2">
        <a href="#">
          <img src="../img/3.jpg" alt="">
        </a>
      </li>
      <li index="3">
        <a href="#">
          <img src="../img/4.jpg" alt="">
        </a>
      </li>
    </ul>

    <!-- 上一张和下一张的按钮 -->
    <div class="slide-btn-wrap">
      <a href="javascript:0" class="prev">&lt;</a>
      <a href="javascript:0" class="next">&gt;</a>
    </div>

    <!-- 选择圆圈按钮 -->
    <div class="slide-sel-btn">
      <a index="0" class="on" href="javascript:0"></a>
      <a index="1" href="javascript:0"></a>
      <a index="2" href="javascript:0"></a>
      <a index="3" href="javascript:0"></a>
    </div>

  </div>

  <script>
    // 实现第一张滑动到第二张
    window.onload = function () {

      // 下一个按钮
      var btnNext = document.querySelector('.slide-btn-wrap .next');
      btnNext.onclick = function (e) {
        slideShowNext();
        autoSlide();
      };

      // 上一个按钮
      var btnPrev = document.querySelector('.slide-btn-wrap .prev');
      btnPrev.onclick = function (e) {
        slideShowPrev();
        autoSlide();
      };

      // 具体选中圆圈的跳转的具体页面
      var selBtnDiv = document.querySelector('.slide-sel-btn');
      selBtnDiv.onclick = function (e) {
        e = e || window.event;
        var target = e.target || e.srcElement;
        if (target == this) {
          return;
        }

        // 如果是点击子元素 a标签
        var nextIndex = target.getAttribute('index');
        nextIndex = parseInt(nextIndex);

        // 设置为on的样式类的a标签
        var curA = document.querySelector('.slide-sel-btn .on');
        var curIndex = curA.getAttribute('index');
        var curIndex = parseInt(curIndex);
        console.log('next:' + nextIndex + '  prev:' + curIndex)

        slide(curIndex, nextIndex);
        // 选中轮播后,要重新设置自动轮播 的时钟
        autoSlide();
      }

      // 自动轮播
      autoSlide();
    };

    // 执行下一张图片
    function slideShowNext() {
      // 滑动下一张图片
      var curLi = document.querySelector('.slide-img-wrap .on');
      var curIndex = curLi.getAttribute('index');
      curIndex = parseInt(curIndex); // 0, 1, 2, 3

      // 让索进行循环: 0,1,2,3,1,2,3,0,.....
      var nextIndex = (curIndex + 1) % 4;

      slide(curIndex, nextIndex);
    }

    function slideShowPrev() {
      // 滑动下一张图片
      var curLi = document.querySelector('.slide-img-wrap .on');
      var curIndex = curLi.getAttribute('index');
      curIndex = parseInt(curIndex); // 0, 1, 2, 3

      // 让索进行循环: 0,1,2,3,1,2,3,0,.....
      var nextIndex = (curIndex - 1 + 4) % 4;

      slide(curIndex, nextIndex);
    }

    var timer;
    // 自动轮播
    function autoSlide() {
      // 先去掉时钟。
      if (timer) {
        clearInterval(timer);
        timer = null;
      }

      // 实现自动滚动效果。
      timer = setInterval(function () {
        slideShowNext();
      }, 2000);
    }

    function slide(curIndex, nextIndex) {
      // 0  left: 0
      // 1  left: -500px
      // 2  left: -1000px
      // 3  lfet: -1500px
      // 要让下一个图片的左放到盒子的最左侧。

      var imgList = document.querySelector('.slide-img-wrap');

      var nextLeft = nextIndex * (-500);
      var curLeft = imgList.offsetLeft;

      // imgList.style.left = (imgList.offsetLeft - 500) + 'px';
      // imgList.style.left = nextLeft + 'px';
      // 进行动画的轮播
      slideAnimate(curLeft, nextLeft, imgList, 500);

      // 把li标签和span标签的选中的那个标签的class的 on设置一下。
      var liArray = document.querySelectorAll('.slide-img-wrap li');
      liArray[curIndex].className = "";
      liArray[nextIndex].className = "on";

      // slide-sel-btn 下面的a标签 重新设置on
      var slideSelBtnArray = document.querySelectorAll('.slide-sel-btn a');
      slideSelBtnArray[curIndex].className = "";
      slideSelBtnArray[nextIndex].className = "on";
    }

    // 对元素进行连续的滚动
    function slideAnimate(curLeft, endLeft, element, duration) {
      var w = endLeft - curLeft; // 总的滑动的距离
      var wPerMS = w / duration; // 每毫秒需要移动的距离。
      var startTime = Date.now();

      var ainmateTimer = setInterval(function(){
        var curTime = Date.now();
        // 每一帧直接的时间间隔。
        var delateTime = curTime - startTime;

        element.style.left = (element.offsetLeft + delateTime * wPerMS ) + 'px';
        duration = duration - delateTime;
        if(duration <= 0) {
          element.style.left = endLeft + 'px';
          clearInterval(ainmateTimer);
          return;
        }
        // 把当前时间设置成起始时间。
        startTime = curTime;
      }, 1000/60);
    }
  </script>
</body>

</html>

DOM特效封装 - 手风琴效果

案例:69-accordion手风琴

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>70-accordion手风琴.html</title>
  <style>
    html, body, div, ul, li {
      margin: 0; padding: 0;
    }
    ul, ol {
      list-style: none;
    }

    .ac {
      border: 1px solid #ccc;
      width: 300px;
      margin: 100px auto;
    }
    .ac .ac-item .ac-item-hd {
      height: 30px;
      line-height: 30px;
      background-color: #efefef;
      border: 1px solid #ddd;
      cursor: pointer;
    }
    .ac .ac-item .ac-item-bd {
      display: none;
      height: 150px;
    }
    .ac .on .ac-item-bd {
      display: block;
    }
  </style>
</head>
<body>
  <ul class="ac">
    <li class="ac-item on">
      <div class="ac-item-hd">头部1</div>
      <div class="ac-item-bd">内容1</div>
    </li>
    <li class="ac-item">
      <div class="ac-item-hd">头部2</div>
      <div class="ac-item-bd">内容2</div>
    </li>
    <li class="ac-item">
      <div class="ac-item-hd">头部3</div>
      <div class="ac-item-bd">内容3</div>
    </li>
    <li class="ac-item">
      <div class="ac-item-hd">头部4</div>
      <div class="ac-item-bd">内容4</div>
    </li>
  </ul>

  <script>
  window.onload = function() {
    var liArray = document.querySelectorAll('.ac-item');
    for(var i = 0; i <liArray.length; i++) {
      liArray[i].onclick = function(e) {
        for(var j = 0; j < liArray.length; j++) {
          liArray[j].className = "ac-item";
        }
        // li被点击后,自己要添加on样式类,所有的兄弟li都要去掉on样式类
        this.className = "ac-item on";
      };
    }
  };
  </script>
</body>
</html>

表单验证

动态创建表格

案例:70-表单校验

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>表单校验</title>
</head>
<body>
  <form id="frm" action="#">
    <table>
      <!-- <tr>
        <td>html5 </td>
        <td>
          <input type="email" name="txtName" id="txtName">
          <input type="number" name="txtName" id="txtName">
          <input type="date" name="txtName" id="txtName">
        </td>
      </tr> -->
      <tr>
        <td>姓名:</td>
        <td>
          <input type="text" name="txtName" placeholder="文本不少于6个字符" id="txtName">
        
        </td>
      </tr>
      <tr>
        <td>邮箱</td>
        <td><input type="text" name="txtEmail" id="txtEmail"></td>
      </tr>
      <tr>
        <td>Tel</td>
        <td><input type="text" name="txtTel" id="txtTel"></td>
      </tr>
     
      <tr>
        <td colspan="2">
          <input type="submit" value="提交">
          <input type="reset" value="重置">
        </td>
      </tr>
    </table>
  </form>

  <script>
    window.onload = function() {
      // 拿到表单
      var frm = document.getElementById('frm');
      // var frm = document.forms[0];

      // 用户名长度错误是提示的消息
      var txtNameMsg = document.createElement('span');
      txtNameMsg.innerHTML = "姓名的字符串长度必须在6-20之间";
      txtNameMsg.style.color = "red";

      // 表单提交的时候限制性此事件响应方法
      frm.onsubmit = function(e) {
        // console.log('frm submit')

        // 校验用户名文本框的字符不少于6个字符,但不能多于20个字符
        var txtName = document.getElementById('txtName');
        // txtName.value;
        var txtNameRegExp = /\w{6,20}/gi;
        if(txtNameRegExp.test(txtName.value)) {
          // 移除文本框错误消息
          txtName.parentNode.removeChild(txtNameMsg);
        } else {
          // 校验失败,添加错误信息取消默认操作
          txtName.parentNode.appendChild(txtNameMsg);
          return false;
        }

        // e = e || window.event;
        // // dom2级绑定事件的取消默认操作的用法
        // if(e.preventDefault) {
        //   e.preventDefault();
        // } else {
        //   e.returnValue = false;
        // }

        // // 只兼容dom0级绑定事件的方式
        // return false;
      };
    }
  </script> 
</body>
</html>

 

源代码下载: https://github.com/godlikecheng/JavaScript_complete

上一篇: JS - BOM详解 -06

下一篇: 暂无.

 

猜你喜欢

转载自blog.csdn.net/qq_40820862/article/details/81780152