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

1、Math内置对象
Math.abs(x):返回一个数的绝对值。
Math.ceil(x):向上取整,返回大于或等于给定数的最小整数。
Math.floor(x):向下取整,返回小于或等于给定数的最大整数。
Math.round(x):四舍五入,返回给定数的最接近的整数。
Math.max(x1, x2, ..., xn):返回一组数中的最大值。
Math.min(x1, x2, ..., xn):返回一组数中的最小值。
Math.pow(x, y):返回 x 的 y 次幂。
Math.sqrt(x):返回一个数的平方根。
Math.random():返回一个介于 0 到 1 之间的随机数。
Math.sin(x):返回一个数的正弦值。
Math.cos(x):返回一个数的余弦值。
Math.tan(x):返回一个数的正切值。
Math.log(x):返回一个数的自然对数(以 e 为底)。
Math.exp(x):返回 e 的指数(e^x)。
Math.floor(x):返回小于或等于给定数的最大整数。
Math.PI:表示圆周率 π 的常量。
      // Math中一些常见的方法和属性
      console.log(Math.PI); //3.14159
      // floor方法表示向下取整,floor是地板的意思,不管小数多大,都是向下取整
      console.log(Math.floor(1.1)); //1
      console.log(Math.floor(1.9)); //1
      console.log(Math.floor(-1.1)); //-2
      console.log(Math.floor(-1.9)); //-2
      // ceil方法表示向上取整,ceil是天花板的意思,不管小数多小,都是向上取整
      console.log(Math.ceil(1.1)); //2
      console.log(Math.ceil(1.9)); //2
      console.log(Math.ceil(-1.1)); //-1
      console.log(Math.ceil(-1.9)); //-1
      // round方法进行四舍五入,在正数方面,正常进行四舍五入,但是如果是负数,四舍五入就是数值靠近哪个值就取哪个值
      // 但是负数中,-1.5进行四舍五入结果是-1,-1.1结果是-1,-1.9结果是-2
      console.log(Math.round(1.1)); //1
      console.log(Math.round(1.9)); //2
      console.log(Math.round(-1.1)); //-1
      console.log(Math.round(-1.9)); //-2
      console.log(Math.round(-1.5)); //-1
      console.log(Math.abs(-1)); //1
猜数字游戏:

      var result = Math.round(Math.random() * 10 + 1);
      console.log(result);
      var num = prompt("请输入的猜的数字:");
      while (result != num) {
        if (result > num) {
          alert("猜小了!");
        } else {
          alert("猜大了!");
        }
        num = prompt("请输入的猜的数字:");
      }
      alert("猜对了!" + result);
2、Date内置对象
      let date = new Date();
      console.log(date.getTime()); //获取毫秒数
      console.log(date.getFullYear()); //获取年份
      console.log(date.getMonth() + 1); //获取月份
      console.log(date.getDay()); //获取星期几(0是星期日,6是星期六)
      console.log(date.getHours()); //小时
      console.log(date.getMinutes()); //分钟
      console.log(date.getSeconds()); //秒
      console.log(date.getDate()); //获取当天日期
      console.log(date.getMilliseconds()); //获取毫秒
计算机上,时间的字符串表示有三种形式:
'2022-9-9 9:9:9'这种的表示没有在日期和时间点之间出现T,所以数值中,如果书简数值小于10,就不需要再前面加上0;

'2022-09-09T09:09:09'这种表示再日期和时间之间出现T的,如果时间数值小于10,就需要在数值前面加上0;
(只要在时间中出现T的,时间的数值小于10,就需要在数值前面加0)但是以上两种出现的情况是查找出来的月份是比现实中小于1的,所以可以手动加1
    
'December 9,2022 8:8:8'或者'December 09,2022 8:8:8'时间中不出现T,这种表示查找出来的月份是和现实中相同

      var birthday = new Date("December 17,1995 03:24:00");
      console.log(birthday.getFullYear());
      console.log(birthday.getMonth());
      console.log(birthday.getDate());
      console.log(birthday.getHours());
      console.log(birthday.getMinutes());
      console.log(birthday.getSeconds());
      console.log("---------------------");
      var birthday = new Date("1995-02-17 3:24:00");
      console.log(birthday.getFullYear());
      console.log(birthday.getMonth() + 1);
      console.log(birthday.getDate());
      console.log(birthday.getHours());
      console.log("---------------------");
      // 注意:使用中间有T字符的,数值小于10的需要补0
      var birthday = new Date("1995-02-17T03:24:00");
      console.log(birthday.getFullYear());
      console.log(birthday.getMonth() + 1);
      console.log(birthday.getDate());
      console.log(birthday.getHours());
      var birthday = new Date(1995, 11, 17);
      console.log(birthday);
      var birthday = new Date(1995, 11, 17, 3, 24, 0);
      console.log(birthday);
