zoukankan      html  css  js  c++  java
  • JavaScript知识点

    JavaScript-jQuery

    JavaScript:https://developer.mozilla.org/en-US/docs/Web/JavaScrip
    ES6:https://es6.ruanyifeng.com/
    MDN:https://developer.mozilla.org/zh-CN/
    w3School:https://www.w3school.com.cn/

    js中的对象有:内置对象,浏览器对象,自定义对象

    a++和++a的区别

    /*        
      a++:a先创建自身的一个副本,然后a自增1,最后返回副本的值。
      a=3;b=a++;
      运行后 b=3,a=4
      ++a:将a自增1并返回a。
      a=3;b=++a;
      运行后 b=4,a=4 */
        let n = 0
        console.log(n++) //0
        console.log(++n)//2
        console.log(n);//2
    

    JavaScript基础

    变量

    • 声明

    • 赋值

    数据类型

    js的变量数据类型,只有在程序运行过程中才能知道数据的具体类型
    js是动态语言,变量的数据类型是可以变化的
    1、简单数据类型(Number,String,Boolean,Undefined,Null)
    • Number数字类型
      • NaN :非数值,如果无法计算的返回的就是NaN
      • isNaN() :验证是否是数字 ,返回true或false

    • String字符串类型

      • 转义符都是以开头: ,\,',", ,
      • str.length:字符串长度
      • str+任何数据类型 :结果都是拼接好的字符串
    • Boolean布尔类型:ture 或false

    • Undefined未定义类型:一个变量声明,但是没有赋值

    • Null空值:number+null=number本身

    2、复杂数据类型(Object)

    判断数据类型

    1. typeof xx :返回结果只能有string,number,boolean,undefined,function,object

    2. A instanceof B 可以判断A是不是B的实例 :返回结果true/false

    3. Object.prototype.toString.call(xx)

    4. 对象的constructor判断:xx.constructor === Date/Function/Array...

    5. Jquery提供的

    • jQuery.isArray();是否为数组

    • jQuery.isEmptyObject();是否为空对象 (不含可枚举属性)。

    • jQuery.isFunction():是否为函数

    • jQuery.isNumberic():是否为数字

    • jQuery.isPlainObject():是否为使用“{}”或“new Object”生成对象,而不是浏览器原生提供的对象。

    • jQuery.isWindow(): 是否为window对象;

    • jQuery.isXMLDoc(): 判断一个DOM节点是否处于XML文档中。

    数据类型的转换

    转换为字符串
    • String(x)

    • x.toString(x, 10)

    • x+''

    转换为数字
    • Number(x)

    • parseInt(x, 10)

    • parseFloat(x)

    • x - 0

    • +x

    转换为 boolean
    • Boolean(x)

    • !!x

    0,NaN, '', null, undefined 转换为布尔型都是false

    补充:
    • 解释语言和编译语言

      • 解释语言:解释一行执行一行(如JavaScript
      • 编译语言:在代码执行前,先编译生成中间代码文件,才去执行代码(如java
    • 内存图

      • object存储的是地址
      • 基本类型存储的是值
      • stack和heap
    • 深复制和浅复制

    • 对于简单类型的数据来说,赋值就是深拷贝
      • 对于复杂类型的数据(对象)来说,才要区分浅拷贝和深拷贝。赋值是浅拷贝,拷贝heap内存是深拷贝*

    运算符

    1.算数运算符
    • + ,- ,*, /, %,

    • a++(a--)是先执行表百达式后再自增,执行表达式时使度用的是a的原值

    • ++a(--a)是先自增再执行表知达示,执行表达式时使道用的是自增后的a

    2.比较运算符

    < ,>,>=,<=,,!=,=,!==

    3.逻辑运算符
    • &&,||,!

    • 短路与:表达式1&&表达式2:1真返回2,1假返回1 (一旦发现假就结束,返回假的那个表达式)

    • 短命或:一旦发现真就结束,返回真。

    4.赋值运算符

    =,+=,-=,*=,/=,%=

    5.运算符优先级

    1)()

    2)++ -- !

    3)* / % + -

    4)> >= < <=

    5)== != === !==

    6) && ||

    7) =

    8) ,

    if语句

    • if

    • if-else

    • if-else if-else

    三元表达式

    • 表达式?执行语句1:执行语句2

    • 相当于if-else

    switch

    • 语法:
      switch (key) {
          case value:
            执行语句1
            break;
          case value2:
            执行语句2
            break;
          default:
            break;
        }
    
    • 注意:
      • key中的值和value是全等
      • 如果当前case里面没有break,就不会退出switch,会继续执行下一个case

    for循环

    for(初始变量;条件表达式;操作符){
        循环体
    }
    

    while循环

    while(条件表达式){
        循环体
    }
    

    do-while循环

    • 先执行一次循环体,再判断条件;如果条件为真,执行循环体,否则就退出

    • 语法:

     do {
          循环体
        } while (条件表达式);
    

    continue和 break

    • continue:立即跳出本次循环,继续下一次循环
    • break: 立即跳出整个循环

    函数

    1、声明函数:
    • function 函数名(){}
    • 调用:函数名()
    2、return作用:
    • 返回函数值
    • 终止函数(return语句之后的代码不执行)
    3、注意:
    • return只能返回一个值(一个数字,数组,对象都可以)
    • 如果函数没有return,返回的就是undefined
    4、arguments:
    • arguments实际上是当前函数的一个内置对象
    • arguments存储了传递的所有实参
    5、伪数组:不是真正意义上的数组
    • 具有数组的length属性

    • 按照索引的方式进行存储

    • 没有真正数组的一些方法如pop(),push()等

    6、函数表达式(匿名函数)
    • var 变量名=function(){}
    • 调用:变量名()

    作用域

    1、目的:提高程序可靠性,减少命名冲突
    2、全局作用域:在script标签或者js文件中
    3、局部作用域(函数作用域):在函数内部
    4、全局变量:
    • 在全局作用域下的变量
    • 浏览器关闭才会销毁,比较占内存资源
    5、局部变量:
    • 在局部作用域下的变量
    • 当程序执行完毕,就会销毁,比较节约内存资源
    6、作用域链:

    内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 (就近原则)

    7、注意:
    • 如果没有声明,直接赋值的变量是全局变量
    • 块级作用域:{} 【在es6中才出现的的】

    预解析

    1、预解析:var和function会被提升到当前作用域的最前面
    2、分类:
    • 变量预解析(变量提升):var 变量=值【相当于:var 变量;变量=值】

    • 函数预解析(函数提升):function fn() {}

    3、补充
    • 函数声明:可以先使用再声明

    • 函数表达式:必须先声明再使用

    对象

    1、创建对象的3种方式:
    • 字面量创建对象
    • new Object创建对象
    • 构造函数创建对象
    2、字面量创建对象
    	 *var 对象名={属性名:属性值,...,方法名:function(){}}*
    
    3、new Object创建对象
    	 *var变量名=new Object*
    
    4、构造函数创建对象(可以创建多个对象)
    • ​ *构造函数语法:
     function 构造函数名() {
              this.属性名=属性值;
              this.方法名=function(){}
            }
    
    • 使用构造函数:new 构造函数名()

    • ​ 注意:

      • 构造函数名首字母大写

      • 利用构造函数创建对象的过程,就是对象的实例化

    • new关键字的执行过程:

      1)new构造函数可以在内存中创建一个空的对象

    2)this就会指向刚才创建的对象

    3)执行构造函数里面的代码,给这个空对象添加属性和方法

      *4)返回这个对象*
    
    5、使用对象
    • 调用对象属性:
    • 对象名.属性名

    • 对象名['属性名']

    • 调用对象方法:
    • 对象名.方法名()
    6、for-in遍历对象
     for(var k in 对象) {
           console.log(k)//属性名,方法名
           console.log(对象[k])//属性值和方法
         }  
    

    Math对象js内置对象

    Math.PI

    Math.max(x)

    Math.min(x)

    Math.floor(x) 向下取值,往最小取

    Math.ceil(x) 向上取值,往最大取

    Math.round(x) 四舍五入

    Math.abs(x) 绝对值

    Math.random()*n [0,n)区间的随机数

    Math.floor(Math.random()*(m-n+1))+n [n,m]区间的随机数整数

    日期对象js内置对象*)

    	console.log(new Date());
        console.log(new Date('2020-4-11 8:8:8'));
        console.log(new Date(2020, 4, 11));
        // 获取当前时间戳
        console.log(new Date().valueOf());
        console.log(new Date().getTime());
        console.log(+new Date());
        console.log(Date.now());
    
        function formatTime() {
          var now = new Date()
          var y = now.getFullYear()
          var m = (now.getMonth() + 1 + '').padStart(1, '0')
          var d = (now.getDate() + '').padStart(1, '0')
          var w = now.getDay()
          var wArr = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
          var week = wArr[w]
          var hh = (now.getHours() + '').padStart(1, '0')
          var mm = (now.getMinutes() + '').padStart(1, '0')
          var ss = (now.getSeconds() + '').padStart(1, '0')
          return `${y}-${m}-${d}-${week} ${hh}:${mm}:${ss}`
        }
        // setInterval(() => {
        //   console.log(formatTime());
        // }, 1000);
        /* 案例:倒计时 */
        // 天:n/60/60/24
        // 时:n/60/60%24
        // 分:n/60%60
        // 秒: n%60
        function countDown(a) {
          var now = Date.now()
          var inputTime = +new Date(a)
          var time = (inputTime - now) / 1000
          var d = (parseInt(time / 60 / 60 / 24) + '').padStart(2, '0')
          var h = (parseInt(time / 60 / 60 % 24) + '').padStart(2, '0')
          var m = (parseInt(time / 60 % 60) + '').padStart(2, '0')
          var s = (parseInt(time % 60) + '').padStart(2, '0')
          return `${d}天 ${h}:${m}:${s}`
        }
        console.log(countDown('2020-4-13 18:50:00'));
    

    数组对象js内置对象

    • 检查是否是数组:

      • 数组 instanceof Array :返回true/false

      • Array.isArray(数组):返回true/false

    • arr.push(xx) 改变原数组,返回新数组的长度

    • arr.unshift(xx) 改变原数组,返回新数组的长度

    • arr.pop(xx) 改变原数组,返回删除元素

    • arr.shift() 改变原数组,返回删除元素

    • arr.reverse() 改变原数组

    • arr.sort() 改变原数组 【单位数好使,标准写法用下面】

     
          // 升序
          arr.sort(function (a, b) {
            return a - b
          })
          // 降序
            arr.sort(function (a, b) {
            return a - b
          })
    
    • arr.indexOf(x,start) 返回数组中第一个x的索引,如果没有返回-1 【正序查找】

    • arr.lastIndexOf(x) 同上【倒序查找】

    • arr.toString() 把数组转成字符串,逗号分隔每一项

    • arr.join('xx') 把数组转成字符串,xx分隔每一项

    • arr1.concat(arr2,arr3,...) 连接数组,返回新数组

    • arr.slice(begin,end) 返回被截取的新数组

    • arr.splice(start,deleteNumber,add1,add2...) 返回被删除的数组,影响原数组

        // 案例:数组去重
        function unique(arr) {
          var nArr = []
          for (var i = 0; i < arr.length; i++) {
            if (nArr.indexOf(arr[i]) === -1) {
              nArr.push(arr[i])
            }
          }
          return nArr
        }
        console.log(unique([1, 2, 5, 7, 22, 4, 2, 3, 4]));
    

    字符串对象(js内置对象

    0、基本包装类型:把String,Number,Boolean这些简单数据类型包装成复杂数据类型
    1、字符串是不可变的,所以字符串的所有方法都返回 一个新的字符串
    • str.length

    • str.indexOf(x,start) 从start开始查找,返回str中x第一次出现的索引,没有返回-1

    • str.charAt(index) 返回索引为index的字符

    • str.charCodeAt(index) 返回索引为index的字符的ASCII码

    • str[index] 返回索引为index的字符

    • str.concat(str1,str2...) 拼接字符串

    • str.substr(start, length) 截取字符串,从start截取length个

    • str.slice(start, end) 截取字符串,从start到end-1,end取不到

    • str.substring(start,end) 截取字符串,从start到end-1,end取不到。不接受负值

    • str.replace('aa','bb') 用bb替换str中的aa

    • str.split("xx") 用xx把字符串分割成数组,每一项用xx隔开

    • str.toLowerCase()

    • str.toUpperCase()

        /* 案例:查找字符串中o出现的位置已经次数 */
        var str = '1234ididhsidhadjidiii'
        var index = str.indexOf('d')
        var n = 0
        var arr = []
        // while (index !== -1) {
        //   arr.push(index)
        //   index = str.indexOf('d', index + 1)
        //   n++
        // }
        for (var i = 0; i < str.length; i++) {
          if (index !== -1) {
            arr.push(index)
            index = str.indexOf('d', index + 1)
            n++
          }
        }
        console.log(n, arr);
        console.log(str.charAt(2));
        console.log(str.charCodeAt(2));
        console.log(str[2]);
        /*案例:判断一个字符串中出现最多次数的字符,统计其次数 */
        var obj = {}
        for (var i = 0; i < str.length; i++) {
          console.log(str.charAt(i));
          var chars = str.charAt(i)
          if (obj[chars]) {
            obj[chars]++
          } else {
            obj[chars] = 1
          }
        }
        console.log(obj);
        var max = 0
        var ch
        for (var k in obj) {
          if (obj[k] > max)
            max = obj[k]
          ch = k
        }
        console.log(max, ch);
        var str2 = 'abcdefG'
        console.log(str2.concat('1', 'm', 'a'));
        console.log(str2.substr(0, 3));
        console.log(str2.slice(0, 3));
        console.log(str2.substring(0, 3));
        console.log(str2.toLowerCase());
        console.log(str2.toUpperCase());
    

    DOM文档对象

    获取元素

    • document.getElementById("id名")
    • element.getElementsByTagName('标签名') 伪数组存储
    • document.getElementsByClassName('类名') 伪数组存储
    • document.querySelector('选择器') 指定选择器的第一个元素对象
    • document.querySelectorAll('选择器') 指定选择器的所有元素对象,伪数组存储
    • 获取body元素:document.body
    • 获取html元素:document.documentElement
    • 补充:console.dir(xx) 打印返回的元素对象,方便查看里面的属性和方法

    改变元素内容

    • element.innerText 替换起始到终止的内容,去除html标签,空格,换行
    • element.innerHTML 替换起始到终止的内容,包括html标签,空格,换行 【用的比较多】

    这两个属性是可以读写的,可以获取元素里面的内容

    元素属性操作

    获取元素属性值
    • element.属性 【只能获取内置属性值】
    • element.getAttribute('属性') 【可以获取自定义属性值】
    设置元素属性并赋值
    • element.属性=属性值 【设置内置属性src,href,id,alt,title,type,value,checked,selected,disabled】
    • element.setAttribute(属性,属性值) 【设置自定义属性】
    删除元素属性
    • element.removeAttribute('属性')
    H5自定义属性(以 data-xx 格式的自定义的属性)*
    • 设置格式:data-xx

    • 获取:

      • element.getAttribute('data-xx')

      • element.dataset.xx

      • element.dataset['xx']

      • 如果自定义属性有多个-连接(data-lis-name),获取时采用驼峰命名法:element.dataset['listName']

    元素样式操作

    样式属性操作(大小,颜色,位置等)
    • element.style.样式名='值' 【行内样式】(如果是background-color这样的用驼峰命名法)
    • element.className='className' 【类名样式】(会覆盖原来的类)
    • 如果想要保留原来的类名: element.className='className oldClassName1 oldClassName2'

    排他思想

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <style>
        .btnBox {
    
          margin: 20px auto;
           100%;
          text-align: center;
        }
    
        .pink {
          background-color: pink;
        }
    
        .box {
          display: flex;
          margin: 0 300px;
          border: 4px solid #fff;
        }
    
        li {
          flex: 1;
          list-style: none;
    
        }
    
        img {
           100%;
          height: 200px;
        }
    
        body {
          background: url('./img/1.jpg') no-repeat center top;
        }
    
        table {
           800px;
          margin: 100px auto;
          text-align: center;
          border-collapse: collapse;
          font-size: 14px;
          background-color: #fff;
        }
    
        thead tr {
          height: 30px;
          background-color: skyblue;
        }
    
        tbody tr {
          height: 30px;
        }
    
        tbody td {
          border-bottom: 1px solid #d7d7d7;
          font-size: 12px;
          color: blue;
        }
    
        .bg {
          background-color: pink;
        }
    
        .wrap {
           300px;
          margin: 100px auto 0;
        }
    
        .wrap table {
          border-collapse: collapse;
          border-spacing: 0;
          border: 1px solid #c0c0c0;
           300px;
        }
    
        .wrap th,
        .wrap td {
          border: 1px solid #d0d0d0;
          color: #404060;
          padding: 10px;
        }
    
        .wrap th {
          background-color: #09c;
          font: bold 16px "微软雅黑";
          color: #fff;
        }
    
        .wrap td {
          font: 14px "微软雅黑";
        }
    
        .wrap tbody tr {
          background-color: #f0f0f0;
        }
    
        .wrap tbody tr:hover {
          cursor: pointer;
          background-color: #fafafa;
        }
      </style>
    </head>
    
    <body>
      <!-- 点击按钮变色 -->
      <div class="btnBox">
        <button>1</button>
        <button>2</button>
        <button>3</button>
        <button>4</button>
        <button>5</button>
      </div>
      <!-- 百度换肤 -->
      <ul class="box">
        <li><img src="./img/1.jpg" alt=""></li>
        <li><img src="./img/2.jpg" alt=""></li>
        <li><img src="./img/3.jpg" alt=""></li>
        <li><img src="./img/4.jpg" alt=""></li>
      </ul>
      <!-- 表格经过变色 -->
      <table>
        <thead>
          <tr>
            <th>代码</th>
            <th>名称</th>
            <th>最新公布净值</th>
            <th>累计净值</th>
            <th>前单位净值</th>
            <th>净值增长率</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>003526</td>
            <td>农银金穗3个月定期开放债券</td>
            <td>1.075</td>
            <td>1.079</td>
            <td>1.074</td>
            <td>+0.047%</td>
          </tr>
          <tr>
            <td>003526</td>
            <td>农银金穗3个月定期开放债券</td>
            <td>1.075</td>
            <td>1.079</td>
            <td>1.074</td>
            <td>+0.047%</td>
          </tr>
          <tr>
            <td>003526</td>
            <td>农银金穗3个月定期开放债券</td>
            <td>1.075</td>
            <td>1.079</td>
            <td>1.074</td>
            <td>+0.047%</td>
          </tr>
          <tr>
            <td>003526</td>
            <td>农银金穗3个月定期开放债券</td>
            <td>1.075</td>
            <td>1.079</td>
            <td>1.074</td>
            <td>+0.047%</td>
          </tr>
          <tr>
            <td>003526</td>
            <td>农银金穗3个月定期开放债券</td>
            <td>1.075</td>
            <td>1.079</td>
            <td>1.074</td>
            <td>+0.047%</td>
          </tr>
          <tr>
            <td>003526</td>
            <td>农银金穗3个月定期开放债券</td>
            <td>1.075</td>
            <td>1.079</td>
            <td>1.074</td>
            <td>+0.047%</td>
          </tr>
        </tbody>
      </table>
      <!-- 表单全选和取消全选 -->
      <div class="wrap">
        <table>
          <thead>
            <tr>
              <th>
                <input type="checkbox" id="j_cbAll" />
              </th>
              <th>商品</th>
              <th>价钱</th>
            </tr>
          </thead>
          <tbody id="j_tb">
            <tr>
              <td>
                <input type="checkbox" />
              </td>
              <td>iPhone8</td>
              <td>8000</td>
            </tr>
            <tr>
              <td>
                <input type="checkbox" />
              </td>
              <td>iPad Pro</td>
              <td>5000</td>
            </tr>
            <tr>
              <td>
                <input type="checkbox" />
              </td>
              <td>iPad Air</td>
              <td>2000</td>
            </tr>
            <tr>
              <td>
                <input type="checkbox" />
              </td>
              <td>Apple Watch</td>
              <td>2000</td>
            </tr>
          </tbody>
        </table>
      </div>
      <script>
        /* 案例:点击按钮变色 */
        var btns = document.querySelectorAll('button')
        for (var i = 0; i < btns.length; i++) {
          btns[i].onclick = function () {
            // 去掉其他人,只设置我自己
            for (var i = 0; i < btns.length; i++) {
              btns[i].className = ''
            }
            this.className = 'pink'
          }
        }
        /* 案例:百度换肤 */
        var imgs = document.querySelectorAll('img')
        for (var i = 0; i < imgs.length; i++) {
          imgs[i].onclick = function () {
            document.body.style.backgroundImage = `url(${this.src})`
            console.log(this.src);
          }
        }
        /* 案例:表格经过变色 */
        var tbody = document.querySelector('tbody')
        var trs = document.querySelectorAll('tr')
        for (var i = 0; i < trs.length; i++) {
          trs[i].onmouseover = function () {
            this.className = 'bg'
          }
          trs[i].onmouseout = function () {
            this.className = ''
          }
        }
        /* 案例:表单全选和取消全选 */
        var all = document.querySelector('#j_cbAll')
        var others = document.querySelector('#j_tb').querySelectorAll('input')
        all.onclick = function () {
          for (var i = 0; i < others.length; i++) {
            others[i].checked = this.checked
          }
        }
        for (var i = 0; i < others.length; i++) {
          others[i].onclick = function () {
            var flag = true
            // 检查是否全部都选中,全选中all就是true,否则就是false
            for (var i = 0; i < others.length; i++) {
              if (!others[i].checked) {
                // all.checked = false
                flag = false
                break
              }
            }
            all.checked = flag
          }
        }
      </script>
    </body>
    
    </html>
    

    获取节点

    节点:nodeType节点类型,nodeName节点名称,nodeValue节点值*
    • 元素节点:nodeType=1
    • 属性节点:nodeType=2
    • 文本节点:nodeType=3 (包括文字,空格,换行等)
    父节点: node.parentNode 亲父亲(如果找不到返回null)
    子节点
    • node.childNodes 所有子节点,包括文本节点元素节点
    • node.firstChild 第一个子节点
    • node.children 所有子元素节点
    • node.firstElementChild 第一个子元素节点
    • node.lastElementChild 最后一个子元素节点
    • node.children[0] 第一个子元素节点
    • node.children[node.children.length-1] 最后一个子元素节点
    兄弟节点
    • node.nextSibling 下一个兄弟节点
    • node.nextElementSibling 下一个兄弟元素节点
    • node.previousSibling 前一个兄弟节点
    • node.previousElementSibling 前一个兄弟元素节点

    节点操作

    创建节点
    • document.createElement('tagName')
    添加节点
    • node.appendChild(child) 在node节点中的末尾 添加child
    • node.insertBefore(child, 指定元素) 在node节点中的指定元素前面 添加child
    删除节点
    • node.removeChild(child) 删除node节点中的child节点,返回删除节点
    复制节点
    • node.cloneNode() 只复制节点本身
    • node.cloneNode(false) 只复制节点本身
    • node.cloneNode(true) 复制节点本身和子节点
    三种动态创建元素的区别
    • document.write(xxx) 如果文档流执行完毕,它会导致页面重绘
    • element.innerHTML=xxx 【创建多个效率更高,采用数组形式拼接】
    • document.createElement('tagName') 【创建多个效率稍低,但结果清晰】

    事件

    • 事件三要素:事件源,事件类型,事件处理程序
    • 注册和删除事件
      • 传统方式【能绑定一个事件】

        //注册
        element.on事件类型=function(){} 
        //删除
        element.on事件类型=null
        
      • 监听注册方式可以绑定多个事件,常用】

        //注册 (第三个参数可有可无,默认false。false在冒泡阶段调用事件处理程序,true在捕获阶段调用事件处理程序)
        element.addEventListener('事件类型', fn,true/false)
        function fn() {}
        //删除
        element.removeEventListener('事件类型',fn)
        
      • 只有ie9以前才支持

        //注册  
        element.attachEvent('on事件类型', fn)
        function fn() {}
        //删除
        element.detachEvent('on事件类型',fn)
        
    • DOM事件流的3个阶段
      • 捕获阶段: element.addEventListener('事件类型', fn,true)

      • 当前目标阶段

      • 冒泡阶段 element.addEventListener('事件类型', fn,false)或 element.addEventListener('事件类型', fn)

      • 注意: (1 )S代码只能执行捕获或者冒泡中的一个阶段 。(2)传统方式和attachEvent只能得到冒泡阶段

    事件对象

    事件对象的定义:事件对象只有有了事件才会存在,在事件的侦听函数的小括号里面。当成形参看。是系统自动创建的

    element.addEventListener('事件类型', function(event) {
        console.log(event)
    })
    //事件对象的名称是自己命名的,常用e
    
    • 事件对象常见属性和方法:

      • 1、普通浏览器:

      • e.target 触发事件的对象

        • e.type 事件类型
      • e.preventDefault() 阻止默认行为

        • e.stopPropagation() 阻止冒泡
      • 2、低版本浏览器:

      • e.srcElement 触发事件的对象

        • e.returnValue 阻止默认行为
      • e.cancelBubble 阻止冒泡

    【传统方式return false 也可以阻止默认行为,return后面的代码不执行了】

    • 补充:
      • 事件里面的this指向的是事件函数的调用者

      • this返回的是绑定事件的对象

      • e.target或e.srcElement 触发事件的对象

    事件委托

    事件委托核心原理:给父节点添加侦听器,利用事件冒泡影响每一个子节点

    常用鼠标事件和鼠标事件对象

    • 鼠标事件:
      • click

      • mouseover(鼠标经过自身盒子会触发,进过子盒子也会触发。会冒泡)

      • mouseout

      • mouseenter(只会经过自身盒子触发。不会冒泡)

      • mouseleave(不会冒泡)

      • focus

      • blur

      • mousemove

      • mouseup

      • mousedown

    // 禁止鼠标右键菜单
        document.addEventListener('    contextmenu', function (e) {
          e.preventDefault()
        })
    //禁止鼠标选中
        document.addEventListener('selectstart', function (e) {
          e.preventDefault()
        })
    
    • 鼠标事件对象
      • e.clientX 可视区域
      • e.clientY
      • e.pageX 文档页面
      • e.pageY
      • e.screenX 电脑屏幕
      • e.screenY

    常用键盘事件和键盘事件对象

    键盘事件:
    • keyup
    • keydown
    • keypress
    • 执行顺序:keydown,keypress,keyup
        // 键盘事件
        document.addEventListener('keyup', function (e) {
          console.log('keyup');
        })
        document.addEventListener('keydown', function (e) {
          console.log('keydown');
        })
    //keypress不识别功能键,如ctrl,shift等
        document.addEventListener('keypress', function (e) {
          console.log('keypress');
        })
    //keyup,keydown事件不区分字母大小写
    
    键盘事件对象
    • keycode 返回该键的ASCII码
    • keyup,keydown事件不区分字母大小写

    BOM浏览器对象

    window常见事件

    1、窗口加载事件:
    //load事件 是等页面全部加载完毕(包括dom元素,img,flash,css等;
    // window.onload=function() {}
        window.addEventListener('load',function() {})
    // DOMContentLoaded事件 是dom加载完毕
        window.addEventListener('DOMContentLoaded',function() {})
    
    • load事件 是等页面全部加载完毕(包括dom元素,img,flash,css等;
    • DOMContentLoaded事件 是dom加载完毕
    2、调整窗口大小事件
      //window.onresize=function(){}
        window.addEventListener('resize', function () {}) 
    
    • window.addEventListener('resize', function () {}) 或 window.onresize=function(){}

    定时器

    1、 setTimeout

        setTimeout(() => {},延迟时间)
        clearTimeout(定时器名字) 清除定时器
    

    2、 setInterval

       setInterval(() => { }, 间隔时间)
        clearInterval(定时器名字) 清除定时器
    

    3、如果第二个时间参数不写,默认是0(单位是毫秒)】

    this指向

    1. 一般情况下,this指向的是调用它的对象
    2. 全局作用域或者普通函数中的this指向全局对象window
    3. 定时器里面的this指向window
    4. 对象方法中的this指向调用该方法的对象
    5. 构造函数中的this指向构造函数的实例
    6. 事件中的this,指向的是绑定事件的对象

    URL

    • 格式 :protocol://host[:port]/path[?query]#fragment
    • 协议
    • 主机(域名)
    • 端口号
    • 路径:由0个或者多个/ 隔开
    • 参数:以键值对形式,通过&符号分隔
    • 片段:常见链接或锚点

    location对象

    • location.href 整个URL【常用】
    • location.host
    • location.port
    • location.pathname
    • location.search 参数【常用】
    • location.hash 片段
    • location.assign('path') 跳转页面
    • location.replace('path') 替换当前页面,无历史记录
    • location.reload() 重新加载页面【location.reload(true)强制刷新】
         // 判断用户是那个终端打开,实现跳转
          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 = ""; //电脑
                }
    

    history对象

    • hisory.back()
    • hisory.forward()
    • hisory.go(n)

    元素偏移量offset

    1、【以带有定位的父级为准,如果没有父级或者父级无定位,就相当于body】
    • element.offsetTop
    • element.offsetLeft
    2、【padding+border+width/height 返回数值无单位】
    • element.offsetWidth
    • element.offsetHeight
    3、返回带有定位的父亲,否则返回body
    • element.offsetParent
    4、offset和style区别
    • 获取元素大小和位置:element.offsetWidth/offsetHeight 【padding+border+widht 返回数值,只可读】
    • 元素改变大小:element.style.width/height 【width 返回有单位的字符串,可读可赋值】

    元素可视区client

    • element.clientTop【上边框的大小】
    • element.clientLeft【左边框的大小】
    • element.clientWidth【padding+width 返回数值】
    • element.clientHeight 【padding+height 返回数值】

    元素滚动scroll

    • element.scrollTop 【元素被卷去的上侧距离,返回数值】

    • element.scrollLeft 【元素被卷去的左侧距离,返回数值】

    注意:(scrollTop 和scrollLeft一般在scroll事件中获取)

    • element.scrollWidth 【真正的内容width+padding,返回数值】

    • element.scrollHeight 【真正的内容height+padding,返回数值】

    补充:

    • 页面被卷去的头部:window.pageYOffset
    • 页面被卷去的左侧:window.pageXOffset
    • 返回顶部:window.scroll(0,0)

    立即执行函数

    • 格式:(function(){})()或(function(){}())

    • 作用:创建一个独立的作用域,避免命名冲突

    • 补充:

    • dpr物理像素比:window.devicePixelRatio
    • pageshow是重新加载页面触发的事件,这个事件是给window添加的
      • 如果是从缓存取过来的页面:那么pageshow事件中的e.persisted返回的是true

    移动端

    触摸事件
    • touchstart
    • touchmove
    • touchend
    触摸事件对象
    • e.touches 当前触摸屏幕的所有手指列表
    • e.targetTouches 当前手指触摸的列表
    • e.targetTouches[0] 当前触摸元素的第一个手指的相关信息
    • e.changedTouches 手指状态发生了改变列表,无到有或有到无
    • 移动端拖动原理:盒子原来的位置+手指移动的距离
    • 手指移动的距离:手指滑动后的位置-手指刚开始触摸的位置
    解决移动端延迟3毫秒
        //使用fastclick :
        //1、引入js
        //2、在点击事件之前写入:
          if ('addEventListener' in document) {
                document.addEventListener('DOMContentLoaded', function () {
                  FastClick.attach(document.body);
                }, false);
              }
    	//3、正常注册点击事件
    
    *移动端插件
    移动端框架

    classList 返回元素的类名

    element.classList.add('className') 添加类名 是在后面追加类名不会覆盖以前的类名

    element.classList.reomve('className') 删除类名

    element.classList.toggle('className') 切换类

    本地存储

    sessionStorage
    • 存储数据 sessionStorage.setItem('key',value)
    • 获取数据 sessionStorage.getItem('key')
    • 删除数据 sessionStorage.removeItem('key')
    • 清空所有数据 sessionStorage.clear()
    localStorage
    • 存储数据 localStorage.setItem('key',value)
    • 获取数据 localStorage.getItem('key')
    • 删除数据 localStorage.removeItem('key')
    • 清空所有数据 localStorage.clear()

    JavaScript高级

    对象和类

    1、创建类
    //类名,首字母大写
       class Star {
          constructor(uname, age) {
            this.uname = uname
            this.age = age
          }
          sing(a) {
            console.log("我的作品:", a);
          }
        }
    
    2、利用类创建对象
        var wyf = new Star('kris', 29)
        console.log(wyf.uname, wyf.age);
        wyf.sing('july')
    
    3、类的继承
    // class Son extends Father{} 【Son类继承了Father类里面的方法和属性】
    // sper 可以调用父类的构造函数或普通函数;super必须在子类this之前调用
    // 继承中的属性和方法查找原则:就近原则
    // 类里面共有的属性和方法一定要加this
        class Father {
          constructor(x, y) {
            this.x = x
            this.y = y
          }
          sum() { console.log(this.x + this.y); }
          money(a) { console.log(a)}
          say() { console.log("我是father")}
        }
    
        class Son extends Father {
          constructor(x, y) {
            super(x, y) //super调用了父类里面的构造函数
            this.x = x
            this.y = y
          }
          say() {
            console.log("我是son")
            super.say() //super调用了父类里面的普通函数
          }
          substract() { console.log(this.x - this.y); }
        }
        var ss = new Son(10, 20)
        ss.money(100)
        ss.sum()
        ss.say()
        ss.substract()
    
    
    
    4、类中this的指向

    constructor里面的this指向创建的实例化对象

    类中方法的this指向 调用该方法的对象

    构造函数和原型

    利用构造函数创建对象
         // 利用构造函数创建对象
        function Star(name, age) {
          //  实例成员:构造函数内部通过this添加的成员,如name,age等
          // 实例成员只能通过实例化的对象来访问
          this.name = name
          this.age = age
          this.sing = function (a) {
            console.log(a);
          }
        }
        /* new在执行时会做4件事情:
              1、在内存中创建一个新的空对象
              2、让this指向这个空对象
              3、执行构造函数里面的代码,给这个新对象添加属性和方法
              4、返回这个新对象(所以构造函数里面不需要return) 
            */
    
        var wyf = new Star('kris', 29)
        console.log(wyf.name, wyf.age);
        wyf.sing('july')
        // 静态成员:在构造函数身上直接添加的成员
        // 静态成员只能通过构造函数来访问
        Star.sex = "男"
        console.log(Star.sex);
        /* 构造函数原型对象prototype
              原型对象的作用:共享方法
              公共属性定义到构造函数里面,公共方法放在原型对象身上
              对象身上系统自己添加一个__proto__属性,指向构造函数的原型对象【对象.__proto__ === 构造函数.prototype】
              方法查找规则:先去对象找,如果没有去构造函数原型对象prototype上找 
            */
        // console.dir(Star);
        Star.prototype.eating = function () {
          console.log("我在吃饭");
        }
        // Star.prototype = {
        //   constructor:Star,
        //   movie: function () {
        //     console.log('movie');
    
        //   },
        //   drink: function () {
        //     console.log("drink");
        //   }
        // }
        wyf.eating()
        console.log(wyf);
        console.log(wyf.__proto__ === Star.prototype);
        console.log(Star.prototype);
        console.log(Star.prototype.__proto__ === Object.prototype);
        console.log(Object.prototype.__proto__);
        console.log(wyf.toString());
    
    构造函数中的this指向
    • 构造函数中的this指向对象实例.
    • 构造函数中方法中的this指向调用该方法的对象.
    • 原型对象函数中的this指向对象实例.
    扩展内置对象
        // 扩展内置对象
        console.dir(Array.prototype);
        Array.prototype.sum = function () {
          var sum = 0
          for (var i = 0; i < this.length; i++) {
            sum += this[i]
          }
          return sum
        }
        var arr = [1, 2, 3, 4]
        console.log(arr.sum());
    
    构造函数的继承
     // 借用call()继承父类中的属性
        function Father(name, age) {
          this.name = name
          this.age = age
        }
        function Son(name, age, sex) {
          Father.call(this, name, age)
          this.sex = sex
        }
        var son = new Son('kris', 29, '男')
        console.log(son);
        // 借用原型对象继承父类中的方法
        Father.prototype.money = function () {
          console.log("money");
        }
        son.prototype=new Father()
        Son.prototype.constructor=Son
        Son.prototype.home = function () {
          console.log("home");
        }
    

    数组新增方法

    • forEach()
    • map()
    • filter() 返回新数组
    • some() 返回ture/false 找到第一个满足条件的就终止循环
    • every() 返回ture/false
    • reduce()

    字符串新方法

    • str.trim() 去除字符串两边的空格

    对象方法

    定义新属性或修改属性
     Object.defineProperty(对象,'属性名',{
          value:属性值,
          writable:true, //是否允许重写
          enumerable:true,//是否可以被枚举 (默认false,false不允许被遍历)
          configurable:true//是否可以被删除或修改特性(默认false,false不允许被删除)
        }) 
    

    函数进阶

    函数定义
    • 自定义函数:function fn()
    • 数表达式(匿名函数):var fun = function () {}
    • 利用new Function('参数1','参数2','函数体')
    函数调用
    • fn()
    • fn.call()
    • 对象.函数名()
    • 立即执行函数
    this指向
    • 普通函数中的this指向window
    • 对象中的方法的this指向调用该方法的对象
    • 构造函数中的this指向实例对象
    • 构造函数的原型对象上的方法指向实例对象
    • 绑定事件中的this指向函数的调用者
    • 定时器里面的this指向window
    • 立即执行函数里面的this指向window
    改变函数内部 this指向

    fn.call(thisArg,参数1,参数2,...) 调用fn,同时把fn中的this指向thisArg

    fn.apply(thisArg,[参数1,参数2,...]) 调用fn,同时把fn中的this指向thisArg,apply只能传递数组(或者伪数组)

    fn.bind(this.Arg,参数1,参数2,...) 不调用fn,fn中的this指向thisArg,返回原函数this指向改变之后一个新函数

      // 求数组中的最大值
        var arr = [1, 33, 4, 6, 7, 9, 10]
        console.log(Math.max(...arr));
        // apply可以用来求数组中的最大值
        console.log(Math.max.apply(Math, arr));
    
    严格模式
    • 开启严格模式:"use strict" 【放在script的最前面或者函数中的最前面】

    • 变化:

      • 变量必须先声明再使用

      • 已经声明的变量不能删除

      • 全局作用域下函数中的this是undefined

      • 构造函数不加new调用 ,this会报错

      • 函数中不能有重名的形参

      • 不允许在非函数块声明函数

    高级函数:把函数作为形参或者返回值的函数

    闭包

    • 定义:一个函数(作用域)访问了另一个函数中的局部变量,这个局部变量所在的函数称为闭包
    • 作用:延伸了变量的作用范围
    • 补充:立即执行函数也称为小闭包

    递归函数

    • 函数内部自己调用自己,这个函数就是递归函数
    • 递归里面必须加退出条件

    浅拷贝和深拷贝

    浅拷贝

    Object.assign(target,...被拷贝对象)

    深拷贝
    • 封装函数:

      
          function deepClone(obj) {
            let objClone = Array.isArray(obj) ? [] : {};
            if (obj && typeof obj === "object") {
              for (key in obj) {
                // obj.hasOwnProperty("属性")返回true/false,判断obj是否包含特定的自身(非继承)属性
                if (obj.hasOwnProperty(key)) {
                  // 判断 obj 是否是对象,如果是,递归复制
                  if (obj[key] && typeof obj[key] === "object") {
                    objClone[key] = deepClone(obj[key]);
                  } else {
                    // 如果不是
                    objClone[key] = obj[key];
                  }
                }
              }
            }
            return objClone
          }
      
          function deepClone2(newObj, oldObj) {
            for (var k in oldObj) {
              var item = oldObj[k]
              // 判断属性值的数据类型
              if (item instanceof Array) {
                newObj = []
                deepClone2(newObj[k], item)
              } else if (item instanceof Object) {
                newObj = {}
                deepClone2(newObj[k], item)
              } else {
                newObj[k] = item
              }
            }
          }
          var o2={}
          deepClone2(o2,obj)
          console.log(o2);
      
    • JSON.parse(JSON.stringify(被拷贝对象))

    • $.extend(true, target, 被拷贝对象);

    正则表达式

    作用:表单验证,替换敏感词,提取相关内容
    创建正则表达式:
    • var xx=/表达式/
    • var xx=/表达式/
    测试正则表达式:
    • 正则表达式.test(要测试的str)
    特殊字符:
       abc   包含abc就可以
        ^abc  必须以abc开头
        ^abc$ 必须是abc
        [abc]  包含三个中的任何一个
        ^[abc]$ 必须是三个中的任何一个
        ^[a-z]$ 必须是26个小写字母中的任何一个
        ^[a-zA-Z]$ 必须是26大小写个字母中的任何一个
        ^[a-zA-Z0-9]$ 必须是26大小写个字母,0-9数字中的任何一个
        ^[a-zA-Z0-9_-]$ 必须是26大小写个字母,0-9数字,_,- 中的任何一个
        ^[^a-zA-Z0-9_-]$ 不能是26大小写个字母,0-9数字,_,- 中的任何一个 【中括号里面的^表示取反】
        [0-9] 包含0-9中的任何一个
        * 重复 >=0次
        + 重复 >=1次
        ? 重复0或1次
        {n} 重复n次
        {n,} 重复 >=n次
        {n,m} 重复n到m次
        d 就是 [0-9]
        D [^0-9]
        w [a-zA-Z0-9]
        W [^a-zA-Z0-9]
        s [	
    vf] 换行符,制表符,空格符
        S [^	
    vf]
        | 表示或
    	替换: str.replace(str1或正则表达式,str2)
    	/表达式/g  全局匹配
    	/表达式/i  忽略大小写
    	/表达式/gi 全局匹配+忽略大小写
    
  • 相关阅读:
    哈夫曼编码-C语言实现
    KMP和BF算法-C语言实现
    Spring框架(1)--只是入门
    MyBatis(1)
    antd TreeSelect 无限级选择
    download下载文件
    react搭建项目问题
    js 数组转tree结构
    反映复制到剪贴板(npm安装)
    js前端实现Table导出excel表格
  • 原文地址:https://www.cnblogs.com/xiaojimeng/p/12821091.html
Copyright © 2011-2022 走看看