JavaScript详解

一、快速入门

1.JavaScript的两种引入方式

方式一:直接在html里面写 目的:实现简单的弹窗
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--script标签内,写JavaScript代码,可以放在head标签里,也可以放在body标签里-->
    <script>
        <!--弹窗,打开页面时弹出一个窗口,并显示有hello,world-->
        alert('hello,world');
    </script>
</head>
<body>

</body>
</html>
运行结果图


方式二:新建一个js文件,在HTML中连接该文件也可以实现,就像css一样和HTML分开


注意script标签必须是成对出现,

2.基本语法

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--Javascript严格区分大小写-->
    <script>
        //单行与多行注释与Java中注释的方式一样
        /*1.定义变量  变量类型  变量名 = 变量值;*/
        var score =100;//这里不写分号也没事
        var name = "twq";//这里不写var也没事,就算不写变量名都可以,是不感觉可以随心所欲了
        if(score>60 && score <70){
            alert('小子,你很危险呀');
        }else if(score > 70 && score < 80){
            alert('革命尚未成功,同学  仍需努力呀!!');
        }else{
            alert('不要骄傲哦!');
        }
    </script>
</head>
<body>

</body>
</html>

调试方法

参照下图:

3.数据类型

(1)number

js不区分小数和整数,Number
点击查看代码
123//整数123
123.1//浮点数123.1
1.123e3//科学计数法
-99//负数
NaN//not a number
Infinity//表示无限大

界面在浏览器上运行结果图

(2)字符串

和Java的一样

(长度str.length)

(3)布尔值

(4)逻辑运算

① && 两个都为真,结果为真
② | | 一个为真,结果为真
③ !真即假,假即真
逻辑中断

逻辑与


语法:表达式1&&表达式2
如果第一个表达式的值为真,则返回表达式2


如果第一个表达式的值为假,则返回表达式1

语法: 表达式1 || 表达式2


如果第一个表达式的值为真,则返回表达式1


如果第一个表达式的值为假,则返回表达式2

(5)比较运算符

① = 赋值
② == 等于(类型不一样,值一样,也会判断为true)
③ === 绝对等于(类型一样,值一样结果为true)
注意:这是Java的一个缺陷,坚决不要使用==比较

须知:

  • NaN===NaN,这个与所有的数值都不相等,包括自己
  • 只能通过isNaN(NaN)来判断这个数据是否是NaN

(6)浮点数

尽量避免使用浮点数进行运算,存在精度问题!

(7)数组

java的数值必须是相同类型的对象,JS中需不要这样!


如果数组下标越界会报undefined

(8)对象

对象是大括号,数组是中括号 每个属性之间用逗号隔开,最后一个属性之后不需要逗号
点击查看代码
<script>
        console.log((1/3)===(1-2/3));
        console.log(Math.abs(1/3-(1-2/3))<0.00000001);
        //保证代码的可读性,尽量使用[]
        var arr=[1,2,3,4,5,'hello',null,true];
        new Array(1,12,3,4,5,'hello');
        var person ={
            name:"Twq",
            age:23,
            tags:['js','java','web','...']
        }

    </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>
    <script>
        var num = 10;
        console.log(typeof num) //number
        //prompt得到的值为字符类型
        var age = prompt("输入年龄")
        console.log(typeof age) //string

        //转化为字符串
        var num = 10
        console.log(typeof num) //number
        console.log(typeof num.toString()) //string
        var a = 1
        console.log(typeof String(a)) //string

        //转换为数字类型
        var a = '3.14'
        console.log(typeof num) //string
        console.log(typeof parseInt(a)) //number,并且a的值为3,直接取整
        console.log(parseInt('120px')) //会去掉px
        console.log(parseInt('as120px')) //NaN

        console.log(parseFloat('3.14')) //3.14
        console.log(parseFloat('120px')) //会去掉px
        console.log(parseFloat('as120px')) //NaN

        //
    </script>
</head>

<body>

</body>

</html>

4.严格检查模式

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        /*前提是IDEA需要设置支持ES6语法
        *'use strict'严格检查模式,预防Javascript的随意性导致产生的一些问题如:
        *       ①定义变量不写变量类型在没有写严格检查时不会报错,但是加上这严格检查之后就会报错
        * 必须要写在JS的第一行
        * 局部变量建议都使用let去定义 */
        'use strict';
        /*let是块作用域,就会好比在for循环里用let定义了一个块变量
        在循环的外部则无法使用该变量,var是函数作用域,在循环里面定义的
        变量在循环外面也可以可以访问*/
        let i = 1;
    </script>
</head>
<body>
</body>
</html>

二、详解数据类型

1.字符串

(1)正常字符串,我们使用单引号或者双引号包裹

(2)注意转义字符

①\'
②\n
③\u4e2d   unicode字符格式:\u####

④\41  Ascll字符

(3)多行字符串编写

(4)模板字符串

点击查看代码
<script>
        //tab 上面 esc下面
        let name = "Twq";
        var msg =`你好呀,${name}`//在Java中连接两个字符串用加号,二JS可以使用$符号连接
    </script>
运行结果图

(5)字符串长度

(6)字符串内容的不可变性

(7)大小写转换

(8)查找

(9)substring

2.数组

(1)长度

Array可以包含任意的数据类型


注意:假如给arr.length赋值,数组大小就会发生变化,如果赋值过小,元素就会丢失

(2)indexOf,通过元素获得下标索引


在数组里字符串的1和数字1是不同的

(3)slice()

截取Array的一部分,返回一个新数组,类似于String中的substring

(4)尾部压入和弹出push(),pop()

从尾部压入和弹出元素

(5)unshift(),shift()

unshift()压入到头部 shift()弹出头部的第一个元素

(6)sort()

(7)元素反转

(8)concat()


注意:concat()并没有修改原来的数组的值,只是会返回一个新的数组

(9)连接符join

打印拼接数组,使用特定的字符串连接

(10)多维数组

3.对象

(1).使用一个不存在的对象属性,不会报错!undefined

(2)动态的删减属性

(3)动态的添加属性

(4)判断属性值是否在这个对象中

(5)判断一个属性是否是这个对象自身拥有的hasOwnProperty()

4.Map和Set

(1)Map

点击查看代码
 <script>
        var map = new Map([['tom',100],['jack',900],['haha',80]])
        console.log(map.get('jack'))
        map.set('admin',90);//新增或修改
        map.delete('tom');//删除
        for(let x of map){
            console.log(x)
        }
    </script>
运行结果图

(2)Set

无序不重复的集合
点击查看代码
 <script>
        var set = new Set([1,1,1,3]);
        set.add(2);//添加一个元素
        set.delete(3);//删除一个元素
        for(let x of set){
            console.log(x)
        }
        console.log(set.has(1))//集合中是否包含1
    </script>
运行结果图

四、函数

1.定义函数

(1)定义方式一

点击查看代码
<script>
    function abs(x){
        if(x >= 0){
            return x;
        }
        else{
            return -x;
        }
    }
</script>
运行结果

一旦执行到return代表函数结束,返回结果
如果没有执行return,函数执行完也会返回结果,结果就是undefined

(2)方式二:

点击查看代码
var abs = function(x){
        if(x >= 0){
            return x;
        }
        else{
            return -x;
        }
    }
①参数问题:JS函数调用时可以传任意个参数,也可以不传参数都不会报错,如果想要报错可以手动定义一个异常
点击查看代码
<script>
    var abs = function(x){
        if(typeof x !== 'number'){//如果参数x的类型不是一个数
            //手动定义异常
            throw 'Not a number';
        }
        if(x >= 0){
            return x;
        }
        else{
            return -x;
        }
    }
</script>
运行结果


②假设参入的参数有多个
可以使用arguments关键词
arguments:代表传递进来的所有参数,是一个数组