获得Date总的毫秒数(时间戳),不是当前时间的毫秒数,而是举例1970年1月1日过了多少毫秒数
1、通过valueOf()  getTime()

      var date1 = new Date();
      console.log(date1.valueOf());

      var date2 = new Date();
      console.log(date2.getTime());

      // 如果不在new Date()前面加上+的话,返回的是年月日时间的格式
      var date = +new Date();
      console.log(date);

      // H5新增的写法,有IE兼容性问题
      console.log(Date.now());
3、数组和数组的方法
常见的创建数组的几种方式:

1、字面量方式:

var array2 = [1, 2, 3];// 创建一个包含初始值的数组


2、使用构造函数方式:

var array5 = new Array(1, 2, 3);         // 创建一个包含初始值的数组

3、使用 Array.from() 方法:

var array7 = Array.from([1, 2, 3]);      // 从类数组对象或可迭代对象创建数组
var array8 = Array.from('hello');        // 从字符串创建包含每个字符的数组

4、使用 Array.of() 方法:

var array9 = Array.of(1, 2, 3);          // 创建一个包含指定元素的数组
var array10 = Array.of('apple', 'banana', 'orange');  // 创建一个包含字符串元素的数组
检测是否为数组的方法:

检测数据是否为数组的方法,返回的都是true和false
1、instanceof    
2、Array.isArray(数据对象)  

      var arr = [];
      console.log(arr instanceof Array);//true
      console.log(Array.isArray(arr));//true
1、向数组中添加一个元素,返回结果是数组的长度,push()括号中的参数是需要添加进行的元素的值,也可以一次性添加多个

2、pop是将数组中的最后一个元素给删除,返回结果是被删除的元素的值,改变原数组

3、unshift是向数组的头部添加元素的值,使用和push()函数差不多,都是添加元素也可以一次性添加多个元素

4、shift是删除数组头部的第一个元素,数组长度减1,函数括号中没有参数,修改原数组,返回值是被删除的元素的值

      let arr1 = [];
      console.log(arr1.push(1, 2, 3, 4));//向数组最后位置添加一个元素,输出结果是数组的长度
      console.log(arr1);//这里输出数组的内容

      let arr2 = [];
      console.log(arr2.unshift(1, 2, 3, 4));//向数组最前位置添加一个元素,结果是数组的长度
      console.log(arr2);//这里输出数组的内容

      let arr3 = [1, 2, 3];
      console.log(arr3.pop());//删除数组最后一个元素并返回该元素
      console.log(arr3);//这里输出数组的内容

      let arr4 = [1, 2, 3];
      console.log(arr4.shift());//删除数组最前一个元素并返回该元素
      console.log(arr4);//这里输出数组的内容

数组排序方法
reverse

颠倒数组中元素的顺序,无参数

该方法会修改原数组,返回新的数组

sort

对数组的元素进行排序

该方法会改变原数组,返回新的数组

     var arr = [1, 2, 3];
      console.log(arr.reverse());
      console.log(
        arr.sort((a, b) => {
          return a - b;
        })
      );

数组的索引

indexOf

数组中查找给定元素的第一个索引

如果存在返回索引号,如果不存在就返回-1

lastIndexOf

数组中最后一个索引号

如果存在返回索引号,如果不存在返回-1

数组转换为字符串

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

返回一个字符串

join("分隔符")

方法用于把数组中的所有元素转换成一个字符串

返回一个字符

