JS篇:比较详细的JS知识点--03

1、事件对象的常见的属性和方法
事件对象属性和方法说明
e.target返回触发的事件对象(标准)
e.srcElement返回触发的事件对象(非标准,IE6-8使用)
e.type返回事件类型,比如click,mouseover等,注意不带on开头
e.cancelBubble该属性阻止冒泡,非标准ie6-8使用
e.returnValue该属性阻止默认事件(默认行为,非标准ie6-8使用,比如不让链接跳转
e.preventDefault()该方法阻止默认事件(默认行为),标准,比如不让链接跳转
e.stopPropagation()阻止事件冒泡,标准
    <button>按钮1</button>
    <button>按钮2</button>
    <a href="http://baidu.com">百度</a>
    <script>

      var button = document.querySelectorAll("button");
      // 输出事件对象
      button[0].addEventListener("click", function (event) {
        console.log(event.target); //target意思是目标,获取元素button[0]
      });
      // 阻止默认行为,这里阻止a链接跳转到百度
      document.querySelector("a").onclick = function (e) {
        e.preventDefault();
      };
      // 阻止冒泡
      document.querySelectorAll("button")[1].onclick = function (e) {
        e.stopPropagation();
      };
      document.onclick = function () {
        console.log("如果存在事件冒泡,这里就会被触发");
      };
    </script>
2、DOM_e.target和this的区别
e.target指向的是触发事件的对象
this指向的是注册事件的对象
            
解释区分:如果注册事件是ul标签,然后因为事件冒泡原因,点击li标签后触发ul事件
这时e.target就是li,this就是ul标签

代码区分:

    <ul>
      <li>知否知否</li>
      <li>知否知否</li>
      <li>知否知否</li>
      <li>知否知否</li>
    </ul>
    <script>
      var ul = document.querySelector("ul");
      ul.addEventListener("click", function (e) {
        console.log(this); //返回的是绑定事件的对象,这里也就是ul元素
        console.log(e.target); //返回的是触发事件的对象或者理解成点击了谁,比如点击li就是li是触发事件的对象
      });
    </script>
3、事件委派
事件委托:事件委托也称为是事件代理,在jquery里面称为是事件委托

事件委托原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其共同的父元素上,然后利用事件冒泡的原理设置到每个子节点上

简单解释:给ul注册点击事件,利用事件对象的target来找到当前点击的li,因为点击li事件会冒泡到ul上,ul由注册事件就会被触发

事件委托的作用:只需要操作一次DOM,提高程序性能

    <ul>
      <li>知否知否,应是绿肥红瘦。</li>
      <li>知否知否,应是绿肥红瘦。</li>
      <li>知否知否,应是绿肥红瘦。</li>
    </ul>
    <script>
      var ul = document.querySelector("ul");
      ul.addEventListener("click", function (e) {
        console.log(e.target.innerText);
        e.target.style.backgroundColor = "red";
      });
    </script>
4、DOM_禁用右键菜单和禁用选中文字事件
contextmenu禁止鼠标右键菜单
selectstart禁止鼠标选中

    <p>我是一条程序指令</p>
    <script>
      var p = document.querySelector("p");
      p.addEventListener("contextmenu", function (e) {
        e.preventDefault(); //取消鼠标右键
      });
      p.addEventListener("selectstart", function (e) {
        e.preventDefault(); //取消鼠标选中
      });
    </script>
5、鼠标事件对象位置属性
鼠标事件对象位置属性说明
e.clientX返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX返回鼠标相对于文档页面的X坐标,IE9+支持
e.pageY返回鼠标相对于文档页面的Y坐标,IE9+支持
e.screenX返回鼠标相对于电脑屏幕的X坐标
e.screenY返回鼠标相对于电脑屏幕的Y坐标
      /* 鼠标相对于浏览器可视区的坐标 */
      document.addEventListener("click", function (e) {
        console.log("e.clientX: " + e.clientX);
        console.log("e.clientY: " + e.clientY);
        console.log("e.pageX: " + e.pageX);
        console.log("e.pageY: " + e.pageY);
        console.log("e.screenX: " + e.screenX);
        console.log("e.screenY: " + e.screenY);
      });
案例:

图片跟随鼠标的移动

    //需要定位
    <style>
      img {
        position: absolute;
        width: 100px;
      }
    </style>

    <img src="../images/4.webp" alt="" />
    <script>
      var img = document.querySelector("img");
      document.addEventListener("mousemove", function (e) {
        img.style.top = e.pageY + "px";
        img.style.left = e.pageX + "px";
        img.style.transform = "translate(-50%,-50%)";
        img.style.cursor = "none";
      });
    </script>
6、键盘事件
键盘事件
onkeyup 键盘按下又回弹触发事件,不区分大小写,尽量使用keyCode来获取ASCLL码值
onkeydown  键盘按下触发事件,不区分大小写
onkeypress  键盘按下触发事件,但是不是识别功能键,区分大小写

keypres识别大小写是根据keyCode属性识别的
keyup和keudown中的keyCode属性不能识别大小写,ASCLL码值一样的

三个的执行顺序是  keydown  keypress keyup

      // keyup和keydown键盘事件不能识别大小写
      document.addEventListener("keyup", function (e) {
        console.log(e.keyCode);
      });

      // 练习利用keyCode属性识别按键大小写
      document.addEventListener("keypress", function (e) {
        if (e.keyCode >= 65 && e.keyCode <= 90) {
          console.log(e.key + "\t" + e.keyCode);
          console.log("你输入的是大写");
        } else {
          console.log("你输入的可能是小写");
          console.log(e.key + "\t" + e.keyCode);
        }
      });
7、BOM_窗口加载事件(load DOMContentLoad)
窗口加载事件onload
  
注意点:如果是加载事件,可以将js代码放在元素前面(因为onload事件是页面加载完毕之后才执行的js代码)
       如果不是加载事件,如果使用事件委托形式,也可以放在元素前面
       如果要获取元素先,则此时需要放在元素后面

          window.addEventListener('load', function () {
              window.alert('我是别的内容加载完成后执行的事件');
          })

窗口加载事件
window.onload = function(){}
window.addEventListener('load',function(){})

window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件
(包括图像、脚本文件、css文件等数据),就调用的处理函数

注意:
1、有了window.onload就可以把js代码写在页面中标签元素的上方或者是下方,因为onload是等页面标签元素全部加载完毕之后才执行处理函数
2、window.onload传统注册事件的方式,只能写一次,如果存在多个,会以最后一个window.onload事件为准
3、如果需要写多个onload事件,使用addEventListener()注册事件的方式,没有次数限制

窗口加载事件
document.addEventListener('DOMContentLoad',function(){})
1、DOMContentLoad事件触发时,仅当DOM(文档对象模型,就是标签元素)加载完毕,不包括样式表、图片、falsh等
2、ie9以上版本才支持
3、如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoad时间比较合适使用
8、BOM_调整窗口大小事件
        调整窗口大小的事件onresize:调整窗口的大小的事件

        window.onresize=function(){}
        window.addEventListener('resize',function(){})
        window.onresize是调整窗口大小加载事件,当触发时就会调用的处理函数

        注意:
        只要窗口的大小发生像素变化,就会触发这个事件
        经常利用这个事件完成响应式布局,window.innerWidth来获取当前屏幕的宽度

     <script>
      window.onresize = function () {
        console.log("我变化了");
        console.log(window.innerWidth); //获取当前电脑屏幕的宽度
      };
    </script>
9、定时器
setTimeout()/setInterval()定时器
window.setTimeout(callback,延迟的毫秒数,传递给回调的参数);
setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数
注意:
1、window可以省略
2、这个调用函数可以直接写成函数,或者写函数名或者采取字符串形式'函数名()'三种形式,第三种不推荐使用
3、延迟的毫秒数省略默认是0,如果写,必须是毫秒
4、因为定时器可能有多个,所以经常给定时器一个标识符

setInterval()定时器
window.setInterval(callback,毫秒数)
setInterval()方法重复调用一个函数,每到这个时间,就调用一次函数
注意点和setTimeout()的一样

        // 停止setTimeout()定时器
        window.clearTimeout(timeoutID)

        // 停止setInterval()定时器
        window.clearInterval(timeoutID)

        // 如:
        let timer = window.setTimeout(callback,毫秒数);
        window.document.addEventListener('click'.function(){
            window.clearTimeout(timer);
        })
练习:

    <button>点击</button>
    <script>
      let timer = undefined;
      document.querySelector("button").onclick = function () {
        clearInterval(timer);
        timer = setInterval(
          (params) => {
            console.log(params);//{ a: 100, b: 200 }
          },
          1000,
          { a: 100, b: 200 }
        );
      };
    </script>
10、按钮的disabled 属性
disabled 属性为真表示可以禁止点击,为false表示可以点击 
    <button>点击</button>
    <script>
      const button = document.querySelector("button");
      button.onclick = function () {
        this.disabled = true;
        this.style.cursor = "move";
        setTimeout(() => {
          this.disabled = false;
          this.style.cursor = "default";
        }, 3000);
      };
    </script>
验证码案例:

    <input type="text" />
    <button>发送验证码</button>
    <script>
      const button = document.querySelector("button");
      const input = document.querySelector("input");
      let timer = undefined;
      let count = 3;
      button.onclick = function () {
        this.disabled = true;
        timer = setInterval(() => {
          count--;
          button.textContent = "请等待" + count + "秒";
          if (!count) {
            clearInterval(timer);
            this.disabled = false;
            button.textContent = "发送验证码";
            input.value = "1234";
            count = 3;
          }
        }, 1000);
      };
    </script>
11、window中this的指向的问题
这里是我自己的理解,如果有更好的说明,欢迎评论:

1、全局下function函数的调用后this的指向都是window
2、在全局下打印的this也是指向window
3、对象中,如果在对象的内部调用函数,普通函数的this指向的是对象
4、箭头函数中,this指向的是最近的一层具有完整function关键字的且调用了完整function关键字的对象

    <button>点击</button>
    <script>
      // 1、全局下调用的函数
      function func() {
        console.log(this, "func函数中的"); //window
      }
      func();

      // 定时器的箭头函数
      const button = document.querySelector("button");
      button.onclick = function () {
        setTimeout(() => {
          console.log(this, "这里是button点击事件中的"); //button
        }, 0);
      };

      // 全局下直接输出的this
      console.log(this, "全局下的"); //window

      // 普通对象上的箭头函数
      var obj = {
        name: "张三",
        sayHello() {  // 这里的完成写法是 sayHello:function(){}
          let obj1 = {
            play: () => {
              console.log(this, "obj中的"); //obj
            },
          };
          obj1.play();
        },
      };
      obj.sayHello();

      // 构造函数中的this
      function People(name, age) {
        this.name = name;
        this.age = age;
        this.sayHi = function () {
          console.log(this);//People
        };
      }

      var peo = new People("张三", 20);
      peo.sayHi();
    </script>
12、JS中同异步任务和执行机制
js是单线程
js语言的一大特点就是单线程执行,也就是说同一个时间点只能做一件事。这是因为js这门脚本语言诞生的使命所在,js是为了处理页面中用户的交互以及操作DOM而诞生的。某个DOM元素进行添加和删除操作,不能同时进行,先添加才能删除单线程意味着所有任务需要排队,前一个任务结束够才会执行下一个任务,这样导致如果js执行的时间过长,就会造成页面的渲染不连贯的问题导致页面加载阻塞。
同步和异步
为了解决页面渲染出现的阻塞问题,利用多核CPU计算能力,h5提出web worker标准,允许js脚本创建多个线程。于是js中出现了同步和异步任务。

同步:前一个任务执行结束,程序按照顺序执行下一个任务。
异步:同一个时间内可以做多件事

同步任务:都在主线程上执行,形成一个执行栈
异步任务:普通事件(click、resize等)  资源加载(load、error等)  定时器,包括setTimeout、setInterval等
js执行机制
1、先执行执行栈中的同步任务
2、异步任务(回调函数)放入任务队列中
3、一旦执行栈中的所有同步任务执行完毕之后,系统就会按照次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进行执行栈中开始执行。由于主线程不断的重复获取任务、执行任务、再获取任务,所以这种机制被称为是事件循环(event loop)
13、history对象
history 对象是浏览器提供的内置对象之一,它提供了与浏览器历史记录相关的功能。
通过 history 对象,您可以在浏览器窗口的会话历史记录中导航、管理浏览历史记录以及在不同页面之间进行前进和后退操作。

history.back():导航到上一个页面(相当于点击浏览器的后退按钮)。
history.forward():导航到下一个页面(相当于点击浏览器的前进按钮)。
history.go(n):在历史记录中导航到相对于当前页面的某个位置,其中 n 可以是正数(向前导航)或负数(向后导航)。

    // history后退.html文件
    <a href="./history前进.html">history后退</a>
    <button>后退</button>
    <script>
        var button = document.querySelector('button');
        button.addEventListener('click', function () {
            // history.back();
            history.go(-1);
        })
    </script>

    // history前进.html文件
    <a href="./history后退.html">history前进</a>
    <button>前进</button>
    <script>
        var button = document.querySelector('button');
        button.addEventListener('click', function () {
            // history.forward();
            history.go(1);
        })
    </script>
14、location对象
window对象给我们提供的一个location属性用来获取或设置窗体的URL,并且可以用于解析URL,
因为这个属性返回的是一个对象,所以我们将这个属性也成为location对象

console.log(window.location.href); //获取href(整个文件的地址)
URL:统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址,
互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
            
            URL的一般语法格式:
            protocol://host[:post]/path/[?query]#fragment
            http://www.itcast.cn/index.html?name=andy&age=18#link

            组成                说明
            protocol            通信协议,常用的http,ftp,maito等
            host                主机(域名),例如:www.itcast.cn
            port                端口号,可选,如果省略,http默认的端口是80
            path                路径,由零个或多个/符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
            query               参数,以键值对的形式,通过&符号分割开
            fragment            片段,#后面内容常见用于链接,锚点

            location的属性:
            location的属性          返回值
            location.href           获取或者设置吻技安的整个URL
            location.host           返回主机或者域名
            location.port           返回端口号,如果未写端口号,返回空字符串
            location.pathname       返回路径
            location.search         返回参数
            location.hash           返沪片段,#后面内容,常见于链接,锚点
location对象的方法:
location.assign()  跟href一样,可以跳转页面(也称为重定向页面),点击跳转之后还可以后退到之前的页面
location.replace()   替换当前页面,因为不记录历史,所以不能后退到之前的页面
location.reload()    重新加载页面,相当于刷新按钮或者f5键,如果参数是空,或者是false, 就只是单纯的刷新的意思,如果参数是true, 就是强制刷新的意思(ctrl_f5)

    <script>
      window.addEventListener("click", function () {
        // location.assign('http://baidu.com')//跳转,有后退功能
        location.replace("http://baidu.com"); //跳转,没有后退功能
        // location.reload()//加载页面,不跳转
      });
    </script>
15、navigator对象
navigator对象包含有关浏览器的信息,有很多属性,最常用的属性是userAgent, 该属性可以返回由客户机
发送到服务器的user - agent头部的值

下面前端代码可以解决判断用户哪个终端打开页面,实现跳转
if (navigator.userAgent.match(  /(phone|pad|pod|iphone|ipod|ios|ipad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Sybian|Windows Phone)/i)) {
   location.href = "#";// 移动端
} else {
   location.href = "#";// 客户端
}
16、PC端网页特效_offset偏移量
概述:offset翻译就是偏移量,使用offset相关属性可以动态的得到元素属性,
比如:位置(偏移),大小等获得元素距离带有定位父元素的位置,获得元素自身的大小(宽度和高度)
注意:返回的数值都不带单位

offset系列常见的属性:
属性                     作用
element.offsetParent     返回作为该元素带有定位的父元素,如果父级没有带定位,则结果返回是body
element.offsetTop        返回元素相对于带有定位的父元素上方的偏移量
element.offsetLeft       返回元素相对于带有定位的父元素左边框的偏移量
element.offsetWidth      返回自身包括padding  边框   内容去的宽度,返回的数值不带有单位
element.offsetHeight     返回自身包括padding  边框   内容去的高度,返回的数值不带有单位

    <div></div>
    <script>
      var div = document.querySelector("div");
      console.log(div.offsetParent);
      console.log(div.offsetHeight);
      console.log(div.offsetWidth);
      console.log(div.offsetTop);
      console.log(div.offsetLeft);
    </script>
17、offset和style的区别
offset和style的区别:

        offset
        offset可以得到任意样式表的样式值
        offset系列获得的数值是没有带单位的
        offsetWidth包含padding  边框   内容去的宽度
        offsetWidth等属性是只读属性,只能获取不能赋值,也改变不了
        所以想要获取元素大小,位置等属性,使用offset比较适合

        style
        style只能得到行内样式表的样式值(就是直接定义在标签中的样式)
        style.width获得的是带有单位的字符串
        style.width获得不包含padding 和 border 的值
        style.width是可读写属性,可以获取也可以改变
        所以想要给改变元素属性的值,使用style

     <div
      style="
        position: absolute;
        top: 100px;
        left: 100px;
        width: 200px;
        height: 200px;
        border: 10px solid red;
        padding: 50px;
        background-color: pink;
        margin: 100px auto;
      "
    ></div>
    <script>
      var div = document.querySelector("div");
      console.log(div.offsetHeight);
      console.log(div.offsetWidth);

      // 因为offset输出的结果中有包含padding   border   的值,所以结果相比style要大
      console.log(div.offsetTop);
      console.log(div.offsetLeft);

      console.log("_________________");

      // style输出的结果中没有包含padding   border   的值
      console.log(div.style.height);
      console.log(div.style.width);

      // 如果行内样式表中没有定义的属性,输出是为空
      console.log(div.style.top);
      console.log(div.style.left);
      console.log(div.style.backgroundColor);
      div.style.backgroundColor = "red";
      console.log(div.style.backgroundColor);
    </script>
案例:

    <div
      style="
        position: absolute;
        top: 100px;
        left: 100px;
        width: 100px;
        height: 100px;
        background-color: red;
      "
    ></div>
    <script>
      var div = document.querySelector("div");
      window.addEventListener("click", function (e) {
        console.log("鼠标点击模块中的坐标是");
        console.log(e.pageX - div.offsetLeft);
        console.log(e.pageY - div.offsetTop);
      });
    </script>
案例:

<!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>
  </head>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    h2 {
      text-align: center;
      cursor: pointer;
    }

    .bg {
      display: none;
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      right: 0;
      background-color: rgba(0, 0, 0, 0.3);
    }

    form {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 400px;
      height: 240px;
      border-radius: 5px;
      background-color: #fff;
      padding: 30px 30px;
      cursor: default;
    }

    form .close {
      position: absolute;
      width: 40px;
      height: 36px;
      line-height: 36px;
      text-align: center;
      border-radius: 50%;
      outline: none;
      border: 0;
      top: -18px;
      right: -20px;
    }

    form .top {
      font-size: 20px;
      font-weight: 500;
      text-align: center;
    }

    form label {
      display: block;
      text-align: right;
    }

    form label input {
      outline: none;
      border: 1px solid #999;
      width: 260px;
      height: 36px;
      margin-top: 20px;
      border-radius: 5px;
      color: #999;
      padding-left: 20px;
    }

    form .login {
      display: block;
      width: 200px;
      height: 30px;
      color: #000;
      font-weight: 500;
      outline: none;
      border: 1px solid #999;
      border-radius: 5px;
      margin: 20px auto;
      background-color: #fff;
    }
  </style>
  <body>
    <h2>点击,弹出模态框</h2>
    <div class="bg">
      <form action="#" class="input_box">
        <button class="close">关闭</button>
        <div class="top">登录会员</div>
        <label
          >用户名:<input type="text" name="user" placeholder="请输入你的账号"
        /></label>
        <label
          >登录密码:<input
            type="password"
            name="pwd"
            placeholder="请输入你的密码"
        /></label>
        <button class="login">登录会员</button>
      </form>
    </div>
    <script>
      const h2 = document.querySelector("h2");
      const bg = document.querySelector(".bg");
      const close = document.querySelector(".close");
      const form = document.querySelector("form");
      h2.addEventListener("click", function () {
        bg.style.display = "block";
        form.style.display = "block";
        close.addEventListener("click", function () {
          form.style.display = "none";
          bg.style.display = "none";
        });
        form.addEventListener("mousedown", function (e1) {
          this.style.cursor = "move";
          const click_x = e1.pageX - this.offsetLeft;
          const click_y = e1.pageY - this.offsetTop;
          document.addEventListener("mousemove", move);
          function move(e2) {
            form.style.top = e2.pageY - click_y + "px";
            form.style.left = e2.pageX - click_x + "px";
          }
          document.addEventListener("mouseup", function () {
            this.removeEventListener("mousemove", move);
          });
        });
      });
    </script>
  </body>
</html>
18、三大系列_scrollWidth_offsetWidth_clientWidth
element.offsetWidth    返回自身包括padding、边框、内容区的宽度,返回值不带单位
element.clientWidth    返回自身包括padding、内容区的宽度,不包括边框,返回值不带单位
element.scrollWidth    返回自身内容区的宽度,不包括padding和边框,返回值不带单位

补充:
Element.scrollWidth 这个只读属性是元素内容宽度的一种度量,包括由于 overflow 溢出而在屏幕上不可见的内容。

  <style>
    div {
      width: 140px;
      height: 140px;
      background-color: pink;
      border: 10px solid red;
      padding: 10px;
    }
  </style>

    <div></div>
    <script>
      window.addEventListener("load", function () {
        var div = document.querySelector("div");
        console.log(div.offsetWidth); //160    width   padding   border-width
        console.log(div.clientWidth); //140    width   padding
        console.log(div.scrollWidth); //140
        // 如果元素的内容可以适合而不需要水平滚动条,则其scrollWidth等于clientWidth
      });
    </script>
19、PC端网页特效_scroll属性
scoll翻译就是滚动,使用scoll系列的相关属性可以动态的得到该元素的大小、滚动距离等

scoll系列属性               作用
element.scollTop            返回被卷去的上侧距离,返回数值不带单位
element.scollLeft           返回被卷去的左侧距离,返回数值不带单位
element.scollWidth          返回自身实际的宽度,不含边框,返回数值不带单位
element.scollHeight         返回自身实际的高度,不含边框,返回数值不带单位
案例分析:
    需要用到页面滚动事件scroll因为是页面滚动,所以事件源是document
    滚动到某个位置,就是判断页面被卷去的上部值
    页面被卷去的头部:可以通过window.pageYOffset获得,如果是被卷去的左侧window.pageXOffset
    注意:元素被卷去的头部是element.scrollTop,如果是页面被卷去的头部则是window.pageYOffset

页面被卷去的头部兼容性问题解决方案 :
    需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常由如下几种写法:
    1、声明了DTD:   使用document.documentElement.scrollTop
    2、未声明DTD:   使用document.body.scrollTop
    3、新方法DTD:   使用window.pageYOffset,ie9开始支持
上下移动的导航栏

<!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>
  </head>
  <body>
    <div class="div">
      <div class="header w">header</div>
      <div class="banner w">banner</div>
      <div class="main w">main</div>
    </div>
    <div class="slider-bar">
      <div class="goback">返回</div>
    </div>
    <script>
      window.addEventListener("load", function () {
        const sbar = document.querySelector(".slider-bar");
        document.addEventListener("scroll", function () {
          if (window.pageYOffset >= 200) {
            sbar.style.display = "block";
            sbar.style.position = "fixed";
          } else {
            sbar.style.display = "none";
          }
        });
        sbar.addEventListener("click", function () {
          animate(window, 0);
          function animate(object, targetlocation, callback) {
            fun();
            clearInterval(object.timer);
            object.timer = setInterval(fun, 10);
            function fun() {
              let step = (targetlocation - window.pageYOffset) / 10;
              step = step > 0 ? Math.ceil(step) : Math.floor(step);
              window.scroll(0, window.pageYOffset + step);
              if (step == 0) {
                clearInterval(object.timer);
                callback && callback();
              }
            }
          }
        });
      });
    </script>
  </body>
  <style>
    .div {
      width: 80%;
      position: absolute;
      top: 0;
    }
    .header {
      background-color: pink;
    }

    .banner {
      background-color: red;
    }

    .main {
      background-color: skyblue;
    }

    .w {
      width: 100%;
      height: 400px;
      text-align: center;
      line-height: 400px;
      margin-top: 20px;
    }
    .slider-bar {
      position: absolute;
      top: 300px;
      right: 100px;
      display: none;
    }

    .goback {
      width: 50px;
      height: 50px;
      text-align: center;
      line-height: 50px;
      background-color: lightgreen;
    }
  </style>
</html>
左右移动的导航栏

<!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>
  </head>

  <body>
    <div class="box">
      <div class="div">我是左右移动栏</div>
      <span>--></span>
    </div>
    <script>
      var span = document.querySelector("span");
      var div = document.querySelector(".div");
      span.addEventListener("mouseenter", function () {
        animate(div, -160, function () {
          span.innerHTML = "-->";
        });
      });
      span.addEventListener("mouseout", function () {
        animate(div, 0, function () {
          span.innerHTML = "<--";
        });
      });
      function animate(object, targetLocation, callback) {
        clearInterval(object.timer);
        fun();
        object.timer = setInterval(fun, 20);
        function fun() {
          let step = (targetLocation - object.offsetLeft) / 10;
          step = step > 0 ? Math.ceil(step) : Math.floor(step);
          object.style.left = object.offsetLeft + step + "px";
          if (step == 0) {
            clearInterval(object.timer);
            callback && callback();
          }
        }
      }
    </script>
  </body>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .box {
      position: absolute;
      right: 40px;
      top: 300px;
    }

    span {
      position: absolute;
      top: 0;
      left: 0;
      display: inline-block;
      width: 40px;
      height: 40px;
      background-color: pink;
      text-align: center;
      line-height: 40px;
      color: #000;
    }

    .div {
      position: absolute;
      top: 0;
      left: 0;
      font-size: 10px;
      width: 200px;
      height: 40px;
      background-color: red;
      text-align: center;
      line-height: 40px;
    }
  </style>
</html>
19、bootstrap轮播图

JavaScript 插件 · Bootstrap v3 中文文档 | Bootstrap 中文网

20、自定义的轮播图
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <style>
    .box,
    .child,
    .fa-box,
    ul,
    li {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .fa-box {
      width: 400px;
      height: 300px;
      background-color: red;
      position: absolute;
      top: 100px;
      left: 50%;
      transform: translateX(-50%);
      overflow: hidden;
    }
    .box {
      position: absolute;
      top: 0;
      left: 0;
      display: flex;
    }

    .child {
      width: 400px;
      height: 300px;
      float: left;
    }

    .first {
      background-color: pink;
    }
    .second {
      background-color: skyblue;
    }
    .third {
      background-color: lightgreen;
    }

    .pot {
      position: absolute;
      bottom: 20px;
      left: 50%;
      transform: translateX(-50%);
      display: flex;
    }

    li {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      background-color: #fff;
      list-style: none;
      margin: 0 5px;
    }

    .active {
      background-color: #999;
    }

    button {
      outline: none;
      border: 0;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      width: 30px;
      height: 40px;
      background-color: transparent;
      color: #fff;
      font-size: 20px;
    }

    button:hover {
      background-color: rgba(0, 0, 0, 0.3);
    }

    .left {
      border-top-right-radius: 5px;
      border-bottom-right-radius: 5px;
      left: 0;
    }

    .right {
      border-top-left-radius: 5px;
      border-bottom-left-radius: 5px;
      right: 0;
    }
  </style>
  <body>
    <div class="fa-box">
      <div class="box">
        <div class="child first"></div>
        <div class="child second"></div>
        <div class="child third"></div>
      </div>
      <ul class="pot"></ul>
      <button class="left">></button>
      <button class="right"><</button>
    </div>
    <script>
      const child = document.querySelectorAll(".child");
      const ul = document.querySelector(".pot");
      const box = document.querySelector(".box");
      const faBox = document.querySelector(".fa-box");
      // 动态生成小点
      for (let i = 0; i < child.length; i++) {
        const li = document.createElement("li");
        ul.appendChild(li);
        li.setAttribute("data-index", i + 1);
      }
      const li = document.querySelectorAll("li");
      li[0].classList.add("active");

      // 一开始就开启定时器
      Window.timer = setInterval(() => {
        button[0].click();
      }, 1000);

      // 给每个小点绑定点击事件
      for (let i = 0; i < li.length; i++) {
        li[i].addEventListener("click", function () {
          index = this.getAttribute("data-index") - 1;
          liIndex = index;
          console.log(index);
          for (let i = 0; i < li.length; i++) {
            li[i].classList.remove("active");
          }
          li[liIndex].classList.add("active");
          animate(box, -faBox.offsetWidth * index);
        });
      }

      // 克隆第一张图片
      const first = box.children[0].cloneNode(true);
      box.appendChild(first);
      first.setAttribute(
        "data-index",
        box.children[0].getAttribute("data-index")
      );

      const button = document.querySelectorAll("button");
      // 切换图片的index
      let index = 0;
      // 切换小点的liIndex
      let liIndex = 0;

      // 点击左按钮切换
      button[0].addEventListener("click", function () {
        // 当切换到最后一张,立刻切换到第一张,这里不使用动画
        if (index == child.length) {
          index = 0;
          box.style.left = "0px";
        }
        index++;
        liIndex++;
        // 判断当小点达到最后一个时切换到第一个
        if (liIndex == li.length) {
          liIndex = 0;
        }
        // 排他思想渲染小点样式
        for (let i = 0; i < li.length; i++) {
          li[i].classList.remove("active");
        }
        li[liIndex].classList.add("active");
        // 动画函数,动画切换
        animate(box, -index * faBox.offsetWidth);
      });

      // 点击右按钮切换图片
      button[1].addEventListener("click", function () {
        // 当切换到第一张时,立刻切换到最后一张
        if (index == 0) {
          index = child.length;
          box.style.left = -index * faBox.offsetWidth + "px";
        }
        index--;
        liIndex--;
        if (liIndex < 0) {
          liIndex = 2;
        }
        for (let i = 0; i < li.length; i++) {
          li[i].classList.remove("active");
        }
        li[liIndex].classList.add("active");
        animate(box, -index * faBox.offsetWidth);
      });

      // 鼠标进入faBox时,使用事件委托,触发faBox的mouseover来停止定时器
      faBox.addEventListener("mouseover", function () {
        // 停止定时器执行
        clearInterval(Window.timer);
        // 标记定时器为停止
        Window.timer = null;

        // 鼠标离开重新开启定时器
        faBox.addEventListener("mouseout", function () {
          // 先清除一次再开启,避免多次开启定时器
          clearInterval(Window.timer);
          Window.timer = null;
          Window.timer = setInterval(() => {
            button[0].click();
          }, 1000);
        });
      });

      // 封装的动画函数,使图片切换更柔和
      function animate(object, targetLocation, callback) {
        clearInterval(object.timer);
        fun();
        object.timer = setInterval(fun, 10);
        function fun() {
          let step = (targetLocation - object.offsetLeft) / 10;
          step = step > 0 ? Math.ceil(step) : Math.floor(step);
          object.style.left = object.offsetLeft + step + "px";
          if (step == 0) {
            clearInterval(object.timer);
            callback && callback();
          }
        }
      }
    </script>
  </body>
</html>

后续前往CSDN

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值