This指向及改变,DOM节点操作、获取,删除,各种节点

DOM节点

node 是节点的意思
我们的页面是由节点组成的,每一个组成部分都是一个节点。
节点的分类:
元素节点 html标签 img body input div
文本节点 文字部分 (空格,换行也算)
属性节点 标签内的属性(比如id,class名是名不含里面的值)
注释节点
1.document
页面中最大的节点,有且只有一个。不属于元素节点,是页面中所有节点的容器。 根节点。
2.html
页面中最大的元素节点。根元素节点。
3.元素节点
html标签等
4.文本节点
每一段文本内容都是一个文本节点
包含 换行 和 空格
一般来说作为元素节点的子节点存在。
5.属性节点:
属性节点不能单独存在,必须依赖于元素节点。
6.注释节点
页面中的注释,作为说明文本使用。

在这里插入图片描述

自定义获取元素节点方法

<script>
        /
        node 表示传入的节点,获取该节点的元素节点。
        classStr 表示传入的classname ,通过classname匹配元素节点
        /
        function elementsByClassName(node,classStr){
    
    
            // 1.获取node这个节点下面的所有子节点。
            var nodes = node.getElementsByTagName("*");
            // 2.存放符合条件的节点
            var arr = [];
            //3.遍历所有的子节点
            for (var i = 0; i < node.length; i++) {
    
    
                //4.判断子节点的class是否与传入的classStr相等
               if(nodes[i].className === classStr){
    
    
                   //5.若相等,则将其放入数组中。
                   arr.push(nodes[i]);
               }
            }
            return arr;
        }
    </script>

操作元素节点的属性

标签上的属性分类:
1.原生属性
2.自定义属性
3.H5 自定义属性

1.原生属性
语法:元素.属性名
修改/新增:
元素.属性名 = “值”
获取:
元素.属性名
【注意】class属性是例外,不能直接通过属性名获取,而是用className

2.自定义属性
不能直接使用 元素. 这个语法来获取。
三个方法去操作:
获取
getAttribute(“属性名”);
返回值:字符串
设置
setAttribute(“属性名”,“属性值”)
删除
removeAttribute(“属性名”)

【注意】这三个方法也可以操作原生属性
3.H5 自定义属性
每一个元素节点上都有一个属性:dataSet
里面包含了所有的H5自定义属性。
键值对结构: 例子;data-id =“idBox”
key:data-XXX xxx的内容。
value:属性值
获取:
元素.dataset.key
设置:
元素.dataset.key = “值”
删除
delete 元素.dataset.key

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function () {
    
    
            var oDiv = document.getElementsByTagName("div")[0];
            // 原生属性--------------------
            //console.log(oDiv.id);//获取 到第一个div中这个id的值
            //oDiv.id = "xin"; //对获取 到第一个div中的id值修改
            //【注意】class属性是例外,不能直接通过属性名获取,而是用className
            //console.log(oDiv.className);//获取 到第一个div中的class值
            //oDiv.className="xin";//更改 class值
            //自定义属性
            //var ziding = oDiv.getAttribute("ab"); console.log(ziding)//获取 自定义属性属性值
            //var shezhi = oDiv.setAttribute("ab", "wei");//更改 自定义属性的属性值 变为 ab="wei"
            //var shanchu = oDiv.removeAttribute("ab" );//删除自定义的属性
            //H5 自定义属性----------------------------------------------------------
            oDiv.dataset.name="xin"//添加属性  div里面有一个dataset.name="xin"属性节点
            // console.log( oDiv.dataset.name) ;//获取
            //delete oDiv.dataset.name;//把上边添加属性节点删除
        }
        //dataset.name中的name是可以自己起名字的dataset.XXX
    </script>
</head>
<body>
    <div id="jiu" ab="nihao" class="jiu"></div>
</body>

在这里插入图片描述

这是dataset的进一步理解

<body>
    <div getTime="20" data-index="2" data-list-name="andy">张三</div>
</body>