数组的各种方法:

          Array数组的各种函数:

          concat()函数连接两个或者多个数组,并且返回一个新数组,不会更改原先数组
          copyWithin()将数组中的数组元素复制到指定的位置或者从指定位置复制
          entries()返回键值对数组迭代对象
          every()检查数组中的每个元素是否通过测试
          fill()用静态值填充数组中元素
          filter()使用数组中通过测试的每个元素创建新数组
          find()返回数组中第一个通过测试的元素的值
          findIndex()返回数组中通过测试的第一个元素的索引
          forEach()为每个数组元素调用函数
          from()从对象创建数组
          includes()检查数组是否包含指定元素
          indexOf()在数组中搜索元素并返回其位置
          isArray()检查对象是否为数组
          join()将数组的所有元素连接成一个字符串
          keys()返回Array Iteration对象,包含原始数组的键
          lastIndexOf()在数组中搜索元素,从末尾开始,并返回其位置
          map()使用为每个数组元素调用函数的结果创建新数组
          pop()删除数组的最后一个元素,并返回改元素
          push()将新元素添加到数组的末尾,并返回新的长度
          reduce()将数组的值减为单个值(从左到右)
          reduceRight()将数组的值减为单个值(从右到左)
          reverse()反转数组中元素的顺序
          shift()删除数组的第一个元素,并返回该元素
          slice()选择数组的一部分,并返回一个新数组
          some()检查数组中的任何元素是否通过测试
          sort()对数组的元素进行排序
          splice()从数组中添加或者删除元素
          toString()将数组转换为字符串,并返回结果
          unshift()将新元素添加到数组的开头,并返回新的长度
          valueOf()返回数组的原始值
4、字符串和封装基本数据类型
包装基本数据类型:
为了方便操作基本数据类型,js提供了三个特殊的引用类型:String  Number  Boolean
基本包装类型就是把简单的数据类型包装成为复杂的数据类型,这样基本数据类型就有了属性和方法

var str = '你好啊';
经过包装之后
var str = new String('你好啊');//这样就可以使用String类型中的属性和方法

字符串的不可变性:指的是里面的值不可变,虽然看上去可以改变内容,但是其实是地址变了,内存中多开辟了空间

如何证明字符串的不可变性:

      // 1、字符串方法返回新字符串
      var str = "Hello";
      var upperCaseStr = str.toUpperCase(); // 转换为大写,返回一个新字符串
      console.log(str); // 输出: "Hello"
      console.log(upperCaseStr); // 输出: "HELLO"

      // 2、使用索引无法直接修改字符串的字符
      var str = "Hello";
      str[0] = "J"; // 尝试修改第一个字符,但不会生效
      console.log(str); // 输出: "Hello"

根据位置返回字符(重点)

charAt(index)

返回指定位置的字符(index字符串的索引号)

str.charAt(0)

charCodeAt(index)

获取指定位置字符的ASCLL码(index索引号)

str.charCodeAt(0)

str[index]

获取指定位置处的字符

HTML5新增的,IE8+支持和charAt()等效

substr(从哪个索引号截取,截取的长度)
subString(从哪个索引号截取,截取到哪个索引号)这个函数不接受负值
slice(从哪个索引号开始截取,截取到哪个索引号)这个函数允许有负值
splice(从哪个索引号开始截取,截取的长度),这个是对数组的

上面函数的返回值都是被截取出来的字符串

let str = "xheimosj3osmo";
console.log(str.substr(0, 2));
console.log(str.substring(0, 2));
console.log(str.slice(0, 3));
console.log(str.split("").splice(0, 3));

字符串中的其他方法:

1、big()函数用于把字符串显示为大号的字体

      let str = "hello";
      document.write(str.big());
      document.write(str);

2、bold()用于把字符串显示为粗体

      let str = 'hello world!';
      document.write(str.bold())

3、fixed()函数用于把字符串显示为打字机字体

      let str = 'hello world';
      // 这里方法需要使用write()函数出来,不然看不出变化
      document.write(str.fixed().bold().big())

4、fontcolor()用于按照指定的颜色来显示字符串
color:必选,指定显示字符串的颜色,颜色名,rba()  tbga()  十六进制

      let str = 'hello world';
      document.write(str.fontcolor('red'))

5、fontsize()函数用于按照指定的尺寸来显示字符串。
注释:size 参数必须是从 1 至 7 的数字。

      let str = 'hello world!';
      document.write(str.fontsize(1));
      document.write(str.fontsize(7));

