JS DOM

作者: 路上灵魂的自由者 | 来源:发表于2019-01-15 12:35 被阅读7次

    ### DOM数

    > dom tree

    > 当浏览器加载HTML页面的时候,首先就是DOM结构的计算,计算出来的DOM结构就是DOM树(把页面中的HTML标签像树状结构一样,分析出之间的层级关系)

    window

    document

    html

    head                             body

    meta title link  style..    div ul li script

    DOM树描述了标签和标签之间的关系(节点间的关系),我们只要知道任何一个标签,都可以依据DOM中提供的属性和方法,获取到页面中任意一个标签或者节点

    ### 在js中获取DOM元素的方法

    “ getElementById ”

    >通过元素的ID获取指定的元素对象,使用的时候都是“document.getElementById('')” 此处的document是限定了获取元素的范围,我们把它称为“上下文(context)”

    强调点:

    1.getElementById的上下文只能是document

    -因为严格意义上,一个页面中的ID是不能重复的,浏览器规定在这个文档中既可以获取这个唯一的ID

    2.如果页面中的ID重复了。我们基于这个方法只能获取到第一个元素,后面相同ID元素无法获取到

    3.在IE6-7浏览器中,会把表单元素(input...)的name属性值当作ID来使用(建议:使用使用表达元素的时候,不要让name和id值有冲突)

    “ getElementsByTagName ”

    ’[context].getElementsByTagName‘在指定的上下文中,根据标签名获取到一组元素集合(HTMLCollection)

    强调点:

    1.获取的元素集合点是一个类数组(不能直接的使用数组中的方法)

    var oBox = document.getElementById('box'),

    HTMLCollection = oBox.getElementsByTagName('div')

    2.他会把当前上下文中,子子孙孙(后代)层级内的标签都获取到(获取的不仅仅是儿子级的)

    3.基于这个方法获取到的结果永远都是一个集合(不管里面的是否有内容,也不管有几项,它是一个容器或者集合),如果想操作集合中具体的某一项,需要基于索引获取才可以 ....

    “ getElementsByClassName ”

    '[context].getElementsByClassName()'在指定的上下文中,基于元素的样式类名(class="xxx")获取一组元素集合

    强调点:

    1.真实项目中,我们经常基于样式类来给元素设置元素,所以在js中,我们也会经常基于样式类来获取元素,但是此方法在IE6-8下不兼容

    “ getElementsByName ”

    "document.getElementsByName()"它的上下文也只能是document,在整个文档中,基于元素的name属性值获取一组节点集合(也是一个类数组)

    前调点:

    1.在IE浏览器中(IE及以下版本),只对表单的name属性起作用(正常来说,我们项目中只会给表单元素设置name,给非表单元素name,其实是一个不太符合的设计)

    “ querySelector ”

    '[context].querySelector()' 在指定的上下文中基于选择器(类似于css选择器)获取到指定的元素对象(获取的是一个元素,哪怕选择器匹配了多个,我们之获取一个)

    “ querySelectorAll ”

    在querySelectorAll的基础上,我们获取到选择器匹配到的所有元素,结果是一个基点集合(nodeList)

    强调点:

    querySelector/querySelectorAll都是不兼容IE6-8浏览器的(不考虑兼容的情况下,我梦能用byID或者其他方式获取的,也尽量不要用这两个方法,这两个方法性能消耗比较大)

    document.querySelector("#HAHA")

    document.querySelectorAll("#HAHA")

    document.querySelectorAll('.box>div')

    document.querySelectorAll('.box>div')

    document.querySelectorAll('[name="hobby"]')

    “ document.head ”

    获取HEAD元素对象

    “ document.body ”

    获取BODY元素对象

    “ document.documentElement ”

    获取HTML元素对象

    ```javascript

    //=>需求: 获取浏览器一屏幕的宽度和高度(兼容所有的浏览器)

    document.documentElement.clientWidth ||

    document.body.clientWidth

    document.documentElement.clientHeight ||

    document.body.clientHeight

    ```

    ### 面试题:获取当前页面中所有ID为HAHA的元素(兼容所有浏览器)

    ```javascript

    //=>不能使用querySelectorAll

    /* 思路

    * 1.首先获取当前文档中所有的HTML标签

    * 2.依次遍历这些元素标签对象,谁的ID等于HAHA,我们就把谁存储起来即可

    */

    ```

    function queryAllById(id){

        var nodeList = document.getElementsByTagName('*'); //=>基于通配符*获取到这个文档中所有的标签

        // =>遍历集合中的每一项,把元素ID和传递ID相同的这一项存储起来

        var ary = [];

        for(var i = 0;i<nodeList.length;i++){

            var item = nodeList[i]

            item.id === id ? ary.push[item]:null

        }

        return ary;

    }

    queryAllById("HAHA");

    console.log(HAHA);  //在js中,浏览器中会自动把元素的id拿过来当变量用(不需要自己获取设置,而且ID重复,获取的结果就是一个集合,包含所有ID项,不重复就是一个元素对象(类似ById获取的结果))

    节点与描述节点之间的属性

    ### 节点(node)

    >在一个HTML文档中出现的所有东西的都是节点

    >元素节点(HTML标签)

    >文本节点(文字内容)

    >注释节点(注释内容)

    >文档节点(document)

    每一种类型的节点都会有一些属性区分自己的特点和特征

    -nodeType: 节点类型

    -nodeName: 节点名称

    -nodeValue: 节点值

    ```元素节点

    nodeType:1

    nodeType:大写标签名

    nodeValue:null

    ```

    ``` 文本节点

    nodeType:3

    nodeName:"#text"

    nodeValue:文本内容

    在标准浏览器中,浏览器都会把空格,换行当作文本节点处理

    ```

    ``` 注释节点

    nodeType:8

    nodeName:"#comment"

    nodeValue:注释内容

    ```

    ``` 文档节点

    nodeType:9

    nodeName:"#document"

    nodeValue:null

    ### 描述节点关系的属性

    " parentNode "

    > 获取当前节点唯一的父亲节点

    " childNodes "

    > 获取当前元素的所有子节点

    > -子节点:只获取儿子级别的

        -所有:包含元素节点,文本节点等

    " children "

    > 获取当前元素所有的元素子节点

    >在IE6-8中注释节点也当作元素节点来获取到,所有兼容性不好。

    " previousSibling "

    > 获取当前节点的上一个节点(获取的哥哥可能是元素也可能是文本等)

    > previousElementSibling :获取上一个哥哥元素节点(不兼容IE8)

    " nextSibling "

    > 获取当前节点的下一个弟弟节点

    > nextElementSibling: 下一个弟弟元素节点(不兼容IE8)

    " firstChild "

    > 获取当前元素的第一个子节点(可能是元素或文本等)

    > firstElementChild 获取第一个元素节点

    " lastChild "

    > 获取当前元素的最后一个子节点

    > lastElementChild 获取当前元素的最后一个子元素节点

    ```

    // 需求一: 获取当前元素的所有元素子节点

    // 基于children不兼容IE低版本浏览器(会把注释当作元素节点)

    /*

    * chikdren: 获取当前元素所有的元素子节点

    *  @parametet:

    * curEle: [object]current elemrnt

    *  @return

    *  [array]all the element nodes

    * by team on 2018

    */

    function children(curEle){

        var result = [],curEle = curEle.childNodes;

        for(var i = 0;i<curEle.length;i++){

            if(curEle[i].nodeType==1){

                list.push(curEle[i])

            }

        }

        return result;

    }

    console.log(children(course))

    // 需求:获取当前元素的上一个哥哥元素节点

    // > previousElementSibling不兼容

    /* prev:获取当前元素的上一个哥哥元素节点

    * @parameter

    * curEle: [object]

    * @return

    * [object] last elder brother element

    *  by skl on 2019

    */

    function prev(curEle){

        //=》先找当前元素的哥哥节点,看是否为元素节点,不是基于哥哥找哥哥的上一个节点。。。一直找到元素节点或者没有哥哥了(说明我就是老大),则结束查找

        var pre = curEle.previousSibling;

        while(pre && pre.nodeType!==1){

        /*

            * pre && pre.nodeType!==1

            *  pre是验证还有木有,这样写代码有,没有pre是null

            *  pre.nodeType是验证是否为元素

        */

           pre = pre.previousSibling;

        }

        return pre;

    }

    ```

    扩展:

    next下一个弟弟元素节点,

    prevAll获取所有哥哥元素节点,

    nextAll获取所有弟弟元素节点

    silbings获取所有兄弟节点,

    index获取当前元素的索引...

    ### DOM增删该查

    "

    createElement

    > 创建一个元素标签(元素对象)

    > `document.createElement([标签名])`

    appendChild

    > 把一个元素对象插入到指定容器的末尾

    > `[container].appendChild([newEle])`

    insertBofore

    > 把一个元素对象插入发哦指定容器中某一个元素标签之前

    > `[container].insertBofore([newEle],[oldEle])`

    cloneNode

    > 把某一个节点进行克隆

    > `[curEle].cloneNode()`: 浅克隆,只克隆当前标签

    > `[curEle].cloneNode(true)`:深克隆,当前标签及其里面的内容都一起克隆了

    removeChild

    > 在指定容器中删除每一个元素

    > `[container].removeChild([curEle])`

    set/get/removeAttribute

    设置/获取/删除 当前元素的某一个自定义属性值(两种方法)

    ···javascript

    var oBox = document.getElementById('box');

    // 1.=> 把当前元素作为一个对象,在对象对应的堆内存新增一个自定义属性

        //增加

            oBox.myIndex = 10;

        //获取

            console.log(oBox['myIndex'])

        //删除

            oBox.myIndex = null;

            delete oBox.myIndex

    // 2.=> 基于Attribute等DOM方法完成自定义属性的设置

        // 设置

            oBox.setAttribute('myColor','red');

        // 获取

            oBox.getAttribute('myColor');

        // 删除

            oBox.removeAttribute('myColor');

    上下两张机制属于独立的运作机制,不能互相混淆使用

    - 第一种是基于对象键值对操作方式,修改当前元素对象的堆内存空间来完成

    - 第二种是直接修改页面中HTML标签的结构来完成的(此种方法设置的自定义属性可以在结构上呈现出来)

    -基于setAttribute设置的自定义属性值都是字符串

    ···

    "

    ### 案例

    /*

    * 需求:解析一个URL字符串问号传参和HASH

    */

    // 解析a标签href

    function queryURLParameter(str){

        // 1.创建一个A标签,把需要解析的地址当作A标签的HREF赋值

            var link = document.createElement('a');

            link.href = str;  //页面中不需要展示A,我们只是想要利用它的属性而已,所以无需添加到页面

        // 2.A元素对象的HASH/SEarch两个属性分别存储了哈希值和参数值

            var search = link.search.substr(1);

            var hash = link.hash.substr(1);

        // 3.分别解析出HASH和参数即可

            var obj = {};

            hash?obj.HASH=hash: null;

            if(search){

                console.log(search)

                var list = search.split('&');

                for(var i = 0;i<list.length;i++){

                    var arrChildlist = list[i].split('=')

                    obj[arrChildlist[0]] = arrChildlist[1]

                }

        }

        return obj;

    }

    var str = 'https://www.baidu.com?lx=1&name=AA&age=1#teacher'

    queryURLParameter(str)

    相关文章

      网友评论

          本文标题:JS DOM

          本文链接:https://www.haomeiwen.com/subject/tvaedqtx.html