<script>
    var div = document.querySelector('div');
    console.log(div);
    //  setAttribute()设置属性节点    getAttribute()获取属性节点
    /* div.setAttribute('data-time', 30);//新建了一个自定义的属性并填值
     console.log(div.getAttribute('getTime'));//20
     console.log(div.getAttribute('data-index'));//2
     console.log(div.getAttribute('data-list-name'));//andy*/

    // 1.h5新增的获取自定义属性的方法 它只能获取data-开头的
    // 2.dataset 是一个集合里面存放了所有以data开头的自定义属性
    // console.log(div.dataset);//{
    
    index: "2", listName: "andy"}
    /*console.log(div.dataset.index);//2
    console.log(div.dataset['index']);//2(这是另一种写法)*/

    // 3.如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
    /* console.log(div.dataset.listName); //andy
     console.log(div.dataset['listName']); //andy*/
    //4.设置自定义属性的属性值     格式:  元素.dataset.key="值"
    /* div.dataset.index = "xin";
     console.log(div.getAttribute('data-index')); //获取到data-index="xin"
      // div.dataset.listName = "xin";//这样也是对自定义属性值进行了更改*/

    //5.删除    格式: delete 元素.dataset.key
    /*delete div.dataset.index
    console.log(div);//输出我们可以看到data-index="2" 被删除了*/
</script>

操作元素的类名

1。按照原生属性的方式来操作
获取:
元素.className
设置:
元素.className = “值”
追加:
元素.className += " 值";
【注意】 追加时,值的前面要加一个空格。
删除:
1.重新设置一遍。
2.
2.1 获取classname属性值、
2.2 按照空格去分割字符串
2.3 遍历数组,将要删除的字符串删除
2.4 数组的join方法

2.H5标准给我们一个API
元素节点都有一个属性叫做:classList
里面包含了所有的class值。
获取:
元素.classList 获取class值的集合。
想要获取单个,使用下标。
新增:
元素.classList.add(“新增的类名”)
删除:
元素.classList.remove(“删除的类名”)
替换:
元素.classList.replace(“旧类名”,“新类名”) ;
toggle() 切换
语法:元素.classList.toggle(类名)
当元素拥有这个类名时,将类名删除
当元素没有这个类名时,将类名添加

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function () {
    
    
            var bDiv = document.getElementsByTagName("div")[0];//获取到第一个div,并起名为bDiv
            // var  huoqu=bDiv.className;//获取到这个类名,并起名为huoqu
            //var gai = bDiv.className = "xin";//更改类名
             //var jia = bDiv.className += " xin";//添加类名,后加的这个要有一个空格
             //var del= bDiv.className = "";重新设置一遍为空删除方法
            //H5标准----------------------------------------------------------------------------------------
            //var huoqu=bDiv.classList;//获取所有的class值
             console.log(huoqu);//box    a
            //var jia = bDiv.classList.add("d");//添加一个类名
            //var  shanchu=bDiv.classList.remove("box");删除你指定的类名
            //var tihuan = bDiv.classList.replace("box" , "zhao"); 替换:元素.classList.replace("旧类名","新类名") ;
            // var   huan=bDiv.classList.toggle("a");当有这个类名时把它删除。没有时添加
        }
    </script>
</head>
<body>
    <div class="box a"></div>
</body>
</html>

操作元素节点中的内容

1.innerHTMl
获取元素节点中除了本身的标签外,所有的HTML代码。
获取:
元素.innerHTML
设置:
元素.innerHTMl = “新的内容”
【注意】 innerHTML 会覆盖原有的内容,而且会解析其中的标签。

2.innerText
获取元素节点中的文本内容,会覆盖原有的内容,不会解析内容中的标签。
获取:
元素.innerText
设置:
元素.innerText = “新的内容”;

3.value
主要使用在表单元素中。
操作表单元素节点的value属性。
获取:
表单元素节点.value
设置:
表单元素节点.value = “值”

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function () {
    
    
            var box = document.getElementById("box");
            // box.innerHTML="<h1>我是新的innerHTML</h1>";
            // box.innerText="<h1>我是新的innerHTML</h1>";  
            var inp = document.getElementById("inp");
            inp.value = "赵宏伟";
        }
    </script>
</head>
<body>
    <div id="box">我是div标签<br> </div>
    <input type="text" id="inp">