6、fromCharCode() 可接受一个指定的 Unicode 值,然后返回一个字符串
   String.fromCharCode(numX,numX,...,numX)
   numX	必需。一个或多个 Unicode 值,即要创建的字符串中的字符的 Unicode 编码。
   注释:该方法是 String 的静态方法,字符串中的每个字符都由单独的数字 Unicode 编码指定。

   它不能作为您已创建的 String 对象的方法来使用。因此它的语法应该是 String.fromCharCode(),
   而不是 对象.fromCharCode()。

        document.write(String.fromCharCode(72, 69, 76, 76, 79))//HELLO
        document.write("<br />")
        document.write(String.fromCharCode(65, 66, 67))//ABC

7、indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
   对象.indexOf(searchvalue,fromindex)
        
   searchvalue	必需。规定需检索的字符串值。
   fromindex	可选的整数参数。规定在字符串中开始检索的位置。它的合法取值是 0 到 
                stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索

        let str = "Hello world!"
        console.log(str.indexOf("Hello") + "\n")
        console.log(str.indexOf("World") + "\n")
        console.log(str.indexOf("world"))

8、italics()方法用于把字符串显示为斜体。

        let str = "Hello world!"
        document.write(str.italics())

9、link()函数用于把字符串显示为超链接
   对象.link(url)  参数url:必选,规定要连接的url地址

        var str = "Free Web Tutorials!"
        document.write(str.link("http://baidu.com"));

10、match()函数可在字符串内检索指定的值,或者找到一个或者多个正则表达式的匹配。
    该方法类似indexOf()和lastIndexOf(),但是它返回指定的值而不是字符串的位置
使用格式:stringObject.match(searchvalue);
         stringObject.match(regexp);

11、replace()函数用于在字符串中用一些字符替换另一个字符,或者替换一个正则表达式匹配的子串

        stringObject.replace(regexp/substr,replacement);
        参数说明:
        regexp/substr:必选,规定子字符串或者要替换的模式的RegExp对象
        replacement:必选,一个字符串值,规定了替换文本或者生成替换文字的函数

        返回值:
        一个新的字符串,是用 replacement 替换了 regexp 的第一次匹配或所有匹配之后得到的。

      // 练习,将字符串'Microsoft'替换成'W3School'
      var str = "Visit Microsoft!";
      document.write(str.replace(/Microsoft/, "W3School"));

12、search()函数用于检索字符串中指定的子字符串,或者检索与正则表达式相匹配的子字符串
        语法:
        stringObject.search(regexp);

        参数:
        regexp:改参数可以是需要在stringObject中检索的子串,也可以是西药检索RegExp对象
        注释:要执行忽略大小写的检索,请追加标志i,如果没有的话,search()函数是区分大小写的

        返回值:
        stringObject中第一个与regexp相匹配的子串的起始位置
        注释:如果没有找到任何相匹配的子串,返回值是-1

      var str = "Visit W3School!";
      console.log(str.search(/w3school/));//-1
      console.log(str.search(/w3school/i));//6

13、slice()函数用于获取字符串中的某个部分子串,并以新字符串的形式返回

        语法:stringObject.slice(start,end)
        参数:
        start:必选,表示从字符串的哪个位置开始获取子串。如果是负数,则改参数规定从字符串的尾部 开始算起的位置。也就是说-1是从尾部的第一个位置开始,-2就是倒数第二和位置
        end:必选。紧接着要抽取片段的结尾的下标。若未指定这个参数,表示从start开始,到字符串结束,获取这个子串。如果参数是负数,规定从字符串的尾部开始算起的位置

        返回值:
        一个新的字符串。包括字符串 stringObject 从 start 开始(包括 start)到 end 结束(不包括 end)为止的所有字符。

        说明
        String 对象的方法 slice()、substring() 和 substr() (不建议使用)都可返回字符串的指定部分。slice() 比 substring() 要灵活一些,因为它允许使用负数作为参数。slice() 与 substr() 有所不同,因为它用两个字符的位置来指定子串,而 substr() 则用字符位置和长度来指定子串。

        还要注意的是,String.slice() 与 Array.slice() 相似。

14、small() 方法用于把字符串显示为小号字。

        var str = "Hello world!"
        document.write(str.small())

15、split()函数用于把一个字符串进行分割成数组,返回值:一个字符串数组。

      var str = "How are you doing today?";
      console.log(str.split(" "));
      console.log(str.split(""));
      console.log(str.split(" ", 3));
