JavaScript 内容总结(PC端网页特效)(一)

JavaScript 内容总结(JavaScript高级程序设计)

  1. 元素偏移量offset系列
  2. 元素可视区client系列
  3. 元素滚动scroll系列
  4. 动画函数封装
  5. 常见的网页特效案例
1.元素偏移量offset系列
  • 动态的得到该元素的位置(偏移量)、大小等

    1. 获得元素距离带有定位父元素的位置
    2. 获得元素自身得大小(宽度高度)
    3. 返回数值不带单位
  • offset常见属性

    在这里插入图片描述

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        * {
          margin: 0;
          padding: 0;
        }
    
        .father {
          position: relative;
          width: 200px;
          height: 200px;
          background-color: rgb(175, 81, 175);
          margin: 100px;
        }
    
        .son {
          width: 100px;
          height: 100px;
          background-color: rgb(187, 105, 105);
          margin: 25px;
          /* 存在父元素塌陷问题 */
        }
    
        .sson {
          width: 50px;
          height: 50px;
          background-color: rgb(145, 187, 105);
          margin: 25px;
          padding: 5px;
       /* box-sizing: border-box; 不会撑大盒子*/
        }
      </style>
    </head>
    
    <body>
      <div class="father">
        <div class="son">
          <div class="sson"></div>
        </div>
      </div>
      <script>
        var father = document.querySelector('.father');
        var son = document.querySelector('.son');
        var sson = document.querySelector('.sson');
        console.log(father.offsetTop);//100
        console.log(father.offsetLeft);//100
        //它以带有定位的父亲为准 如果没有父亲则以body为主,或者父亲没有定位则一直想上找到有定位的父元素,以它为准
        console.log(son.offsetTop);//0
        console.log(son.offsetLeft);//25
        console.log(sson.offsetTop);//0
        console.log(sson.offsetLeft);//50
        console.log(sson.offsetWidth);//60
      </script>
    </body>
    
    </html>
    

    offset和style区别:

在这里插入图片描述

  • 案例:模态框拖拽

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        .father {
          position: absolute;
          width: 300px;
          height: 200px;
          left: 500px;
          top: 200px;
          background-color: rgb(255, 228, 196);
          display: none;
        }
    
        .close {
          position: absolute;
          top: -10px;
          right: -10px;
          background-color: rgb(255, 228, 196);
          width: 20px;
          height: 20px;
          font-size: 9px;
          border-radius: 10px;
          border: 1px solid silver;
          line-height: 20px;
          text-align: center;
          cursor: pointer;
        }
      </style>
    </head>
    
    <body>
      <button>点击</button>
      <div class="father">
        <div class="close">关闭</div>
      </div>
      <script>
        var button = document.querySelector('button');
        var father = document.querySelector('.father');
        var close = document.querySelector('.close');
        button.addEventListener('click', () => {
          document.body.style.backgroundColor = 'silver'
          father.style.display = 'block';
        });
        close.addEventListener('click', () => {
          father.style.display = 'none';
          document.body.style.backgroundColor = '#fff'
        });
        father.addEventListener('mousedown', (e) => {
    
          var x = e.pageX - father.offsetLeft;
          var y = e.pageY - father.offsetTop;
    
          function zz(e) {
            father.style.left = (e.pageX - x) + 'px';
            father.style.top = (e.pageY - y) + 'px';
          }
          document.body.addEventListener('mousemove', zz);
          document.body.addEventListener('mouseup', () => {
          document.body.removeEventListener('mousemove', zz);
          });
        });
      </script>
    </body>
    
    </html>
    
2.元素可视区client系列
  • 获取元素可视区的相关信息,通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等

在这里插入图片描述

  • 立即执行函数:不需要调用,立马能够自己执行的函数

    好处:独立作用域,避免命名冲突,执行后销毁,常用于解决闭包

3.元素滚动scroll系列
  • 可以动态的得到该元素的大小、滚动距离等

在这里插入图片描述

  • 仿淘宝侧边栏案例:window.pageYOffset:动态获取页面滚动距离

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
    <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        * {
          padding: 0;
          margin: 0;
        }
    
        .header {
          width: 80%;
          height: 400px;
          background-color: red;
        }
    
        .center {
          width: 80%;
          height: 800px;
          background-color: purple;
        }
    
        .righttab {
          position: absolute;
          right: 220px;
          top: 481px;
          width: 50px;
          height: 200px;
          background-color: rgb(207, 111, 207);
        }
    
        .footer {
          width: 80%;
          height: 800px;
          background-color: green;
        }
      </style>
    </head>
    
    <body>
      <div class="header"></div>
      <div class="center"></div>
      <div class="righttab"></div>
      <div class="footer"></div>
      <script>
        var header = document.querySelector('.header');
        var righttab = document.querySelector('.righttab');
        var righttab_top = righttab.offsetTop;
        document.addEventListener('scroll', () => {
          //console.log(window.pageYOffset);
          if (window.pageYOffset > header.clientHeight) {
            righttab.style.position = 'fixed';
    
            righttab.style.top = (righttab_top - header.clientHeight) + 'px';
          }
          else {
            righttab.style.position = 'absolute';
            righttab.style.top = righttab_top + 'px';
          }
        });
      </script>
    </body>
    
    </html>
    

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