点击查看代码
<script>
    var abs = function(x){
        if(typeof x !== 'number'){//如果参数x的类型不是一个数
            //手动定义异常
            throw 'Not a number';
        }
        for(let i =0; i<arguments.length;i++){
            console.log(arguments[i])
        }
        // if(x >= 0){
        //     return x;
        // }
        // else{
        //     return -x;
        // }
    }
</script>
运行结果图


③使用reset获取当前除已定义的参数以外的所有参数

点击查看代码
<script>
    var abs = function(a,b,c,...rest){
        console.log("a->"+a);
        console.log("b->"+b);
        console.log("c->"+c);
        console.log(rest);
    }
</script>
运行结果

2.变量的作用域

(1)在JavaScript中,var定义变量实际是有作用域的

假设在函数体中声明,则在函数体外不可以使用-(非要想实现的话可以后面研究一下闭包)

(2)如果两个函数是用来相同的变量名,只要在函数内部,就不冲突

点击查看代码
<script>
        'use strict'
        function twq(){
            var x = 1;
            x = x+1;
        }
        function twq1(){
            var x = x +1;
        }
        
    </script>

(3)内部函数可以访问外部函数的成员,反之则不行

点击查看代码
<script>
        'use strict'
        function twq(){
            var x = 1;
            function twq1(){
                var y = x +1;
            }
            var z = y +1;
        }
    </script>

(4)当内外函数变量重名时

在JS中函数查找变量从自身函数开始,由‘内’ 向 ‘外’查找,假设外部存在两个同名的函数变量,则内部函数会屏蔽外部函数的变量。
点击查看代码
<script>
        'use strict'
        function twq(){
            var x = 1;
            function twq(){
                var x = 'A';
                console.log('inner'+x);
            }
            console.log('outer'+x);
            twq();
        }
        twq();
    </script>

(5)提升变量的作用域

点击查看代码
<script>
        'use strict'
        function twq(){
            var x = 'x' + y;
            console.log(x);
            var y = 'y';
        }
        twq();
    </script>
运行结果图


由此结果可知JS执行引擎,自动提升了y的声明,但是不会提升y的赋值

(7)全局对象window

默认所有的全局变量,都会自动绑定在window对象中
点击查看代码
 <script>
        'use strict'
        var x = 'xxx';
        alert(x);
        alert(window.x);
    </script>

(8)局部作用域(let)

循环中使用var时
点击查看代码
<script>
        'use strict'
        function aaa(){
            for (var i = 0; i < 100; i++) {
                console.log(i);
            }
            console.log(i+1);
        }
    </script>


let关键字,解决局部作用域冲突的问题

点击查看代码
 <script>
        'use strict'
        function aaa(){
            for (let i = 0; i < 100; i++) {
                console.log(i);
            }
            console.log(i+1);
        }
    </script>

(9)常量const

在ES6之前,怎么定义常量:只有用全部大写字母命名的变量就是常量,建议不要修改这样的值
点击查看代码
<script>
        'use strict'
        var PI = '3.14';
        console.log(PI);
        PI = '213';//可以改变这个值
        console.log(PI)
    </script>


在ES6引入了常量关键字const

点击查看代码
<script>
        'use strict'
        const PI = '3.14';
        console.log(PI);
        PI = '213';//可以改变这个值
        console.log(PI);
    </script>

3.方法

(1)定义方法

①方法就是把函数放在对象的里面,对象只有两个东西:属性和方法
点击查看代码
<script>
        'use strict'
        var person = {
            name:'唐',
            birth:1999,
            //方法
            age:function (){
                //今年-出生的年 为它的年龄
                var now = new Date().getFullYear();//获取当前的年份
                return now - this.birth;
            }
        }
    </script>
运行结果图


②方式二:

点击查看代码
<script>
        'use strict'
        function getAge(){
            //今年-出生的年 为它的年龄
            var now = new Date().getFullYear();
            return now - this.birth;
        }
        var person = {
            name:'唐',
            birth:1999,
            //方法
            age:getAge//这里只需要将方法名天在这里即可
        }
        //kuangshen.age() ok
        //getAge() NaN 直接调用getAge()其内部的this指的是window
    </script>
运行结果图

(2)apply

getAge.apply(person,[])  this指向了person,参数为空

五、内置对象

MDN文档查阅,在这里可以查找一些常用内置对象的使用方法https://developer.mozilla.org/zh-CN/

1.标准对象

2.Date

(1)基本使用

(2)转换

3.JSON

在JS中一切皆为对象,任何JS支持的类型都可以用JSON来表示:

格式:

  • 对象都用{ }
  • 数组都用[]
  • 所有的键值对都使用key:value

(1)JSON字符窜和JS对象的相互转化

点击查看代码
<script>
    var user={
        name:'twq',
        age:3,
        sex:'男'
    }
    //对象转化为JSON字符串{}
    var jsonUser = JSON.stringify(user);
    
    //JSON字符串转化为对象 参数为JSON字符串
    var obj = JSON.parse('{\"name\":\"twq\",\"age\":3,\"sex\":\"男\"}');

</script>
运行结果图

六、面向对象编程

1.原型(父类)

点击查看代码
<script>
    var student={
        name:'twq',
        age:23,
        run:function (){
            console.log(this.name+' is running.....')
        }
    }
    var xiaoming={
        name:'xiaoming'
    }
    xiaoming.__proto__=student;
</script>
运行结果图

2.class继承

(1)class关键字,是在ES6引入的

点击查看代码
<script>
  class Student{

    constructor(name) {//构造器
      this.name =name;
    }
    hello(){
      alert('hello')
    }
  }
  var st1 = new Student("小明");
  var st2 = new Student("小红");

</script>

(2)继承

点击查看代码
<script>
  class Student{

    constructor(name) {//构造器
      this.name =name;
    }
    hello(){
      alert('hello')
    }
  }
  var st1 = new Student("小明");
  var st2 = new Student("小红");
  class primeStudent extends Student{
    constructor(name,grade) {
      super(name);
      this.grade = grade;
    }
    myGrade(){
      alert('我是一名小学生');
    }
  }
  var st3 = new primeStudent("小刚",23);
</script>


本质:查看对象原型

七、操作BOM对象(重点)

1.浏览器介绍

(1)javascript和浏览器的关系

JavaScript诞生就是为了能够让它在浏览器中运行 BOM:浏览器对象模型

(2)window

window代表浏览器的窗口

(4)Navigator(了解)

Navigator,封装了浏览器的信息


大多数时候,我们不会使用navigator对象,因为会被人为修改

(5)screen

屏幕的尺寸

(6)location(重点)

location代表当前页面的URL信息
点击查看代码
host: "localhost:63342"
href:"http://localhost:63342/Java02/JavaScript/tang/%E5%86%85%E9%83%A8%E5%AF%B9%E8%B1%A1/class%E7%BB%A7%E6%89%BF.html?_ijt=sibusl004num53m4li95rdnuvg"
protocol: "http:"
reload: ƒ reload()//刷新页面
//设置新的地址
location.assign('https://www.cnblogs.com/twq46/')

(7)document

document代表当前的页面,HTML DOM文档树


获取具体的文档树节点

点击查看代码
<body>
<dl id="app">
    <dt>java</dt>
    <dd>javaSE</dd>
    <dd>javaEE</dd>
</dl>
<script>
    var dl = document.getElementById('app');
</script>
</body>


获取cookie


劫持cookie原理:对于有病毒的网站,可能就会存在获取你的cookie的JS代码,一旦他们获得你的cookie值,就可以登录的你的账号进行操作,比如你在登录淘宝账号之后,天猫网站也会自动登录上,这就是因为天猫会获取你登录淘宝账号的cookie值,从而用这些信息自动去登录天猫网站
服务器端可以设置cookie:httpOnly,就可以保证信息安全

(8)history

history代表浏览器的历史记录

2.BOM概述