</body>
</html>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

函数的执行顺序

函数的执行
里面若涉及到了变量
在定义的时候不解析变量,而是按照变量名保存,
只有在函数调用时,才会解析变量

 <script>
  
      var num = 20;
        function func(){
    
    
            console.log(num);//输出是40
        }
        num = 40;
        func();
    </script>

this:(重要)

在函数中,this保存的是函数调用者的地址信息。
谁调用了当前的函数,this就表示谁。

this全局变量中指向window

单独使用 this,则它指向全局对象。

 <script>
        console.log(this);// Window
    </script>

this在对象的方法中指向调用者

<script>
    	var o = {
    
    
        a:10,
        b:{
    
    
            a:12,
            fn:function(){
    
    
                console.log(this.a);//12(运行过程,是b调用了这个函数,然后去b里面找a)
            }
        }
    }
    o.b.fn();//这里的this指b
</script>

下面这个例子你可能会认为this为j,并不是,j只是给赋值

  <script>  var o = {
    
    
        a:10,
        b:{
    
    
            a:12,
            fn:function(){
    
    
                console.log(this.a);//undefined  (去window里面找a,找不到所以为未定义)
                console.log(this);//window
            }
        }
    }
    // o.b.fn(); 放开这个, this就为b   this.a就为12
    var j = o.b.fn;
    window.j();
</script>

this在事件绑定中,指向目标对象。

<body>
    <div id="box"></div>
</body>
<script>
    var box = document.getElementById("box");
box.onclick = function(){
    
    
    console.log(this);//this指向为box  
}
</script>

this在定时器处理函数中,指向window

<script>
     var o = {
    
    
        a:10,
        b:{
    
    
            a:12,
            fn:function(){
    
    
                console.log(this.a);//undefined  window里面找不到a,所以为未定义
                console.log(this);//window
            }
        }
    }
    setTimeout(o.b.fn,0)
 //setInterval(o.b.fn,1000)
</script>

强行改变this指向的方式

call()

格式:

函数名.call(obj,arg...);
/obj : 函数内部的this指向
/arg...:从第二个参数开始,为函数的参数。是一个一个的

而apply()的参数是一个数组

特点:立即执行当前函数。

<script>
    function fn(x, y) {
    
    
        console.log(x + y); //30
        console.log(this); //this指向window
    }
    fn(10, 20)
</script>
<script>
    function fn(x, y) {
    
    
        console.log(x + y); //30
        console.log(this); //this指向obj{}
    }
    var obj = {
    
    }
    fn.call(obj, 10, 20);
</script>

【注意】定时器处理函数或者事件处理函数不能用

<script>
    function fn(){
    
    
        console.log("我是延时函数");
    }
 var   obj={
    
      }
   // setTimeout(fn,3000)//正常使用3s后执行
    setTimeout(fn.call(obj),3000);//直接出现,延迟失效
    </script>

apply()

格式

/obj : 函数内部的this指向
/arr:一个数组或者伪数组,里面的每一个元素会依次传递给函数。
函数名.apply(obj,arr);

特点:立即执行当前函数。

<script>
    function fn(x, y) {
    
    
        console.log(x + y); //30
        console.log(this); //this指向window
    }
    fn(10, 20)
</script>
-------------------------------------------------------------------------------
<script>
    function fn(x, y) {
    
    
        console.log(x + y); //30
        console.log(this); //this指向obj{}这个空对象
    }
    fn(10, 20)
    var obj = {
    
    };
    fn.apply(obj, [10, 20]);
</script>

【注意】定时器处理函数或者事件处理函数不能用

这是应用:可以以数组的形式给某些功能函数传参。

<script>
   /*常规方法
    var max = Math.max(10,5,30,-15,6);
    console.log(max);//30*/
   //apply()方法
    var arr = [10, 5, 30, -15, 6, 40]
    var max2 = Math.max.apply(null, arr);
    console.log(max2);//40
</script>

面试题
求数组中的最大值 和 最小值
(上面提到,apply()传入的参数可以是一个数组,所以可以这样写)

  let arr = [11, 34, 22, 45, 50]
            js的解法:(后面es6中res还有新的写法)            
    let max = Math.max.apply(null, arr)
    let min = Math.min.apply(null, arr)