match函数的练习

      var str = "Hello world!";
      console.log(str.match("world"));
      console.log(str.match("World"));
      console.log(str.match("worlld"));
      console.log(str.match("world!"));

      let str1 = "123 school 123_?@";
      console.log(str1.match(/.{4}/g));
      console.log(str1.match(/.{3}/g));
      console.log(str1.match(/.{2}/g));
      console.log(str1.match(/./g));

      console.log(str1.match(/\d/g));
      console.log(str1.match(/\D/g));
      console.log(str1.match(/\W/g));
      console.log(str1.match(/\w/g));

5、DOM_获取对象的元素
1、根据元素的id属性获取元素对象
格式:document.getElementById("time")
    <script>
        var timer = document.getElementById("time");
        console.log(timer)
        console.dir(timer)
    </script>

2、根据标签名获取
使用getElementsByTagName()方法可以返回带有指定标签名的对象的集合
document.getElementByTagName('标签名') 
注意:不管是getElementById还是getElementsByTagName,括号里面都需要带引号


3、通过html5新增的方法获取,如果考虑IE8的兼容性问题,这个就不能使用
   document.getElementsByClassName('类名')根据类名返回对象的集合
   document.querySelector('选择器')根据指定选择器返回第一个元素对象
   document.querySelectorAll('选择器')根据指定选择器返回所有元素对象

4、获取特殊元素(body、html)
   获取body元素
   var bodyElement = document.body;//返回body元素对象
   获取html元素
   var htmlElement = document.documentElement;//返回html元素对象
6、DOM事件和获取元素属性
鼠标事件(Mouse Events):

click:单击事件
dblclick:双击事件
mousedown:鼠标按下事件
mouseup:鼠标释放事件
mousemove:鼠标移动事件
mouseenter:鼠标进入元素事件
mouseleave:鼠标离开元素事件
mouseover:鼠标悬停在元素上事件
mouseout:鼠标离开元素事件

键盘事件(Keyboard Events):

keydown:按键按下事件
keyup:按键释放事件
keypress:按键按下并释放事件

表单事件(Form Events):

submit:表单提交事件
input:输入框输入事件
change:表单元素值改变事件
focus:元素获得焦点事件
blur:元素失去焦点事件

窗口事件(Window Events):

load:页面加载完成事件
resize:窗口大小改变事件
scroll:滚动事件
unload:页面关闭或离开事件

触摸事件(Touch Events):移动端中使用

touchstart:触摸开始事件
touchend:触摸结束事件
touchmove:触摸移动事件
touchcancel:触摸取消事件
自定义属性、固有属性

<div getTime="2" data-index="1" data-list-name="div"></div>
    <input type="text" value="显示input的固有属性" />
    <script>
      /* 
        1、自定义属性和获取  getAttribute 和 setAttribute
        2、使用h5新增的方法dateset(使用有局限性,只能在ie11以上使用),dateset是一个保存以date-开头的所有自定义属性的集合
        3、直接使用元素的固有属性 document.querySelector("input").type等
        */
      // getAttribute()可以用来获取所有自定义的属性
      var div = document.querySelector("div");
      console.log(div.getAttribute("getTime")); //2
      console.log(div.getAttribute("data-index")); //1
      console.log(div.getAttribute("data-list-name")); //3

      // setAttribute()设置元素自定义属性
      div.setAttribute("getTime", 1);
      div.setAttribute("data-index", 2);
      div.setAttribute("data-list-name", 4);
      console.log(div.getAttribute("getTime")); //1
      console.log(div.getAttribute("data-index")); //2
      console.log(div.getAttribute("data-list-name")); //4

      // 使用h5新增的方法dateset(使用有局限性,只能在ie11以上使用)
      // dateset是一个保存以date-开头的所有自定义属性的集合
      console.log(div.dataset.index);
      // 自定义属性中如果出现用多个-连接起来的属性,获取的时候采用驼峰命名法
      console.log(div.dataset["index"]);
      console.log(div.dataset["listName"]);

      // 直接获取元素的固有属性
      const input = document.querySelector("input");
      input.value = "修改了属性值";
      console.log(input.type);
      console.log(input.value);
    </script>
自定义属性的增删改查:

<div id="first_div" date="10">你好啊</div>
    <script>
      const div = document.querySelector("div");
      console.log(div.id);
      //   element.属性名称的方式只能用来获取内置属性,不能获取自定义属性
      //   console.log(div.date);
      //   div.id = "second-div";
      //   和获取自定义属性一样,修改也不行
      //   div.date = "11";

      //   getAttribute()方式可以可以帮助获取元素中的属性,但是这个方法获取的元素的属性可以是自定义的,
      //   也可以是系统中内置好的属性
      //   修改属性值,getAttribute也是可以修改内置属性和自定义属性的
      //   修改元素上的属性和修改数据对象数据的属性一样,如果不存在的属性是添加进去
      //   element.属性名称 这种方式获取的属性的方式只能获取内置的属性,不能获取自定义的属性
      console.log(div.getAttribute("id"));
      console.log(div.getAttribute("date"));
      div.setAttribute("id", "second-div");
      div.setAttribute("date", "11");
      div.setAttribute("date1", "11");

      //   删除属性
      div.removeAttribute("id");
      div.removeAttribute("date");

      //   获取属性getAttribute()
      //   修改属性setAttribute()
      //   删除属性removeAttribute()
    </script>
7、操作元素中排他思想
排他思想 是一种在操作元素时,确保只有一个元素处于某种状态或被选中的原理。这种思想常用于创建交互性强的界面,例如选项卡、单选按钮组、下拉菜单等。     

      for (var i = 0; i < li.length; i++) {
        li[i].onclick = function () {
          for (var i = 0; i < li.length; i++) {
            li[i].style.backgroundColor = "";
            li[i].querySelector(".div").style.display = "none";
          }
          this.style.backgroundColor = "red";
          this.querySelector(".div").style.display = "block";
        };
      }
8、H5自定义属性
h5自定义属性
            自定义属性的目的是为了保存并且使用数据,有些数据可以保存在页面中而不用保存在数据库中
            自定义属性获取是用过getAttribute('属性')获取
            但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性
            h5给我们新增了自定义属性

            设置h5自定义属性
            h5规定自定义属性使用data-开头,比如:<div data-index = "1">你好啊</div>

            H5获取自定义属性的方式
            1、兼容性获取element.getAttribute('data-index')
            2、H5新增element.dataset.index或者是element.dataset['index'] ie11才开始支持这种写法

            如果遇到多个单词组成的:
            <div data-list-name = '2'>你好啊</div>
            element.getAttribute('data-list-name');
            element.dataset.listName;
            element.dataset['listName'];

<div data-list-name="1">你好啊</div>
    <script>
      const div = document.querySelector("div");
      console.log(div.getAttribute("data-list-name"));
      console.log(div.dataset.listName);
      console.log(div.dataset["listName"]);

      //   修改属性值只是用setAttribute()
      div.setAttribute("data-list-name", "2");
      console.log(div.dataset["listName"]);
    </script>
9、兄弟节点
兄弟节点(包含文本节点和元素节点)
node.nextSibling
nextSibling返回的是当前元素的下一个兄弟节点,找不到就返回null,同样也是包含所有的节点

node.previousSibling
previousSibling返回的是当前元素的上一个兄弟节点,找不到就返回null,同样也是包含所有的节点

兄弟节点(只包含元素节点)
node.nextElementSibling
nextElementSibling返回当前元素下一个兄弟元素节点,找不到就返回null,只包含元素节点

node.previousElementSibling
previousElementSibling返回当前元素的上一个兄弟元素节点,找不到就返回null

注意:下面这两个获取兄弟元素节点的存在兼容性,IE9+才可以使用(I9以上的才能使用)

封装兼容性的函数:

      function getNextElementSibling(element) {
        var el = element;
        while ((el = el.nextSilbing)) {
          if (el.nodeType === 1) {
            return el;
          }
        }
        return null;
      }
10、孩子节点
子节点
        parentNode.childNodes(标准)
        parentNode.parentNodes返回包含指定节点的子节点的集合,改集合为即时更新的集合
        注意:返回值中包含了所有了所有的子节点,包括元素节点、文本节点等
        如果只想要获得里面的元素节点,需要专门处理,使用循环和判断语句来获取元素节点,所以不提倡使用childNodes方法获取子节点
        childNodes使用方法
        var ul = document.querySelector('ul');
        for(var i=0;i<ul.childNodes.length;i++){
            if(ul.childNodes.nodeType==1){
                因为此时子节点对应的索引值是i
                console.log(ul.childNodes[i]);
            }
        }

        第二种获取子节点的方式(非标准,但提倡)
        parentNode.children
        是一个只读属性,返回所有的子元素节点,它只返回子元素的节点,其余包含在父节点中的非子元素节点不取
        没有兼容性问题,各个浏览器都可以使用