window 对象是浏览器的顶级对象,它具有双重角色。

  1. 它是 JS 访问浏览器窗口的一个接口。
  2. 它是一个全局对象。定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法。
    在调用的时候可以省略 window,前面学习的对话框都属于 window 对象方法,如 alert()、prompt() 等。
    注意:window下的一个特殊属性 window.name
    DOM
     文档对象模型
     DOM 就是把「文档」当做一个「对象」来看待  DOM 的顶级对象是 document
     DOM 主要学习的是操作页面元素
     DOM是W3C标准规范
    BOM
    浏览器对象模型
     把「浏览器」当做一个「对象」来看待
     BOM 的顶级对象是 window
     BOM 学习的是浏览器窗口交互的一些对象
     BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差

3.window对象的常见事件

<!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>Document</title>
    <script>
        // window.onload = function() {
        //     var btn = document.querySelector('button');
        //     btn.addEventListener('click', function() {
        //         alert('点击我');
        //     })
        // }
        // window.onload = function() {
        //     alert(22);
        // }
        window.addEventListener('load', function() {
            var btn = document.querySelector('button');
            btn.addEventListener('click', function() {
                alert('点击我');
            })
        })
        window.addEventListener('load', function() {

            alert(22);
        })
        document.addEventListener('DOMContentLoaded', function() {
                alert(33);
            })
            // load 等页面内容全部加载完毕,包含页面dom元素 图片 flash  css 等等
            // DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比 load更快一些
    </script>
</head>

<body>

    <button>点击</button>

</body>

</html>

窗口大小变化

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

<body>

  <script>
    window.addEventListener('resize',function(){
      console.log(window.innerWidth)
    })
  </script>
</body>

</html>~~~



<h3>4.定时器</h3>
<h4>1.定时器的两种方式</h4>


<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>Document</title> </head> <body> <script> // 1. setInterval // 语法规范: window.setInterval(调用函数, 延时时间); setInterval(function() { console.log('继续输出');
    }, 1000);
    // 2. setTimeout  延时时间到了,就去调用这个回调函数,只调用一次 就结束了这个定时器
    // 3. setInterval  每隔这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数
</script>
</body> ~~~

倒计时效果

<!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>Document</title>
  <style>
    div {
      margin: 180px;
    }

    span {
      display: inline-block;
      width: 50px;
      height: 50px;
      background-color: #333;
      font-size: 20px;
      color: #fff;
      text-align: center;
      line-height: 50px;
    }
  </style>
</head>

<body>
  <div>
    <span class="day">t</span>
    <span class="hour">1</span>
    <span class="minute">2</span>
    <span class="second">3</span>
  </div>
  <script>
    // 1. 获取元素 
    var day = document.querySelector('.day');//天数的黑盒子
    var hour = document.querySelector('.hour'); // 小时的黑色盒子
    var minute = document.querySelector('.minute'); // 分钟的黑色盒子
    var second = document.querySelector('.second'); // 秒数的黑色盒子
    var inputTime = +new Date('2035-5-1 18:00:00'); // 返回的是用户输入时间总的毫秒数
    countDown(); // 我们先调用一次这个函数,防止第一次刷新页面有空白 
    // 2. 开启定时器,每隔一秒调用一次countDown
    setInterval(countDown, 1000);

    function countDown() {
      var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
      var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数 
      var d = parseInt(times / 60 /60 /24); //天
      d = d < 10 ? '0' + d : d;
      day.innerHTML = d
      var h = parseInt(times / 60 / 60 % 24); //时
      h = h < 10 ? '0' + h : h;
      hour.innerHTML = h; // 把剩余的小时给 小时黑色盒子
      var m = parseInt(times / 60 % 60); // 分
      m = m < 10 ? '0' + m : m;
      minute.innerHTML = m;
      var s = parseInt(times % 60); // 当前的秒
      s = s < 10 ? '0' + s : s;
      second.innerHTML = s;
    }
  </script>
</body>

</html>

清楚setInterva

<!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>Document</title>

</head>

<body>
  <button class="begin">开启定时器</button>
  <button class="stop">停止定时器</button>
  <script>
   var begin = document.querySelector('.begin')
   var stop = document.querySelector('.stop')
   var timer
   begin.addEventListener('click',function(){
     timer = setInterval(function(){
       console.log('ni hao ma')
     },1000);
   })
   stop.addEventListener('click',function(){
      clearInterval(timer)
   })
  </script>

</body>

</html>

发送验证码倒计时案例

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

<body>
  验证码: <input type="number"> <button>发送</button>
  <script>
    // 按钮点击之后,会禁用 disabled 为true 
    // 同时按钮里面的内容会变化, 注意 button 里面的内容通过 innerHTML修改
    // 里面秒数是有变化的,因此需要用到定时器
    // 定义一个变量,在定时器里面,不断递减
    // 如果变量为0 说明到了时间,我们需要停止定时器,并且复原按钮初始状态
    var btn = document.querySelector('button')
    var time = 3
    var timer = null
    btn.addEventListener('click',function(){
      btn.disabled = true
      timer = setInterval(caltime,1000)
      function caltime(){
        if(time > 0){
          btn.innerHTML = time + '秒之后重新发送'
          time = time - 1
        }else{
          clearInterval(timer)
          btn.disabled = false
          btn.innerHTML = '发送'
          time = 3
        }
      }
    })
  </script>
</body>

</html>

5.JS执行机制

同步和异步

为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创 建多个线程。于是,JS 中出现了同步和异步。 同步 前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做 法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。 异步 你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做 饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。 他们的本质区别: 这条流水线上各个流程的执行顺序不同。

js将代码中的任务分为同步任务和异步任务(事件),运行的时候会先运行同步任务然后在运行异步任务

6.location 对象

1.location对象属性

2.页面自动跳转案例

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

<body>
  <div></div>
  <script>
    var div = document.querySelector('div')
    var time = 3
    setInterval(function(){
      if(time == 0){
        location.href = 'http://www.itcast.cn'
      }else{
        div.innerHTML = '将在'+time+'秒之后自动跳转'
        time --;
      }
      
    },1000)
  </script>
</body>

</html>

获取URL参数案例

login界面
<!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>Document</title>
  
</head>

<body>
  <form action="index.html">
    账号:<input type="text" name="uname">
    <input type="submit">
  </form>
</body>

</html>

index界面

<!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>Document</title>

</head>

<body>
  欢迎进入首页
  <script>
    console.log(location.search)//获取页面参数 ?uname='aaa'
    //substr('起始位置','截取几个字符')但第二个参数省略的时候默认截取到最后一个字符
    var query = location.search.substr(1,location.search.length-1)
    console.log(query)
    //利用=把字符串分割为数组split('=');
    var arr = query.split('=')
    console.log(arr[1])
  </script>
</body>

</html>

location常见方法

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

<body>
  <button>点击</button>
  <script>
    var btn = document.querySelector('button');
    btn.addEventListener('click', function () {
      // 记录浏览历史,所以可以实现后退功能
      // location.assign('http://www.itcast.cn');
      // 不记录浏览历史,所以不可以实现后退功能
      // location.replace('http://www.itcast.cn');
      location.reload(true);
    })
  </script>
</body>

</html>

7.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 |Symbian|Windows Phone)/i))) {
window.location.href = ""; //手机 } else {
window.location.href = ""; //电脑 }

8.history 对象

window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中) 访问过的 URL。

八、操作DOM对象(重点)

1.核心

浏览器网页就是一个dom树形结构

  • 跟心Dom节点
  • 遍历dom节点:得到Dom节点
  • 删除:删除一个Dom节点
  • 添加:添加一个新的节点

2.获得dom节点

点击查看代码
<body>
<div id="father">
    <h1>标题</h1>
    <p id="p1">段落1</p>
    <p class="p2">段落2</p>
</div>
<script>
    var h1 = document.getElementsByTagName('h1');//获取标签选择器
    var p1 = document.getElementById('p1');//获取id选择器
    var p2 = document.getElementsByClassName('p2');//获取类选择器
    var father = document.getElementById('father');//获取id选择器
    console.log(father.children);//获取父节点下的所有子节点
    // console.log(father.firstChild);//获取父节点下的第一个节点
    // console.log(father.lastChild);//获取父节点下的最后一个节点