4.动画函数封装
  • 动画实现原理

    核心原理:通过定时器setInterval()不断移动盒子位置

    实现步骤:

    1. 获得盒子当前位置
    2. 让盒子在当前位置加上1个移动距离
    3. 利用定时器不断重复这个操作
    4. 加一个结束定时器的条件
    5. 此元素加定位
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=<device-width>, initial-scale=1.0">
      <title>Document</title>
      <style>
        .box {
          position: absolute;
          width: 100px;
          height: 100px;
          background-color: red;
        }
      </style>
    </head>
    
    <body>
      <div class="box"></div>
      <script>
        var box = document.querySelector('.box');
        var time = setInterval(() => {
          if (box.offsetLeft + 1 == 500) {
            clearInterval(time);
          }
          box.style.left = (box.offsetLeft + 1) + 'px';
        }, 15);
      </script>
    </body>
    
    </html>
    
  • 简单动画函数封装

    参数:动画对象,最大移动距离,步长

      <script>
        var box = document.querySelector('.box');
        var box1 = document.querySelector('.box1');
        function move(obj, mixlenght, step) {
          var time = setInterval(() => {
            if (obj.offsetLeft +step == mixlenght) {
              clearInterval(time);
            }
            obj.style.left = (obj.offsetLeft + step) + 'px';
          }, 15);
        }
        move(box, 300, 2);
        move(box1, 400, 1);
      </script>
    
  • 动画函数给不同元素记录不同定时器

      <script>
        var box = document.querySelector('.box');
        var box1 = document.querySelector('.box1');
        function move(obj, mixlenght, step) {
          obj.time = setInterval(() => {
            clearInterval(obj.time);
            if (obj.offsetLeft + step == mixlenght) {
              clearInterval(obj.time);
            }
            obj.style.left = (obj.offsetLeft + step) + 'px';
          }, 15);
        }
        move(box, 300, 2);
        move(box1, 400, 1);
      </script>
    
  • 缓动动画:让元素运动速度有所变化,最常见的是让速度慢慢停下来

    1. 让盒子每次移动的距离慢慢变小,速度就会慢慢落下来
    2. 核心算法:(目标值-现在的位置)/10 作为每次移动的距离步长
    3. 停止的条件:让当前的盒子位置等于目标位置就停止定时器
    4. 注意步长值取整
      <script>
        var box = document.querySelector('.box');
        var box1 = document.querySelector('.box1');
        function move(obj, mixlenght) {
          obj.timer = setInterval(() => {
            var step = Math.ceil((mixlenght - obj.offsetLeft) / 10);//核心算法
            if (obj.offsetLeft == mixlenght) {
              clearInterval(obj.timer);
            }
            obj.style.left = (obj.offsetLeft + step) + 'px';
          }, 15);
        }
        move(box, 300);
        move(box1, 400);
      </script>
    
  • 缓动动画:多个值之间缓动

    <script>
        var box = document.querySelector('.box');
        var box1 = document.querySelector('.box1');
        function move(obj, mixlenght, callback) {
          obj.timer = setInterval(() => {
            var step = (mixlenght - obj.offsetLeft) / 10;
            step = step > 0 ? Math.ceil(step) : Math.floor(step);//多个值之间缓动
            if (obj.offsetLeft == mixlenght) {
              clearInterval(obj.timer);
              callback();
            }
            obj.style.left = (obj.offsetLeft + step) + 'px';
          }, 15);
        }
        move(box, 300, () => { console.log(11); });
        move(box1, 400, () => { console.log(11); });
      </script>
    
  • 缓动动画加回调函数

    原理:函数可以作为一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数,这个过程就叫做回调

      <script>
        var box = document.querySelector('.box');
        var box1 = document.querySelector('.box1');
        function move(obj, mixlenght, callback) {
          obj.timer = setInterval(() => {
            var step = (mixlenght - obj.offsetLeft) / 10;
            step = step > 0 ? Math.ceil(step) : Math.floor(step);
            if (obj.offsetLeft == mixlenght) {
              clearInterval(obj.timer);
              callback();//回调函数
            }
            obj.style.left = (obj.offsetLeft + step) + 'px';
          }, 15);
        }
        move(box, 300, () => { console.log(11); });
        move(box1, 400, () => { console.log(11); });
      </script>
    
  • 动画函数封装到单独JS文件里面

    1. 单独新建一个JS文件
    2. 引入

    animate.js

    //缓动动画
    function move(obj, mixlenght, callback) {
      obj.timer = setInterval(() => {
        var step = (mixlenght - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == mixlenght) {
          clearInterval(obj.timer);
          // if (callback) { callback(); }
          callback && callback();
        }
        obj.style.left = (obj.offsetLeft + step) + 'px';
      }, 15);
    }
    
5.常见的网页特效