11、父节点
      // 判断节点是否存在父级节点,存在就删除节点
      if (node.parentNode) {
        // 从 DOM 树中删除 node 节点,除非它已经被删除了。
        node.parentNode.removeChild(node);
      } 

      // 两个方法都是获取节点的父级节点,都是获取最近的父级节点
      console.log(li[0].parentNode);
      console.log(li[0].parentElement);
12、创建添加删除复制节点

1)、创建添加节点

<ul></ul>
  
        1、创建子元素节点
        node.createElement('节点的名称');
        如:var li = document.createElement('li');

        2、添加子元素到指定位置,假如是ul标签需要添加li元素
        const ul = document.querySelector('ul');
        ul.appendChild(li);//动态添加标签,这是从内部的后面添加子元素
        ul.insertBefore(li);//动态添加标签,这是从内部的前面添加子元素

代码演示: 
      const ul = document.querySelector("ul");
      const li = document.createElement("li");
      li.innerHTML = "你好啊";
      ul.appendChild(li);
      ul.insertBefore(document.createElement("li"), ul.children[0]);   

2)、删除节点

删除节点使用
格式:parentNode.removeChild(childrenNode)

    <table>
      <thead>
        <tr>
          <th>姓名</th>
          <th>科目</th>
          <th>成绩</th>
          <th>操作</th>
        </tr>
      </thead>
    </table>
    <script>
      const table = document.querySelector("table");
      const arr = [
        {
          name: "张三",
          course: "JavaScript",
          score: 100,
          todo: "<a href = 'javascript:;' >删除</a>",
        },
        {
          name: "李四",
          course: "JavaScript",
          score: 90,
          todo: "<a href = 'javascript:;'>删除</a>",
        },
        {
          name: "王五",
          course: "JavaScript",
          score: 80,
          todo: "<a href = 'javascript:;'>删除</a>",
        },
        {
          name: "赵六",
          course: "JavaScript",
          score: 70,
          todo: "<a href = 'javascript:;'>删除</a>",
        },
      ];
      let tbody = document.createElement("tbody");
      table.appendChild(tbody);
      for (let i = 0; i < arr.length; i++) {
        let tr = document.createElement("tr");
        tbody.appendChild(tr);
        for (let j = 0; j < Object.keys(arr[i]).length; j++) {
          let td = document.createElement("td");
          tr.appendChild(td);
          td.innerHTML = arr[i][Object.keys(arr[i])[j]];
        }
      }
      const tr = document.querySelector("tbody").querySelectorAll("tr");
      for (let i = 0; i < tr.length; i++) {
        tr[i].children[3].onclick = function () {
          tbody.removeChild(this.parentNode);
        };
      }
     

3)、复制节点

使用node.cloneNode()

    <ul>
      <li>1</li>
    </ul>
    <script>
      var ul = document.querySelector("ul");
      var li = document.querySelectorAll("li");
      ul.insertBefore(ul.children[0].cloneNode(), ul.children[0]);
      console.log((ul.children[0].innerHTML = "我是张三"));
      // node.cloneNode()方法返回调用改方法的节点的一个副本,也称为是克隆节点/拷贝节点
      /* 注意:如果括号参数为空或者是false,就是浅拷贝,即只克隆赋值节点本身,不克隆节点里面的内容;
        如果是true, 则深度克隆,会复制节点本身和节点中的所有内容,包括节点中的子节点*/
      ul.insertBefore(ul.children[0].cloneNode(true), ul.children[0]);
    </script>
13、三种动态创建元素标签的方式
document.write()
element.innerHTML
document.createElement()

document.write是直接将内容写入页面的内容流中,但是文档流执行完毕,则它会导致页面全部被重绘(就是原先的整个页面的内容会被替换成write中的内容)
innerHTML是将内容写入某个DOM节点中,不会导致页面全部重绘
innerHTML创建多个元素效率更高(不要拼接字符串的形式,而采取数组的形式创建元素时),结构稍微复杂
createElement()创建多个元素效率稍微低一点,但是结构更清晰

