节点层次

图片描述

node类型-dom1

nodeName和nodeValue属性

https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType

Constant                                                                   Value              Description
Node.ELEMENT_NODE                                          1                    An Element node such as <p> or <div>.
Node.TEXT_NODE                                                   3                    The actual Text of Element or Attr.
Node.PROCESSING_INSTRUCTION_NODE           7                    A ProcessingInstruction of an XML document such as <?xml-stylesheet ... ?> declaration.
Node.COMMENT_NODE                                          8                   A Comment node.
Node.DOCUMENT_NODE                                      9                    A Document node.
Node.DOCUMENT_TYPE_NODE                            10                    A DocumentType node e.g. <!DOCTYPE html> for HTML5 documents.
Node.DOCUMENT_FRAGMENT_NODE                11                    A DocumentFragment node.
    var test = document.getElementById("aaa"); //假设我的aaa 是一个p元素
    console.log(test.nodeType);
    if(test.nodeType == 1){
        console.log("Node is an element");
        console.log(test.nodeName); //返回p
    }

至于nodeValue就是元素Element的名称

节点关系

  • 每个节点都有一个childNodes属性,其中保存着一个NodeList对象,是一个类数组对象(这个对象有length属性,但不属于Array对象)会随着dom结构变化而变化

  • 因为是类数组,所以访问里面的属性可以使用索引,也可以使用item()方法,效果是一样的

<div id="bbb">
    <p>dasdasdasdasdas</p>
    <p>dasdasdasdasdas</p>
    <p>dasdasdasdasdas</p>
    <p>dasdasdasdasdas</p>
</div>
    var test = document.getElementById("bbb");
    console.log(test.childNodes.length);//返回9,因为把空格都当成了节点,所以并不准确
    console.log(test.childNodes[0]);//返回一个#text对象,空白被当成了文本对象
    console.log(test.childNodes[1]);//返回<p>1</p>
    console.log(test.childNodes.item(0));//返回一个#text对象,空白被当成了文本对象
    console.log(test.childNodes.item(1));//返回<p>1</p>

因为childNodes会把dom里面的空格,也会计算进去,并且不同浏览器的空白也是不一样的,所以进行处理的时候需要先清理空白的dom

  • 每一个节点都会有一个parentNode属性,指向父节点

  • previousSibling指向前一个节点,nextSibling指向后一个

  • hasChildNodes判断是否包含子节点

操作节点

需要基于有parentNode属性才能使用

  • appendChild() 末尾添加一个节点

  • insertBefore() 指定在某个位置添加一个节点,两个参数(要插入的节点和作为参照的节点)

  • replaceChild() 替换节点,两个参数(要插入的节点和要替换的节点)

  • removeChild() 移除节点

cloneNode() 复制节点,参数是布尔值,是否进行深复制,深复制就是把所有子节点也复制,另外这个方法不会复制事件属性

Document类型

    var body = document.body; //取得body的引用
    var title = document.title; //取得title的引用
    console.log(document.URL); //取得完整的URL
    console.log(document.domain); //取得域名
    console.log(document.childNodes[0]);//对于document来说第一个元素就是html

getElementById 查找id
getElementByTagName 查找元素
getElementByName 查找有name属性的元素

    var test = document.getElementsByTagName("*");
    console.log(test);//获取所有的文档元素
    console.log(test[0]);//返回html元素
    console.log(test[1]);//返回head元素

Element类型

获取属性的话,自定义属性需要加上data-

    var div = document.getElementById("aaa");
    console.log(div.id); //可以获取这些属性
    div.id = "xxxx"; //也可以设置这些属性
    console.log(div.className);
    console.log(div.title);
    console.log(div.lang);
    //也可以这样获取属性
    console.log(div.getAttribute("id"));
    console.log(div.getAttribute("class"));
    console.log(div.getAttribute("title"));
    //也可以这样设置属性
    div.setAttribute("id","ooooo");
    //移除属性
    div.removeAttr("class");

创建元素createElement

创建的元素是没有加入到文档树中的,所以可以对其进行编辑后再放入文档树

    //先创建元素
    var div = document.createElement("div");
    //编辑元素的属性
    div.id = "myNewDiv";
    div.className = "box";
    //再放入文档树
    document.body.appendChild(div);

元素的子节点

    var ul = document.getElementById("list");
    //用tagname来获取所有的li标签
    var items = ul.getElementsByTagName('li');

dom操作技术

动态加载脚本

    //创建script元素
    var script = document.createElement("script");
    //写入type属性,javascript的属性是text/javascript
    script.type = "text/javascript";
    //写入js文件的路径和文件名
    script.src = "client.js";
    //写入dom树
    document.body.appendChild(script);

动态样式

需要注意的是css是放在head的

    var link = document.createElement("link");
    link.rel - "stylesheet";
    link.type = "text/css";
    link.href = "style.css";
    //因为只有一个head,所以用[0]数组第一个元素获取head标签
    var head = document.getElementsByTagName("head")[0];
    head.appendChild(link);

选择符API

querySelector()方法