轮播图案例:

html

 <div class="focus">
        <a href="javascript:;" class="left_btn">&lt;</a>
        <ul>
          <li>
            <img src="upload/focus1.jpg" alt="">
          </li>
          <li>
            <img src="upload/focus2.jpg" alt="">
          </li>
          <li>
            <img src="upload/focus3.jpg" alt="">
          </li>
          <li>
            <img src="upload/focus4.jpg" alt="">
          </li>
        </ul>
        <a href="javascript:;" class="right_btn">&gt;</a>
        <div class="circle">
          <ol>
            <!-- <li class="check"></li> -->
          </ol>
        </div>
      </div>

css

.main .focus{
  position: relative;
  width: 721px;
  height: 455px;
  float: left;
  overflow: hidden;
}
.main .focus .left_btn,
.main .focus .right_btn{
  position: absolute;
  top: 50%;
  margin-top: -20px;
  width: 24px;
  height: 40px;
  background: rgba(0, 0, 0, .3);
  text-align: center;
  line-height: 40px;
  font-size: 18px;
  color: white;
}
.main .focus .right_btn{
  right: 0;
  border-radius: 50% 0 0 50%;
  display: none;
  z-index: 1;
}
.main .focus .left_btn{
  border-radius: 0 50% 50% 0 ;
  display: none;
  z-index: 1;
}
.main .focus ul{
  position: absolute;
  width: 500%;
}
.main .focus ul li{
  float: left;
}
.main .focus .circle {
  position: absolute;
  bottom: 2px;
  left: 325px;
}
.main .focus .circle li {
  float: left;
  width: 10px;
  height: 10px;
  border: 2px solid rgba(255, 255, 255, 0.5);
  margin: 0 3px;
  border-radius: 50%;
  cursor: pointer;
}
.main .focus .circle .check{
  background-color: #fff;
}

js

// 轮播图
var focus = document.querySelector('.focus');
var right_btn = document.querySelector('.right_btn');
var left_btn = document.querySelector('.left_btn');

//解决左右按钮显隐问题
focus.addEventListener('mouseenter', function () {
  right_btn.style.display = 'block';
  left_btn.style.display = 'block';
  //清除定时器
  clearInterval(timer);
})
focus.addEventListener('mouseleave', function () {
  right_btn.style.display = 'none';
  left_btn.style.display = 'none';
  //开启定时器
  timer = setInterval(() => {
    right_btn.click();//手动调用点击事件
  }, 2000);
})
var circle = document.querySelector('.circle')
var focus_ol = circle.querySelector('ol')
var focus_ul = focus.querySelector('ul')
//根据图片生成小圆圈
for (let i = 0; i < focus_ul.children.length; i++) {
  var img_width = focus_ul.children[i].clientWidth;
  let li = document.createElement('li');
  focus_ol.appendChild(li);
  focus_ol.children[i].setAttribute('data_index', i);
}
//克隆图片 便于无缝连接
var img_first = focus_ul.children[0].cloneNode(true);
focus_ul.appendChild(img_first);
//圆圈底色及图跟着圆圈走
for (let i = 0; i < focus_ol.children.length; i++) {
  focus_ol.children[0].className = 'check';
  focus_ol.children[i].addEventListener('click', () => {
    //干掉其他人
    for (let i = 0; i < focus_ol.children.length; i++) {
      focus_ol.children[i].className = '';
    }
    //留下我自己
    focus_ol.children[i].className = 'check';
    //图跟着圆圈走
    move(focus_ul, -(i * img_width));
    var index = focus_ol.children[i].getAttribute('data_index');
    //圈圈跟着左右按钮走
    num = index;
  })
}
//有变量提升不怕
//按钮控制图片
var num = 0;
var flag = true;//节流阀
right_btn.addEventListener('click', () => {
  if (flag) {
    flag = false;
    if (num >= focus_ul.children.length - 1) {
      num = 0;
      focus_ul.style.left = '0px';
    }
    num++;
    move(focus_ul, -(num * img_width), () => { flag = true });
    paita();
  }
})
left_btn.addEventListener('click', () => {
  if (flag) {
    flag = false;
    if (num == 0) {
      num = focus_ul.children.length - 1;
      focus_ul.style.left = (-num * img_width) + 'px';
    }
    num--;
    move(focus_ul, -num * img_width, () => { flag = true });
    paita();
  }
})
//提取公共函数
function paita() {
  for (let i = 0; i < focus_ol.children.length; i++) {
    focus_ol.children[i].className = '';
  }
  //留下我自己
  if (num == focus_ul.children.length - 1) {
    focus_ol.children[0].className = 'check';
  }
  else {
    focus_ol.children[num].className = 'check';
  }
}
//自动轮播
var timer = setInterval(() => {
  right_btn.click();//手动调用点击事件
}, 2000);
  • 节流阀:防止轮播图按钮连续点击造成的播放过快

    目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续播放

    核心思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

    if(flag){flag=false;do something};关闭水龙头

    利用回调函数 动画执行完毕,flag=true;打开水龙头

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值