bind()

格式:

/obj : 函数内部的this指向
/arg:从第二个参数开始,依次为函数传递参数。
函数名.apply(obj,...arg);

特点

不会立即执行函数,会返回一个新的函数,该函数内部的this指向为传入的对象。

    <!-- <script>
        function fn(x,y){
    
    
          console.log(x+y);//30
          console.log(this);// this指向window
      }
      fn(10,20);   
  </script>  -->
    <script>
        function fn(x, y) {
    
    
            console.log(x + y);// 30
            console.log(this);//this指向obj{}
        }
        var obj = {
    
    
        }
        var res = fn.bind(obj, 10, 20);
        res();  //调用  
    </script> 

把这个图记住就是区别:
在这里插入图片描述
面试题,call() apply() 的区别:

call() apply()

  • 共同点

    1. 修改this指向,
    2. 调用执行函数
  • 不同点:

    参数的传递方式不同, call()参数是一一罗列;
    apply()参数是以数组的形式传递

操作元素节点的样式

元素节点的样式:
样式:
行内
内嵌
外链
行内样式:
原生属性的方式获取
元素.style.样式的属性名
【注意】如果属性名是多个单词,第二个单词首字母大写,删除中划线。 比如背景颜色
该方法只能获取行内。

获取元素的有效样式

  • 标准浏览器:

    getComputedStyle(要获取样式的元素)

  • IE低版本:(IE8以下)

    元素.currentStyle.样式属性名
    例如: box.currentStyle.width

设置样式
语法:元素.style.样式名 = “值”;

<!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>
        #box{
    
    
            width: 200px;
        }
    </style>
    <script>
        window.οnlοad=function(){
    
    
            var box = document.getElementById("box");
            //该方法只能获取行内样式
            console.log(box.style.height);//获取到宽
            console.log(box.style.backgroundColor);//获取到背景色
            //获取到有效样式-标准浏览器
           console.log( getComputedStyle(box).width) ;//这样格式写
           console.log( getComputedStyle(box)[width]) ;//或者这样格式写
          // IE低版本-这样写
          console.log( box.currentStyle.width);
          //兼容写法
          //node 要获取样式的元素节点  cssStyle 要获取样式的属性名
            function getStyle(node,cssStyle){
    
    
            return node.currentStyle?node.currentStyle[cssStyle]:getComputedStyle(node)[cssStyle];
              }
        }
    </script>
</head>
<body>
    <div id="box" style="height: 100px;background-color: blue;"></div>
</body>
</html>

获取元素节点的属性节点

属性节点:
获取元素节点的属性节点
元素.attributes

单个属性节点:
元素.attributes.getNamedItem(“属性名”);

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function(){
    
    
            var box = document.getElementById("box");
            //获取box这个元素节点中的所有属性节点
            console.log(box.attributes);//获取到id和class的值
            //获取单个属性节点
            console.log(box.attributes.getNamedItem("class"));//home 当class还有其他值时也会获取
        }
    </script>
</head>
<body>
    <div id="box"  class="home"></div>
</body>
</html>

通过节点关系获取节点

DOM节点不是孤立存在,我们可以通过节点之间的关系去获取他们。
节点的关系,是以属性的方式存在的。

获取父节点。
节点.parentNode

(IE支持parentElement和parentNode获取父节点,而firfox只能使用parentNode来获取父节点。
所以在JS中获取父节点是,推荐大家统一使用parentNode。)

获取兄弟节点
1.下一个节点
node.nextSibling
对于标准浏览器,标签,空文档,换行都属于节点。
IE低版本:指下一个元素节点。
2.下一个元素节点
node.nextElementSibling
下一个兄弟节点 = 节点.nextElementSibling||节点.nextSibling(保守写法)

3.上一个节点
node.previousSibling
4.上一个元素节点
node.previousElementSibling

获取单个子节点
1.第一个子节点
node.firstChild
2.获取第一个元素节点
node.firstElementChild
3.获取最后一个子节点
node.lastChild
4.获取最后一个元素节点
node.lastElementChild