返回第一个匹配的元素

   //支持元素,id,类,跟css的选择器和jq的选择器很像
    var body = document.querySelector("body");
    var myDiv = document.querySelector("#myDiv");
    var selected = document.querySelector(".selected");
    var img = document.body.querySelector("img.button");

querySelectorAll()

返回所有匹配的元素,是一个集合

    var ems = document.getElementById("myDiv").querySelectorAll("em");

    var i ,len = ems.length;
    //需要循环遍历来获取每一个元素,也可以用item()方法
    for(i=0;i<len;i++){
        console.log(ems[i]);
    }

matchSelector()

如果选择符和实际的元素匹配,就会返回true,不过因为浏览器之间的实现有差异,如果需要使用,就要封装一下:

    function matchesSelector(element, selector) {
        if (element.matchesSelector) {
            return element.matchesSelector(selector);
        } else if (element.msMatchesSelector) {
            return element.msMatchesSelector(selector);
        } else if (element.mozMatchesSelector) {
            return element.mozMatchesSelector(selector)
        } else if (element.webkitMatchesSelector) {
            return element.webkitMatchesSelector(selector);
        } else {
            throw new Error("Not supported");
        }
    }

元素遍历

  • childElementCount 返回子元素(不包括文本节点和注释)的个数

  • firstElementChild 指向第一个子元素

  • lastElementChild 指向最后一个子元素

  • previousElementSilbing 指向前一个同辈元素

  • nextElementSibling 指向后一个同辈元素

这些属性不必担心文本空白节点

    var i,len,child = element.firstChild;
    //旧方式
    while(child != element.lastChild){
        if(child.nodeType == 1){ //需要判断是不是元素,因为有可能是空白文本节点
            processChild(child);
        }
        child = child.nextSibling;
    }
    //新方式
    while (child != element.lastElementChild){ //这里不需要判断了
        processChild(child);
        child = child.nextElementSibling;
    }

H5 api

getElementsByClassName() 查找类

console.log(document.getElementsByClassName("class"));

className属性

<li id="test1" class="class1 class2">test1</li>

console.log(document.getElementById("test1").className.split(/\s+/));

如果要删除类,一个元素有两个class,一个class1 一个class2,假如要删除class2

    var div = document.getElementById("test1");
    //将class组成一个数组
    var classNames = div.className.split(/\s+/);
    var pos = -1, i;
    var len = classNames.length;
    for (i = 0; i < len; i++) {
        //只要这个数组里面有要删除的classs
        if (classNames[i] == "class2") {
            pos = i;
            break;
        }
    }
    //删除class组成的数组的一个元素,这个元素就是刚才匹配我们要删除的元素
    classNames.splice(pos, 1);
    //重新将数组组成一个字符串,赋值到html元素的的className
    div.className = classNames.join(" ");

很多js库都实现了这个方法,以简化这些操作

换成h5的api的话

    console.log(div.classList); //返回nodelist
    console.log(div.classList.remove("class1"));//很方便的删除和添加class
    console.log(div.classList.add("class3"));

焦点管理

    var button = document.getElementById("myButton");
    //只要有元素活的焦点,文档也就也有焦点
    button.focus();
    //确定文档是否获得焦点两种方式
    console.log(document.activeElement === button);//返回true
    console.log(document.hasFocus());//返回true 

自定义数据

html5 规定可以为元素添加非标准属性,但要添加data-前缀

    <li id="test1" data-myname="haha" class="class1 class2">test1</li>
        var div = document.getElementById("test1");
        console.log(div.dataset.myname);//返回haha
        div.dataset.myname = "lala";
        console.log(div.dataset.myname); //修改为lala

专业扩展

//强制ie7模式
<meta http-equiv="X-UA-COMPATIBLE" content="IE=7">

innerHTML

    var div = document.getElementById("test1");
    div.innerHTML = "<p>adasda</p>" +
        "<input type='text'>";

需要注意的是一些特殊符号需要转义,例如双引号要"

dom2 dom3

css设置

    div.style.backgroundColor = "red";
    div.style.width = "100px";

偏移量

  • offsetHeight 元素在垂直方向上占用的像素距离

  • offseWidt 略

  • offsetLeft 元素的左外边框至包含元素的左内边框之间的像素距离

  • offsetTop 略
    图片描述

客户区代大小

元素的客户区大小指的是元素内容及其内边距所占据的空间大小

  • clientWidth

  • clientHeight
    图片描述

滚动大小

包含滚动内容的元素的大小

  • scrollHeight 在没有滚动条的情况下,元素内容的总高度

  • scrollWidth, ...总宽度

  • scrollLeft 被隐藏在内容区域左侧的像素数,通过设置这个属性可以改变元素的滚动的位置

  • scrollTop 被隐藏在内容区域上方的像素数,通过设置这个属性可以改变元素的滚动的位置

  • 如果元素尚未滚动时,scrollLeft和scrollTop都为0

  • 如果元素被垂直滚动了,那么scrollTop会大于0,表示元素上方不可见内容的像素高度

  • scrollLeft类似

图片描述


线上猛如虎
2.2k 声望178 粉丝

你们都有梦想的,是吧.怀抱着梦想并且正朝着梦想努力的人,寻找着梦想的人,我想为这些人加油呐喊!