案例:

document.write("张三")
document.querySelector('span').innerHTML = "你好啊";

let span = document.createElement("span");
span.innerHTML = "你好啊";
document.querySelector('.box').appendChild(span);

14、高级事件-事件监听器addEventListener
        封装解决注册事件的兼容性函数,但是先兼顾大多数的浏览器,再兼容少数的浏览器
        function addEventListener(element,eventName,fn){
            // 判断当前浏览器是否支持addEventListener方法
            if(element.addEventListener){
                element.addEventListener(eventName,fn);
            }
            else if(element.attachEvent){
                element.attachEvent('on'+eventName,fn);
            }
            else{
                element['on'+eventName] = fn;
            }
        }

案例:
    <button>点击触发事件</button>
    <script>
      const button = document.getElementsByTagName("button")[0];
      button.addEventListener("click", function () {
        alert("button按钮被触发");
      });
    </script>
15、删除事件
删除事件:使用   document.removeEventListener(事件类型, 回调函数)

      // 下面这个程序中只能被触发一次,因为触发之后删除事件
      document.addEventListener("click", fun);
      function fun() {
        alert("我是一条指令");
        document.removeEventListener("click", fun);
      }
16、DOM事件流_事件捕获/事件冒泡

1)、addEventListener()默认处于冒泡阶段

addEventListener()方法默认是冒泡阶段

      // 函数的最后一个参数如果是true表示在捕获节点,如果是false表示在冒泡阶段
      // 测试冒泡阶段
      document.addEventListener("click", function () {
        alert("我是document");
      });
      var button = document.querySelector("button");
      button.addEventListener("click", function () {
        alert("我是button按钮");
      });

      // 测试捕获阶段
      document.addEventListener(
        "click",
        function () {
          alert("我是document");
        },
        true
      );
      var button = document.querySelector("button");
      button.addEventListener("click", function () {
        alert("我是button按钮");
      });

2)、DOM事件流

DOM事件流
事件流描述的是从页面中接收事件的顺序
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流
           
DOM事件流:
事件捕获:网景最早提出的,由DOM最顶层的节点开始,然后逐级向下传播到最具体的元素接收的过程
         当前目标阶段
事件冒泡:IE最早提出的,事件开始时由最具体的元素接收,然后主机向上传播到DOM最顶层的节点的过程

3)、事件捕获和事件冒泡

事件冒泡和事件捕获分别是什么?

捕获阶段:
在该阶段,事件从文档根节点开始向下传播,经过嵌套层次中的父元素,直到达到事件的目标元素之前。在捕获阶段中,事件会依次触发元素的父级元素的事件处理程序。

目标阶段:
当事件到达目标元素时,即触发目标元素上的事件处理程序。在目标阶段中,事件处于目标元素上,可以执行与事件关联的操作。

冒泡阶段:
在该阶段,事件从目标元素开始向上传播,经过嵌套层次中的父元素,直到达到文档根节点之前。在冒泡阶段中,事件会依次触发元素的父级元素的事件处理程序。
事件捕获和事件冒泡:
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程叫做DOM事件流

注意:

js代码中只能执行捕获或者冒泡其中的一个阶段,onclick和attachEvent只能得到冒泡阶段,
addEventListener(type,listener[,Capture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写或者为false),表示在事件冒泡阶段调用事件处理程序

实际开发中更少使用事件捕获,事件冒泡比较多。有些事件没有冒泡阶段:onblur  onfocus  onmouseenter  onmouseleave。
事件冒泡有利有弊

4)、事件对象

什么是事件对象
eventTarget.onclick = function(event){}
eventTarget.addEventListener('click',function(event){})
// 这个event就是事件对象,写成e或者是event都是可以的

官方解释:event对象代表的是事件的状态,比如键盘按键的状态、鼠标的位置状态、鼠标按钮的状态等简单解释就是事件发生后,跟事件相关一系列信息数据的集合都放到event对象里面,这个对象就是事件对象,包含很多属性和方法

比如:
绑定事件的对象  currentEvent或者使用this表示
触发事件的对象  e.target或者是event.target表示
键盘触发事件会得到相关的信息,比如按键信息

后续前往CSDN

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值