获取所有子节点
1.获取所有子节点
语法:node.childNodes
返回的是子节点的伪数组(元素节点,文本节点,注释节点)
2.获取所有的元素子节点
语法:node.children
返回元素节点。使用最多的方法。

节点的属性
属性:事物的特征
nodeName: 节点名称
注释节点: #comment
文本节点: #text
元素节点: 大写的标签名
属性节点: 属性名

nodeType:节点类型
注释节点:8
文本节点:3
元素节点:1
属性节点:2

nodeValue:节点的值
注释节点:注释内容
文本节点:文本内容
元素节点:null
属性节点:属性值

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.onload = function () {
    
    
            var box = document.getElementById("box");
              console.log(box.parentNode);//   元素节点div的父节点是body
             console.log(box.nextSibling);//获取到下一个节点,空格换行也算  获取到空格换行是#text
             console.log(box.nextElementSibling);//获取到下一个元素节点<p class="box">我是p标签</p>
             // 不会出错的写法   下一个兄弟节点 = 节点.nextElementSibling||节点.nextSibling
             //-----------------------------------------------------------
             console.log(box.previousSibling);//获取到上一个节点,空格换行也算 
             console.log(box.previousElementSibling);//获取到上一个元素节点
             //获取单个子元素节点-----------------------------------------------------
             console.log(document.body.firstChild) //第一个子节点,空格换行也算 
              console.log(document.body.firstElementChild);//第一个子元素节点,包含h1中所有内容
              //-------------------------------------------------------------
              console.log(document.body.lastChild);//最后一个子节点,空格换行也算 
              console.log(document.body.lastElementChild);//最后一个子元素节点
            //-------------------------------------------------------------
            //console.log(document.body.childNodes);//获取body中所有的子节点输出的是伪数组(元素节点,属性,文本节点,注释节点)
            //console.log(document.body.children);//获取body中所有的元素子节点
            //-------------------------------------------------------------------------------------------
            var firstChild = document.body.firstChild;//body中第一个节点 这里指的是<!-- 我是注释 -->
            var sec = firstChild.nextSibling;第一个节点的下一个节点    这里指的是 纸短情长
            var h1 = document.body.firstElementChild;//body中第一个元素节点  这里指的是 h1标签
            var title = h1.attributes.getNamedItem("id");//直接选中h1属性节点    这里指的是id="title"
            /*attributes 属性返回指定节点的属性集合        getNamedItem() 方法返回节点列表中指定属性名的值。*/
            // console.log("注释节点:nodeName="+firstChild.nodeName);//#comment
            // console.log("注释节点:nodeType="+firstChild.nodeType);//8
            //  console.log("注释节点:nodeValue="+firstChild.nodeValue);//注释内容    这里是 我是注释
            //  console.log("文本节点:nodeName="+sec.nodeName);//#text
            // console.log("文本节点:nodeType="+sec.nodeType);//3
            // console.log("文本节点:nodeValue="+sec.nodeValue);//文本内容    这里是 纸短情长
            // console.log("元素节点:nodeName="+h1.nodeName);//H1   这里是 大写的标签名
            // console.log("元素节点:nodeType="+h1.nodeType);//1
            // console.log("元素节点:nodeValue="+h1.nodeValue);//null
            console.log("属性节点:nodeName=" + title.nodeName);//属性名  这里是 id
            console.log("属性节点:nodeType=" + title.nodeType);//2
            console.log("属性节点:nodeValue=" + title.nodeValue);//属性值   这里是 title
        }
    </script>
</head>

<body>
    <!-- 我是注释 -->纸短情长<h1 id="title">我是一级标题</h1>
    <div id="box">我是div标签</div>
    <p class="box">我是p标签</p>
</body>
</head>

</html>

未获取对应id的dom节点,可直接用id操作dom

<div id="app">
        <div id="aaa">
        </div>
    </div>
//js代码
    console.log(app);
    console.log(aaa);

在这里插入图片描述
网上查询后发现了一点总结:

dom元素的id名称不和js内置属性或全局变量重名的话,该名称自动成为window对象的属性

猜你喜欢

转载自blog.csdn.net/z18237613052/article/details/112489841