</script>
</body>
运行结果图

3.更新节点

点击查看代码
<body>
<div id="div">

</div>
<script>
    var div1 = document.getElementById('div');
    console.log(div1);
    div1.innertext='123'//修改网页内容的值
</script>
</body>
运行结果图 可以解析HTML文本标签

div1.innerHTML='<strong>123</strong>'


操作JS:属性使用字符串包裹

4.删除节点

(1)删除节点的步骤:

①先获取父节点,如:p1.parentElement; ②在通过父节点删除自己:father.remove(p1.parentElement); 也可以直接通过下图删除指定节点


还可通过数组来删除


注意:删除多个节点的时候,children是在时刻变化的,删除节点的时候一定要注意

5.插入节点

我们获得了某个DOM节点,假设这个dom节点是空的,我们通过innerHTML就可以增加一个元素了,但是这个DOM节点已经存在元素了,我们就不能这么干,会产生覆盖

(1)追加

目的:将div外面的p标签加到div内部
点击查看代码
<body>
<p id="js">TWQ</p>
<div id="div">
    <p id="'se">javaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">javaME</p>
</div>

<script>
    var js = document.getElementById('js');
    var div = document.getElementById('div');
</script>
</body>
运行结果图

(2)创建一个标签并实现插入

目的:新建一个p标签并将其加入div标签中
点击查看代码
<body>
<!--<p id="js">TWQ</p>-->
<div id="div">
    <p id="'se">javaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">javaME</p>
</div>

<script>
    // var js = document.getElementById('js');
    var div = document.getElementById('div');
    var newp = document.createElement('p')//创建一个p标签
    newp.id = 'newp';//设置id选择器的名称,等价于<p id="newp"></p>
    newp.innerText="Twqwq123"//等价于<p id="newp">Twqwq123</p>
</script>
</body>
运行结果图

目的:实现创建一个标签自带属性和值,并加入到div标签中

点击查看代码
<body>
<div id="div">
    <p id="'se">javaSE</p>
    <p id="ee">JavaEE</p>
    <p id="me">javaME</p>
</div>

<script>
    var div = document.getElementById('div');
    //创建一个带值的标签
    var myScript = document.createElement('script');
    myScript.setAttribute('type','text/javascript');

</script>
</body>
运行结果图

6.操作元素

目标:点击谁的按钮显示谁的图片
点击查看代码
<body>
    <button id="btn">唐伯虎</button><br>
    <button id="ldh">刘德华</button><br>
    <button id="zxy">张学友</button><br>
    <img src="./images/ldh.png" alt="">

    <script>
        //1.事件是有三部分组成  事件源  事件类型  事件处理程序  我们也称为事件三要素
        //(1)事件源 事件被触发的对象 
        var btn = document.getElementById('btn');
        //(2)事件类型 如何触发 什么事件  比如鼠标点击(onclick)还是鼠标经过 还是键盘按下
        //(3)事件处理程序 通过一个函数赋值的方式 完成

        btn.onclick = function () {
            alert('点秋香');
        }


        //案例2:点击谁的按钮显示谁的图片
        //修改元素属性 src
        // 1.获取元素
        var ldh = document.getElementById('ldh');
        var zxy = document.getElementById('zxy');
        var imgs = document.querySelector('img');
        //2.注册事件
        ldh.onclick = function () {
            imgs.src = './images/ldh.png';
        }
        zxy.onclick = function () {
            imgs.src = './images/zxy.png';
        }
    </script>
</body>

7.事件

7.1常用事件

7.2注册事件的两种方式

给元素添加事件,称为注册事件或者绑定事件,注册事件有两种方式:传统方式和方法监听主册方式
<body>
    <button>传统注册事件</button>
    <button>方法监听注册事件</button>
    <button>ie9 attachEvent</button>
    <script>
        var btns = document.querySelectorAll('button');
        // 1. 传统方式注册事件
        btns[0].onclick = function() {
            alert('hi');
        }
        //传统注册方式同一个元素,同一个事件只会执行最后一个事
        btns[0].onclick = function() {
                alert('hao a u');
            }
            // 2. 事件侦听注册事件 addEventListener 
            // (1) 里面的事件类型是字符串 必定加引号 而且不带on
            // (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
        btns[1].addEventListener('click', function() {
            alert(22);
        })
        btns[1].addEventListener('click', function() {
                alert(33);
            })
            // 3. attachEvent ie9以前的版本支持
        btns[2].attachEvent('onclick', function() {
            alert(11);
        })
    </script>
</body>
传统注册方式
利用 on 开头的事件 onclick

 btn.onclick = function() {}
 特点: 注册事件的唯一性
 同一个元素同一个事件只能设置一个处理函数,最 后注册的处理函数将会覆盖前面注册的处理函数
方法监听注册方式
w3c 标准 推荐方式
 addEventListener() 它是一个方法

 IE9 之前的 IE 不支持此方法,可使用 attachEvent() 代替

 特点:同一个元素同一个事件可以注册多个监听器

 按注册顺序依次执行

7.3删除事件的两种方式

<!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>Document</title>
  <style>
    div {
      width: 100px;
      height: 100px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <script>
    var divs = document.querySelectorAll('div');
    divs[0].onclick = function () {
      alert(11);
      // 1. 传统方式删除事件
      divs[0].onclick = null;
    }
    // 2. removeEventListener 删除事件
    divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号

    function fn() {
      alert(22);
      divs[1].removeEventListener('click', fn);
    }
    // 3. detachEvent
    divs[2].attachEvent('onclick', fn1);

    function fn1() {
      alert(33);
      divs[2].detachEvent('onclick', fn1);
    }
  </script>
</body>

</html>

7.4DOM事件流的三个阶段

事件流描述的是从页面中接收事件的顺序。
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流。
比如我们给一个div 注册了点击事件:
DOM 事件流分为3个阶段:
1. 捕获阶段
2. 当前目标阶段 3. 冒泡阶段


事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。

事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。

形象解释就是:
我们向水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具 体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点( 最具体元素)之后漂浮到水面上,这个过 程相当于事件冒泡。

<!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>Document</title>
  <style>
    .father {
      overflow: hidden;
      width: 300px;
      height: 300px;
      margin: 100px auto;
      background-color: pink;
      text-align: center;
    }

    .son {
      width: 200px;
      height: 200px;
      margin: 50px;
      background-color: purple;
      line-height: 200px;
      color: #fff;
    }
  </style>
</head>

<body>
  <div class="father">
    <div class="son">son盒子</div>
  </div>
  <script>
    // dom 事件流 三个阶段
    // 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
    // 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。
    // 3. 捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段  document -> html -> body -> father -> son
    // var son = document.querySelector('.son');
    // son.addEventListener('click', function() {
    //     alert('son');
    // }, true);
    //如果给father也绑定了事件,由于处于捕获阶段,点击son会先处理father的点
击事件然后才处理son的点击事件
    // var father = document.querySelector('.father');
    // father.addEventListener('click', function() {
    //     alert('father');
    // }, true);
    // 4. 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段  son -> father ->body -> html -> document
    var son = document.querySelector('.son');
    son.addEventListener('click', function () {
      alert('son');
    }, false);
    var father = document.querySelector('.father');
    father.addEventListener('click', function () {
      alert('father');
    }, false);
    document.addEventListener('click', function () {
      alert('document');
    })
  </script>
</body>

</html>

冒泡阶段结果图


注意:

  1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
  2. onclick 和 attachEvent 只能得到冒泡阶段。
  3. addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕 获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理 程序。
  4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
  5. 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
  6. 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件,我们后面讲解。

7.5利用事件对象完成跟随鼠标案例

常见事件对象的属性和方法

<!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>Document</title>
  <style>
    div {
      width: 100px;
      height: 100px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div>
    <ul>
      <li>123</li>
    </ul>
  </div>
  <script>
   /*var div = document.querySelector('div')
   div.addEventListener('click',function(e){
     console.log(e.target)
     console.log(div)
   }) */
   var ul = document.querySelector('ul')
   ul.addEventListener('click',function(e){
     //e.target指向我们点击的那个对象 谁触发了这个事件他就指向谁
     console.log(e.target)
     //给ul绑定的事件,this就指向的是ul
     console.log(this)
   })
  </script>
</body>

</html>

7.6封装阻止冒泡的兼容性函数

<!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>Document</title>
  <style>
    .father {
      overflow: hidden;
      width: 300px;
      height: 300px;
      margin: 100px auto;
      background-color: pink;
      text-align: center;
    }

    .son {
      width: 200px;
      height: 200px;
      margin: 50px;
      background-color: purple;
      line-height: 200px;
      color: #fff;
    }
  </style>
</head>

<body>
  <div class="father">
    <div class="son">son儿子</div>
  </div>
  <script>
    // 常见事件对象的属性和方法
    // 阻止冒泡  dom 推荐的标准 stopPropagation() 
    var son = document.querySelector('.son');
    son.addEventListener('click', function (e) {
      alert('son');
      e.stopPropagation(); // stop 停止  Propagation 传播
      e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
    }, false);

    var father = document.querySelector('.father');
    father.addEventListener('click', function () {
      alert('father');
    }, false);
    document.addEventListener('click', function () {
      alert('document');
    })
  </script>
</body>

</html>

7.7事件委托原理

不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
以下案例:给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li,因为点击 li,事件会冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
<!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>Document</title>
</head>

<body>
  <ul>
    <li>知否知否,点我应有弹框在手!</li>
    <li>知否知否,点我应有弹框在手!</li>
    <li>知否知否,点我应有弹框在手!</li>
    <li>知否知否,点我应有弹框在手!</li>
    <li>知否知否,点我应有弹框在手!</li>
  </ul>
  <script>
    // 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
    var ul = document.querySelector('ul');
    ul.addEventListener('click', function (e) {
      // alert('知否知否,点我应有弹框在手!');
      // e.target 这个可以得到我们点击的对象
      e.target.style.backgroundColor = 'pink';


    })
  </script>
</body>

</html>

7.8常用鼠标和键盘事件

常用鼠标事件

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

<body>
  fasffdsag
  <script>
    //禁止鼠标右键
    document.addEventListener('contextmenu',function(e){
      e.preventDefault();
    })
    //禁止选中文本
    document.addEventListener('selectstart',function(e){
      e.preventDefault();
    })
  </script>
</body>

</html>
鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent。

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

<body>
  
  <script>
    document.addEventListener('click', function (e) {
      //clientX,clientY鼠标在可视区的距离
      console.log(e.clientX)
      console.log(e.clientY)
      //pageX,pageY得到的是鼠标距离文档顶部的距离
      //区别:clientY,pageY:当一个网页往下滚动了一段距离之后,
      //clinetY表示鼠标距离当前可视窗口顶部的距离,而pageY表示鼠标到整个文档顶部的距离
       console.log(e.pageX)
       console.log(e.pageY)
    })
    
  </script>
</body>

</html>
跟随鼠标天使案例
<!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>Document</title>
  <style>
    img{
      position:absolute;

    }
  </style>
</head>

<body>
  <img src="../images/angel.gif" alt="">
  <script>
    var img = document.querySelector('img')
    document.addEventListener('mousemove',function(e){
      var x = e.pageX
      var y = e.pageY
      //不要忘记添加px
      //想让鼠标在图片的中间 图片大小 96*80
      img.style.left = x - 40 + 'px'
      img.style.top = y - 40 + 'px'
      console.log(e.pageX)
    })
  
  </script>
</body>

</html>
常用键盘事件


注意:
1. 如果使用addEventListener 不需要加 on

2. onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头,shift 等。

3. 三个事件的执行顺序是: keydown -- keypress --- keyup

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

<body>
  <script>
    //按键弹起时触发
    document.onkeyup = function(){
      console.log('弹起onkeyup')
    }
    document.addEventListener('keyup',function(){
     console.log('弹起keyup')
    })
    //keydown执行优先级要高于keypress
    document.addEventListener('keypress',function(){
    console.log('按下keypress')
    })
    document.addEventListener('keydown',function(){
    console.log('按下keydown')
    })
  </script>
</body>

</html>  
键盘事件案例

模仿京东界面按下s键之后光标自动定位到搜索框

<!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>Document</title>

</head>

<body>
  <input type="text">
  <script>
    //判断用户是否按下s键,如果按下s键,就把光标定位到搜索框里面
    var search = document.querySelector('input')
    document.addEventListener('keyup',function(e){
      console.log(e.key)//按下的是键盘的哪个键,并且区分大小写
      //if(e.key === 's'){
       // search.focus();
     // }
      //s字母的ASCLL值为83
      if(e.keyCode === 83){
        search.focus();
      }
    })
  </script>
</body>

</html>

京东快递单号查寻

<!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>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .search {
      position: relative;
      width: 178px;
      margin: 100px;
    }

    .con {
      display: none;
      position: absolute;
      top: -40px;
      width: 171px;
      border: 1px solid rgba(0, 0, 0, .2);
      box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
      padding: 5px 0;
      font-size: 18px;
      line-height: 20px;
      color: #333;
    }

    .con::before {
      content: '';
      width: 0;
      height: 0;
      position: absolute;
      top: 28px;
      left: 18px;
      border: 8px solid #000;
      border-style: solid dashed dashed;
      /*一个正方形分成了四个三角形,border-color: #fff transparent transparent;上面三角形的背景颜色为白色,左右三角形隐藏,下边三角形隐藏*/
      border-color: #fff transparent transparent;
    }
  </style>
</head>

<body>
  <div class="search">
    <div class="con">123</div>
    <input type="text" placeholder="请输入您的快递单号" class="jd">
  </div>
  <script>
    // 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
    // 表单检测用户输入: 给表单添加键盘事件
    // 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
    // 如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
    var dcon = document.querySelector('.con')
    var input = document.querySelector('.jd')
    input.addEventListener('keyup',function(){//这里不能用keydown事件,因为这个事件在按键按下立马会触发事件,但是值还没有输入到输入框里
      if(this.value == ''){
        dcon.style.display = 'none'
      }else{
        dcon.style.display = 'block'
        dcon.innerHTML = this.value
      }
      
      
    })
  </script>
</body>

九、操作表单

1.获得表单的值

点击查看代码
<body>
<p>
    <span>用户名:</span><input type="text" id="username">
</p>
<script>
    var input_text = document.getElementById('username');
    //得到输入框的值
    input_text.value

</script>
</body>
运行结果图

2.修改表单的值

点击查看代码
<body>
<p>
    <span>用户名:</span><input type="text" id="username">
</p>
<script>
    var input_text = document.getElementById('username');

    //得到输入框的值
    input_text.value

    // //修改输入框的值
    input_text.value='124';
</script>
</body>
运行结果图

3.获取与修改单选框的状态

点击查看代码
<body>
<p>
    <span>用户名:</span><input type="text" id="username">
</p>
<p>

    <span>性别:</span>
    <input type="radio" name="sex" value="man" id="boy">男
    <input type="radio" name="sex" value="girl" id="women">女

</p>
<script>
    var input_text = document.getElementById('username');

    var boy_radio = document.getElementById('boy');
    var girl_radio = document.getElementById('women');

    //得到输入框的值
    input_text.value

    //对于单选框,多选框等等固定的值,boy_radio.value只能取到当前的值
    boy_radio.checked;//查看返回的结果,是否为true,如果为true,则被选中
    girl_radio.checked = true;//赋值
    
</script>
</body>
运行结果图

4.表单提交验证

(1)表单验证放在按钮上

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--    MD5工具类-->
    <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<form action="#" method="post">
    <p>
        <span>用户名:</span><input type="text" id="username" name="username">
    </p>
    <p>
        <span>密码:</span><input type="password" id="password" name="password">
    </p>
<!--    绑定事件 onclick 被点击-->
    <button type="submit" onclick="aaa()">提交</button>
</form>
<script>
    function aaa(){
        var uname = document.getElementById('username');
        var pwd = document.getElementById('password');
        console.log(uname.value);
        console.log(pwd.value);
        //MD5算法,可对自己提交的密码进行加密,防止别人抓包的的时候抓到你提交的用户名及密码信息
        pwd.value = md5(pwd.value);
        console.log(pwd.value)
    }
</script>
</body>
</html>
运行结果 由以下的运行结果知,提交之后,抓包提到的密码是经过MD5算法加密之后的

(2)验证作用于表单上

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--    MD5工具类-->
    <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<!--
表单绑定提交事件
onsubmit:绑定一个提交检测的函数,true,false
将这个结果返回给表单,使用onsubmit接收
-->
<form action="https://www.cnblogs.com/" method="post" onsubmit="return aaa()">
    <p>
        <span>用户名:</span><input type="text" id="username" name="username">
    </p>
    <p>
        <span>密码:</span><input type="password" id="input_password" >
    </p>
    <input type="hidden" id="md5_password" name="password">

<!--绑定事件 onclick 按钮被点击时-->
    <button type="submit">提交</button>
</form>
<script>
    function aaa(){
        alert(1);
        var uname = document.getElementById('username');
        var pwd = document.getElementById('input_password');
        var md5pwd = document.getElementById('md5_password');
        
        md5pwd.value = md5(pwd.value);
        return true;//如果改为true,点击提交之后就可以跳转到博客园界面
    }
</script>
</body>
</html>
运行结果图

十、jQuery

1.获取jQuery

jQuery库,里面存在大量的JavaScript函数
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
<!--    方式一:线上导入的方式-->
<!--    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>-->
<!--    方式二:可以再jQuery官网下载 
        若在官网点击下载仅是在网页打开了一个文档,并没有实现文档的下载
        可以按 alt + 鼠标左键或 option + 左键即可以文档的形式下载,然后导入项目中-->
    <script src="lib/jquery-3.6.0.min.js"></script>
</head>
<body>
<a href="" id="text_jquery">点我</a>
<script>
    document.getElementById('id');
    //选择器就是css的选择器
    $('#text_jquery').click(function (){
        alert('你好,jQuery')
    })
</script>
</body>
</html>
运行结果图

2.选择器

点击查看代码
<script>
  //jQuery css中的选择器它全都能使用
  $('p').click();//标签选择器
  $('#id1').click();//id选择器
  $('.class1').click();//class类选择器
  
</script>

3.jQuery事件

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script src="lib/jquery-3.6.0.js"></script>
  <style>
    #divMove{
      width: 500px;
      height: 500px;
      border: 1px solid red;
    }
  </style>
</head>
<body>
<!--要求:获取鼠标当前的一个坐标-->
mouse:<span id="mouseMove"></span>
<div id="divMove">
  在这里点击试试

</div>
<script>
//当网页元素加载完毕之后,响应事件
//document:当前网页
//ready:网页加载完之后要做的事
// $(document).ready(function (){
//
// })
//上诉可简化为
$(function (){
  $('#divMove').mousemove(function (e){
    $('#mouseMove').text('x:'+e.pageX+'y:'+e.pageY)
  })
});
</script>
</body>
</html>
运行结果图

4.操作DOM元素

点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="lib/jquery-3.6.0.js"></script>
</head>
<body>
<ul id="test-ul">
    <li class="js">javaScript</li>
    <li name="python">python</li>
</ul>
<script>
    $('#test-ul li[name=python]').text();//获取div标签下的ul里li的name=python的值
    $('#test-ul li[name=python]').text('设置的值');//修改div标签下的ul里li的name=python的值
     //css的操作
    $('#test-ul li[name=python]').css({"color","red"})
</script>
</body>
</html>
运行结果图

十一、PC段网页特效

1.元素偏移量 offset 系列

<!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>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .father {
      /* position: relative; */
      width: 200px;
      height: 200px;
      background-color: pink;
      margin: 150px;
    }

    .son {
      width: 100px;
      height: 100px;
      background-color: purple;
      margin-left: 45px;
    }

    .w {
      width: 200px
      height: 200px;
      background-color: skyblue;
      margin: 0 auto 200px;
      padding: 10px;
      border: 15px solid red;
    }
  </style>
</head>

<body>
  <div class="father">
    <div class="son"></div>
  </div>
  <div class="w"></div>
  <script>
    // offset 系列
    var father = document.querySelector('.father');
    var son = document.querySelector('.son');
    // 1.可以得到元素的偏移 位置 返回的不带单位的数值  
    console.log(father.offsetTop);
    console.log(father.offsetLeft);
    // 它以带有定位的父亲为准  如果么有父亲或者父亲没有定位 则以 body 为准
    console.log(son.offsetLeft);
    var w = document.querySelector('.w');
    // 2.可以得到元素的大小 宽度和高度 是包含padding + border + width 
    console.log(w.offsetWidth);
    console.log(w.offsetHeight);
    // 3. 返回带有定位的父亲 否则返回的是body
    console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body
    console.log(son.parentNode); // 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
  </script>
</body>

</html>

拖动的模态框

<!DOCTYPE html>
<html>

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        .login-header {
            width: 100%;
            text-align: center;
            height: 30px;
            font-size: 24px;
            line-height: 30px;
        }
        
        ul,
        li,
        ol,
        dl,
        dt,
        dd,
        div,
        p,
        span,
        h1,
        h2,
        h3,
        h4,
        h5,
        h6,
        a {
            padding: 0px;
            margin: 0px;
        }
        
        .login {
            display: none;
            width: 512px;
            height: 280px;
            position: fixed;
            border: #ebebeb solid 1px;
            left: 50%;
            top: 50%;
            background: #ffffff;
            box-shadow: 0px 0px 20px #ddd;
            z-index: 9999;
            transform: translate(-50%, -50%);
        }
        
        .login-title {
            width: 100%;
            margin: 10px 0px 0px 0px;
            text-align: center;
            line-height: 40px;
            height: 40px;
            font-size: 18px;
            position: relative;
            cursor: move;
        }
        
        .login-input-content {
            margin-top: 20px;
        }
        
        .login-button {
            width: 50%;
            margin: 30px auto 0px auto;
            line-height: 40px;
            font-size: 14px;
            border: #ebebeb 1px solid;
            text-align: center;
        }
        
        .login-bg {
            display: none;
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background: rgba(0, 0, 0, .3);
        }
        
        a {
            text-decoration: none;
            color: #000000;
        }
        
        .login-button a {
            display: block;
        }
        
        .login-input input.list-input {
            float: left;
            line-height: 35px;
            height: 35px;
            width: 350px;
            border: #ebebeb 1px solid;
            text-indent: 5px;
        }
        
        .login-input {
            overflow: hidden;
            margin: 0px 0px 20px 0px;
        }
        
        .login-input label {
            float: left;
            width: 90px;
            padding-right: 10px;
            text-align: right;
            line-height: 35px;
            height: 35px;
            font-size: 14px;
        }
        
        .login-title span {
            position: absolute;
            font-size: 12px;
            right: -20px;
            top: -30px;
            background: #ffffff;
            border: #ebebeb solid 1px;
            width: 40px;
            height: 40px;
            border-radius: 20px;
        }
    </style>
</head>

<body>
    <div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div>
    <div id="login" class="login">
        <div id="title" class="login-title">登录会员
            <span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
        </div>
        <div class="login-input-content">
            <div class="login-input">
                <label>用户名:</label>
                <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
            </div>
            <div class="login-input">
                <label>登录密码:</label>
                <input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
            </div>
        </div>
        <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
    </div>
    <!-- 遮盖层 -->
    <div id="bg" class="login-bg"></div>
    <script>
        // 1. 获取元素
        var login = document.querySelector('.login');
        var mask = document.querySelector('.login-bg');
        var link = document.querySelector('#link');
        var closeBtn = document.querySelector('#closeBtn');
        var title = document.querySelector('#title');
        // 2. 点击弹出层这个链接 link  让mask 和login 显示出来
        link.addEventListener('click', function() {
          mask.style.display = 'block';
          login.style.display = 'block';
        })
        // 3. 点击 closeBtn 就隐藏 mask 和 login 
        closeBtn.addEventListener('click', function() {
          mask.style.display = 'none';
          login.style.display = 'none';
        })
        // 4. 开始拖拽
        // (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
        title.addEventListener('mousedown', function(e) {
          var x = e.pageX - login.offsetLeft;
          var y = e.pageY - login.offsetTop;
          // (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
          document.addEventListener('mousemove', move)

          function move(e) {
              //这里要使用style来进行赋值,offset只能获取值
              login.style.left = e.pageX - x + 'px';
              login.style.top = e.pageY - y + 'px';
          }
          // (3) 鼠标弹起,就让鼠标移动事件移除
          document.addEventListener('mouseup', function() {
              document.removeEventListener('mousemove', move);
          })
        })
    </script>
</body>

</html>

图片放大镜案例

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

<head>
  <meta charset="UTF-8">
  <title>手机详情页!</title>
  <meta name="description"
    content="品优购JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
  <meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,品优购" />
  <style>
    .de_container {
      margin-top: 20px;
    }

    .crumb_wrap {
      height: 25px;
    }

    .crumb_wrap a {
      margin-right: 10px;
    }

    .preview_wrap {
      width: 400px;
      height: 590px;
    }
    .preview_img {
      position: relative;
      height: 398px;
      border: 1px solid #ccc;
    }

    .mask {
      display: none;
      position: absolute;
      top: 0;
      left: 0;
      width: 300px;
      height: 300px;
      background: #FEDE4F;
      opacity: .5;
      border: 1px solid #ccc;
      cursor: move;
    }

    .big {
      display: none;
      position: absolute;
      left: 410px;
      top: 0;
      width: 500px;
      height: 500px;
      background-color: pink;
      z-index: 999;
      border: 1px solid #ccc;
      overflow: hidden;
    }

    .big img {
      position: absolute;
      top: 0;
      left: 0;
    }
  </style>
</head>

<body>
  <!-- 详情页内容部分	 -->
  <div class="de_container w">
    <!-- 产品介绍模块 -->
    <div class="product_intro clearfix">
      <!-- 预览区域 -->
      <div class="preview_wrap fl">
        <div class="preview_img">
          <img src="../images/s3.png" alt="">
          <div class="mask"></div>
          <div class="big">
            <img src="../images/big.jpg" alt="" class="bigImg">
          </div>
        </div>
      </div>
    </div>    
  </div>  
  <script>
    //等页面加载完毕在进行操作
    window.addEventListener('load',function(){
      var preview_img = document.querySelector('.preview_img')
      var mask = document.querySelector('.mask')
      var big = document.querySelector('.big')
      preview_img.addEventListener('mouseover',function(){
        mask.style.display = 'block'
        big.style.display = 'block'
      })
      preview_img.addEventListener('mouseout',function(){
        mask.style.display = 'none'
        big.style.display = 'none'
      })
      preview_img.addEventListener('mousemove',move)
      function move(e){
        var x = e.pageX - this.offsetLeft - mask.offsetWidth / 2
        var y = e.pageY - this.offsetTop - mask.offsetWidth / 2
        var maskMaxlength = preview_img.offsetWidth - mask.offsetWidth
        if(x <= 0){
          x = 0
        }
        if(y <= 0){
          y = 0
        }
        if(x >= maskMaxlength){
          x = maskMaxlength
        }
        if (y >= maskMaxlength){
          y = maskMaxlength
        }
        mask.style.left = x + 'px'
        mask.style.top = y + 'px'
       // 大图片的移动距离 / 大图片的最大移动距离 = 遮挡层移动距离 / 遮挡层的最大移动距离
        var bigImg = document.querySelector('.bigImg')
        //大图片的最大移动距离
        var bigmaxlength = big.offsetWidth - bigImg.offsetWidth 
        var bigX = x * bigmaxlength / maskMaxlength
        var bigY = y * bigmaxlength / maskMaxlength
        bigImg.style.left = bigX + 'px'
        bigImg.style.top = bigY + 'px'
      }
    })
  </script>
</body>

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

<head>
  <meta charset="UTF-8">
  <title>手机详情页!</title>
  <meta name="description"
    content="品优购JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
  <meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,品优购" />
  <style>
    .de_container {
      margin-top: 20px;
    }

    .crumb_wrap {
      height: 25px;
    }

    .crumb_wrap a {
      margin-right: 10px;
    }

    .preview_wrap {
      width: 400px;
      height: 590px;
    }
    .preview_img {
      position: relative;
      height: 398px;
      border: 1px solid #ccc;
    }

    .mask {
      display: none;
      position: absolute;
      top: 0;
      left: 0;
      width: 300px;
      height: 300px;
      background: #FEDE4F;
      opacity: .5;
      border: 1px solid #ccc;
      cursor: move;
    }

    .big {
      display: none;
      position: absolute;
      left: 410px;
      top: 0;
      width: 500px;
      height: 500px;
      background-color: pink;
      z-index: 999;
      border: 1px solid #ccc;
      overflow: hidden;
    }

    .big img {
      position: absolute;
      top: 0;
      left: 0;
    }
  </style>
</head>

<body>
  <!-- 详情页内容部分	 -->
  <div class="de_container w">
    <!-- 产品介绍模块 -->
    <div class="product_intro clearfix">
      <!-- 预览区域 -->
      <div class="preview_wrap fl">
        <div class="preview_img">
          <img src="../images/s3.png" alt="">
          <div class="mask"></div>
          <div class="big">
            <img src="../images/big.jpg" alt="" class="bigImg">
          </div>
        </div>
      </div>
    </div>    
  </div>  
  <script>
    //等页面加载完毕在进行操作
    window.addEventListener('load',function(){
      var preview_img = document.querySelector('.preview_img')
      var mask = document.querySelector('.mask')
      var big = document.querySelector('.big')
      preview_img.addEventListener('mouseover',function(){
        mask.style.display = 'block'
        big.style.display = 'block'
      })
      preview_img.addEventListener('mouseout',function(){
        mask.style.display = 'none'
        big.style.display = 'none'
      })
      preview_img.addEventListener('mousemove',move)
      function move(e){
        var x = e.pageX - this.offsetLeft - mask.offsetWidth / 2
        var y = e.pageY - this.offsetTop - mask.offsetWidth / 2
        
        var maskMaxlength = preview_img.offsetWidth - mask.offsetWidth
        if(x <= 0){
          x = 0
        }
        if(y <= 0){
          y = 0
        }
        if(x >= maskMaxlength){
          x = maskMaxlength
        }
        if (y >= maskMaxlength){//因为盒子是个正方形,所以可以用动y上
          y = maskMaxlength
        }
        mask.style.left = x + 'px'
        mask.style.top = y + 'px'
       // 大图片的移动距离 / 大图片的最大移动距离 = 遮挡层移动距离 / 遮挡层的最大移动距离
        var bigImg = document.querySelector('.bigImg')
        //大图片的最大移动距离
        var bigmaxlength = big.offsetWidth - bigImg.offsetWidth 
        var bigX = x * bigmaxlength / maskMaxlength
        var bigY = y * bigmaxlength / maskMaxlength
        //bigImg必须要有定位才行
        bigImg.style.left = bigX + 'px'
        bigImg.style.top = bigY + 'px'
      }
    })
  </script>
</body>

</html>

2.元素可视区 client 系列

client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列 的相关属性可以动态的得到该元素的边框大小、元素大小等。

淘宝 flexible.js 源码分析

flexible.js是手淘开发出的一个用来适配移动端的js框架。手淘框架的核心原理就是根据制不同的width给网页中html根节点设置不同的font-size,然后所有的px都用rem来代替,这样就实现了不同大小的屏幕都适应相同的样式了。其实它就是一个终端设备适配的解决方案,也就是说它可以让你在不同的终端设备中实现页面适配。

(function flexible(window, document) {
    var docEl = document.documentElement
    var dpr = window.devicePixelRatio || 1

    // adjust body font size
    function setBodyFontSize() {
        if (document.body) {
            document.body.style.fontSize = (12 * dpr) + 'px'
        } else {
            document.addEventListener('DOMContentLoaded', setBodyFontSize)
        }
    }
    setBodyFontSize();

    // set 1rem = viewWidth / 10
    function setRemUnit() {
        var rem = docEl.clientWidth / 10
        docEl.style.fontSize = rem + 'px'
    }

    setRemUnit()

    // reset rem unit on page resize
    window.addEventListener('resize', setRemUnit)
    window.addEventListener('pageshow', function(e) {
        if (e.persisted) {
            setRemUnit()
        }
    })

    // detect 0.5px supports
    if (dpr >= 2) {
        var fakeBody = document.createElement('body')
        var testElement = document.createElement('div')
        testElement.style.border = '.5px solid transparent'
        fakeBody.appendChild(testElement)
        docEl.appendChild(fakeBody)
        if (testElement.offsetHeight === 1) {
            docEl.classList.add('hairlines')
        }
        docEl.removeChild(fakeBody)
    }
}(window, document))
立即执行函数
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>手机详情页!</title>
  <meta name="description"
    content="品优购JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
  <meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,品优购" />

</head>

<body>
  
  <script>
    //普通函数
    function fn(){
      console.log(1);
    }
    fn();//当有多个函数时每个函数之间需要使用分号来结尾
    //立即执行函数:不需要调用,立马能够自己执行的函数
    //写法:(function(){})() 第二个小括号相当于调用函数 或者 (function(){}())
    (function(a,b){
      console.log(a + b);
    })(1,2)
  </script>
</body>

</html>

3.元素滚动 scroll 系列

scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。

<!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>Document</title>
    <style>
        .slider-bar {
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }
        
        .w {
            width: 1200px;
            margin: 10px auto;
        }
        
        .header {
            height: 150px;
            background-color: purple;
        }
        
        .banner {
            height: 250px;
            background-color: skyblue;
        }
        
        .main {
            height: 1000px;
            background-color: yellowgreen;
        }
        
        span {
            display: none;
            position: absolute;
            bottom: 0;
        }
    </style>
</head>

<body>
    <div class="slider-bar">
        <span class="goBack">返回顶部</span>
    </div>
    <div class="header w">头部区域</div>
    <div class="banner w">banner区域</div>
    <div class="main w">主体部分</div>
    <script>
        //1. 获取元素
        var sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        // banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
        var bannerTop = banner.offsetTop
            // 当我们侧边栏固定定位之后应该变化的数值
        var sliderbarTop = sliderbar.offsetTop - bannerTop;
        // 获取main 主体元素
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');
        var mainTop = main.offsetTop;
        // 2. 页面滚动事件 scroll
        document.addEventListener('scroll', function() {
            // console.log(11);
            // window.pageYOffset 页面被卷去的头部
            // console.log(window.pageYOffset);
            // 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位
            if (window.pageYOffset >= bannerTop) {
                sliderbar.style.position = 'fixed';
                sliderbar.style.top = sliderbarTop + 'px';
            } else {
                sliderbar.style.position = 'absolute';
                sliderbar.style.top = '300px';
            }
            // 4. 当我们页面滚动到main盒子,就显示 goback模块
            if (window.pageYOffset >= mainTop) {
                goBack.style.display = 'block';
            } else {
                goBack.style.display = 'none';
            }

        })
    </script>
</body>

</html>

4.动画函数封装

动画原理

<!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>Document</title>
  <style>
    div {
      position: absolute;
      left: 0;
      width: 100px;
      height: 100px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div></div>
  <script>
    // 动画原理
    // 1. 获得盒子当前位置  
    // 2. 让盒子在当前位置加上1个移动距离
    // 3. 利用定时器不断重复这个操作
    // 4. 加一个结束定时器的条件
    // 5. 注意此元素需要添加定位, 才能使用element.style.left
    var div = document.querySelector('div');
    var timer = setInterval(function () {
      if (div.offsetLeft >= 400) {
        // 停止动画 本质是停止定时器
        clearInterval(timer);
      }
      div.style.left = div.offsetLeft + 1 + 'px';
    }, 30);
  </script>
</body>

</html>

简单动画函数的封装

<!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>Document</title>
  <style>
    /**/
    div {
      position: absolute;/*定位必须得加*/
      left: 0;
      width: 100px;
      height: 100px;
      background-color: pink;
    }

    span {
      position: absolute;/*定位必须得加*/
      left: 0;
      top: 200px;
      display: block;
      width: 150px;
      height: 150px;
      background-color: purple;
    }
  </style>
</head>

<body>
  <div></div>
  <span>夏雨荷</span>
  <script>
    var div  = document.querySelector('div')
    var span = document.querySelector('span')
    animate(div,300)
    animate(span,200)
    //调用函数
    function animate(obj,target){
      clearInterval(obj.timer)//先清除以前定时器,只保留当前的一个定时器
      obj.timer = setInterval(function(){
        if(obj.offsetLeft > target){
          clearInterval(obj.timer)
        }
        obj.style.left = obj.offsetLeft + 1 + 'px'
      })
    }
  </script>
</body>

</html>

5.animate.js

function animate(obj, target, callback) {
    // console.log(callback);  callback = function() {}  调用的时候 callback()

    // 先清除以前的定时器,只保留当前的一个定时器执行
    clearInterval(obj.timer);
    obj.timer = setInterval(function() {
        // 步长值写到定时器的里面
        // 把我们步长值改为整数 不要出现小数的问题
        // var step = Math.ceil((target - obj.offsetLeft) / 10);
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if (obj.offsetLeft == target) {
            // 停止动画 本质是停止定时器
            clearInterval(obj.timer);
            // 回调函数写到定时器结束里面
            // if (callback) {
            //     // 调用函数
            //     callback();
            // }
            callback && callback();
        }
        // 把每次加1 这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 现在的位置) / 10
        obj.style.left = obj.offsetLeft + step + 'px';

    }, 15);
}

引用动画函数

<!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>Document</title>
    <style>
        .sliderbar {
            position: fixed;
            right: 0;
            bottom: 100px;
            width: 40px;
            height: 40px;
            text-align: center;
            line-height: 40px;
            cursor: pointer;
            color: #fff;
        }
        
        .con {
            position: absolute;
            left: 0;
            top: 0;
            width: 200px;
            height: 40px;
            background-color: purple;
            z-index: -1;
        }
    </style>
    <script src="animate.js"></script>
</head>

<body>
    <div class="sliderbar">
        <span>←</span>
        <div class="con">问题反馈</div>
    </div>

    <script>
        // 1. 获取元素
        var sliderbar = document.querySelector('.sliderbar');
        var con = document.querySelector('.con');
        // 当我们鼠标经过 sliderbar 就会让 con这个盒子滑动到左侧
        // 当我们鼠标离开 sliderbar 就会让 con这个盒子滑动到右侧
        sliderbar.addEventListener('mouseenter', function() {
            // animate(obj, target, callback);
            animate(con, -160, function() {
                // 当我们动画执行完毕,就把 ← 改为 →
                sliderbar.children[0].innerHTML = '→';
            });

        })
        sliderbar.addEventListener('mouseleave', function() {
            // animate(obj, target, callback);
            animate(con, 0, function() {
                sliderbar.children[0].innerHTML = '←';
            });

        })
    </script>
</body>

</html>

6.常见网页特效案例

轮播图

posted @ 2022-07-13 16:48  剑断青丝ii  阅读(473)  评论(0编辑  收藏  举报