js DOM(三)节点、元素创建3种方式、为元素绑定多个事件addEventListener、attachEvent

录:

     1.节点的概念
     2.节点的属性(nodeType,nodeName,nodeValue)
     3.父节点(父元素)
     4.获取子节点或子元素
     5.获取节点、元素的方法(12行代码)
     6.案例:div标签里面的p标签背景高亮(使用子节点或子元素的方式)
     7.封装节点兼容代码
     8.案例:切换背景图片
     9.案例:全选、全不选
    10.元素创建的第一种方式  document.write("<p>文本</P>");
    11.元素创建的第二种方式 document.getElementById("divId").innerHTML="<p>新添加的文本</P>";
    12.案例:点击按钮,在div中加载一张图片
    13.案例:动态创建列表(元素创建的第二种方式)
    14.第三种元素创建方式  var pEle = document.createElement("p");
    15.案例:动态创建列表(使用第三种元素创建方式)
    16.动态创建表格(使用第三种元素创建方式)
    17.【操作元素的一些方法】
    18.点击按钮,创建元素(只创建一次)
    19.为元素绑定多个事件
    20.为元素绑定事件的兼容代码
    21.解绑事件的三种方式
    22.解绑事件的兼容代码
    23.事件冒泡、阻止事件冒泡
    24.事件的3个阶段
    25.为同一个元素绑定多个不同事件,事件使用同一个处理函数
    26.案例:模拟百度搜索

1.节点的概念    <--返回目录
    * 文档:document
    * 元素:element,页面中所有的标签都是元素,标签--元素--对象
    * 节点:node,页面中所有的内容(标签、属性、文本)
    * 根元素:html这个标签

2.节点的属性(nodeType,nodeName,nodeValue)    <--返回目录
    * 节点的属性:可以通过标签(属性或文本).点出来
    * 节点类型nodeType:1--标签,2--属性,3--文本
    * 节点名称nodeName:标签节点--大写的标签名字,属性节点--小写的属性名字,文本节点--#text
    * 节点的值nodeValue:标签节点--null,属性节点--属性值,文本节点--文本内容

3.父节点(父元素)    <--返回目录
    * 只有标签可以作为父节点(父元素)
        - 获取所有的父节点   ele.parentNode;
        - 获取所有的父元素   ele.parentElement;

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>        
</head>
<body>
<div id="box">
    div里面的文本
    <p>p里面的文本</p>
</div>
<script type="text/javascript">
    var pEle = document.getElementById("box").getElementsByTagName("p")[0];
    console.log(pEle.parentNode);//[object HTMLDivElement]---说明父节点是标签
    console.log(pEle.parentElement);//[object HTMLDivElement]---说明父元素是标签

    var parentEle= pEle.parentNode;  //获取父标签
    console.log(parentEle.nodeType);  //1--标签类型
    console.log(parentEle.nodeName);  //DIV--标签名字
    console.log(parentEle.nodeValue);  //null--标签的值
</script>
</body>
</html>

4.获取子节点或子元素    <--返回目录
    * 获取所有的子节点  ele.childNodes;
    * 获取所有的子元素(子标签)  ele.children;

  【获取子节点或子元素】

<div id="box">
    div里面的文本
    <p>p里面的文本</p>
    <a href=""></a>
</div>
<script type="text/javascript">
    var divEle = document.getElementById("box");
    console.log(divEle.childNodes);//子节点NodeList(5) [ #text, p, #text, a, #text ]
    console.log(divEle.children);//子元素HTMLCollection [ p, a ]
</script>

  代码:【获取子节点】

<div id="box">
    div里面的文本
    <p>p里面的文本</p>
    <a href="">a标签里面的文本</a>
</div>
<script type="text/javascript">
    var divEle = document.getElementById("box");
    var _childNodes = divEle.childNodes;//子节点NodeList(5) [ #text, p, #text, a, #text ]
    for(var i=0;i<_childNodes.length;i++){
        console.log(_childNodes[i].nodeType+"---"+_childNodes[i].nodeName+"---"+_childNodes[i].nodeValue);
    }
</script>

  结果:
        3---#text---div里面的文本
        1---P---null
        3---#text---
        1---A---null
        3---#text---

  【根据属性名字获取属性节点】

<script type="text/javascript">
    var ele = document.getElementById("txt");
    var attNode = ele.getAttributeNode("name");
    console.log(attNode);//属性节点name="username"
    alert(attNode);//属性节点[object Attr]
    console.log(attNode.nodeType+"---"+attNode.nodeName+"---"+attNode.nodeValue);//2---name---username
</script>

5.获取节点、元素的方法(12行代码)    <--返回目录
    * 总结:凡是获取节点的代码在谷歌和火狐得到的都是节点,凡是获取元素的代码在谷歌和火狐总都是元素;
      除父(子)节点/元素,凡是获取节点的代码在IE8中得到的是元素,获取元素的代码不支持。

//父节点
ele.parentNode;
//父元素
ele.parentElement;
//子节点
ele.childNodes;
//子元素
ele.children;
//第一个子节点
ele.firstChild;
//第一个子元素
ele.firstElementChild
//最后一个子节点
ele.lastChild;
//最后一个子元素
ele.lastElementChild;
//某个元素的前一个兄弟节点
ele.previousSibling;
//某个元素的前一个兄弟元素
ele.previousElementSibling;
//某个元素的后一个兄弟节点
ele.nextSibling;
//某个元素的后一个兄弟元素
ele.nextElementSibling;

6.案例:div标签里面的p标签背景高亮(使用子节点或子元素的方式)    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>        
</head>
<body>
<input type="button" value="变色">
<div style="300px;border:2px solid blue">
    <span>这是span内的文本1</span>
    <p>这是p内的文本1</p>
    <span>这是span内的文本2</span>
    <p>这是p内的文本2</p>
</div>
<script type="text/javascript">
    var divEle = document.getElementsByTagName("div")[0];
    document.getElementsByTagName("input")[0].onclick=function(){
        var eles = divEle.children;//获取div标签里面所有的子标签
        //遍历所有的子标签,并判断是否是p标签
        for(var i=0;i<eles.length;i++){
            if(eles[i].nodeType===1 && eles[i].nodeName==="P"){
                eles[i].style.backgroundColor="red";
            }
        }
    };
</script>
</body>
</html>

7.封装节点兼容代码    <--返回目录
  获取任意一个父元素的第一个子元素

function getfirstEleChild(ele){
    //if(typeof ele.firstElementChild != "undefined"){
    if(ele.firstElementChild){  //ele.firstElementChild有值就为true
        return ele.firstElementChild;
    }else{
        var node = ele.firstChild;
        while(node && node.nodeType !=1){
            node=node.nextSibling;
        }
        return node;
    }
}

  获取任意一个父元素的最后一个子元素

function getlastEleChild(ele){
    if(ele.lastElementChild){  //ele.lastElementChild有值就为true
        return ele.lastElementChild;
    }else{
        var node = ele.lastChild;
        while(node && node.nodeType !=1){
            node=node.previousSibling;
        }
        return node;
    }
}

8.案例:切换背景图片    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>        
    <style type="text/css">
        img{
            150px;
        }
        div{
             700px;
            margin: 0 auto;
        }
        body {
            background:url("images/1.jpg");/*设置背景图片*/
        }
    </style>
</head>
<body>
<div id="box">
    <img src="images/1.jpg">
    <img src="images/2.jpg">
    <img src="images/3.jpg">
    <img src="images/4.jpg">
</div>

<script type="text/javascript">
    var eles = document.getElementById("box").children;
    for(var i=0;i<eles.length;i++){
        eles[i].onclick=function(){
            console.log(this.src);//file:///C:/Users/oy/Desktop/images/2.jpg
            document.body.style.background="url("+this.src+")";
            console.log("url("+this.src+")");//url(file:///C:/Users/oy/Desktop/images/2.jpg)
        };
    }
</script>
</body>
</html>

9.案例:全选、全不选    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>        
</head>
<body>
<table align="center" width="30%" cellspacing="0" border="1" bgcolor="#eee">
    <tr >
        <th><input type="checkbox" id="checkboxId"></th>
        <th>菜名</th>
        <th>饭店</th>
    </tr>
    <tbody>
        <tr align="center">
            <td><input type="checkbox" name=""></td>
            <td>aa</td>
            <td>aa</td>
        </tr >
        <tr align="center">
            <td><input type="checkbox" name=""></td>
            <td>aa</td>
            <td>aa</td>
        </tr>
        <tr align="center">
            <td><input type="checkbox" name=""></td>
            <td>aa</td>
            <td>aa</td>
        </tr>
    </tbody>
</table>
<script type="text/javascript">
    var checkboxEle = document.getElementById("checkboxId");
    var eles = document.getElementsByTagName("input");
    //为第一个checkbox注册点击事件
    checkboxEle.onclick=function(){
        //如果第一个checkbox选中,则全部选中; 否则,全部取消选中
        for(var i=0;i<eles.length;i++){
            eles[i].checked=this.checked;
        }
    };
    //为后面3个checkbox注册点击事件
    for(var j=1;j<eles.length;j++){
        eles[j].onclick=function(){
            //判断后面3个checkbox的状态,如果都被选中,则将第一个checkbox也选中
            var count=0;//计数器,用于保存选中的checkbox的个数
            for(var k=1;k<eles.length;k++){
                if(eles[k].checked){
                    count++;
                }
            }
            //如果计数器count=3,说明后面3个checkbox都被选中了,则将第一个checkbox也选中
            //如果计数器count<3,则将第一个checkbox去掉选中
            console.log(`count = ${count}`)
            if(count == 3){
                checkboxEle.checked=true;
            }else if(count<3){
                checkboxEle.checked=false;
            }
        };
    }
</script>
</body>
</html>

10.元素创建的第一种方式    <--返回目录
  document.write("<p>文本</P>");
        - 如果是页面加载完毕后,通过该种方式创建元素,页面之前的所有内容被清空
        - 如果是页面加载的时候,通过该种方式创建元素,页面之前的所有内容被保留

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>        
</head>
<body>
<input type="button" id="btn" value="按钮" />

<script type="text/javascript">
var ele = document.getElementById("btn");
ele.onclick=function(){
    document.write("<p>文本</P>");//该句代码是在点击按钮后执行,此时页面已经加载完毕,页面之前的所有内容被清空
};
document.write("<p>文本</P>");//页面加载的时候,通过该种方式创建元素,页面之前的所有内容被保留
</script>
</body>
</html>

11.元素创建的第二种方式    <--返回目录
  document.getElementById("divId").innerHTML="<p>新添加的文本</P>";

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>        
</head>
<body>
<input type="button" id="btn" value="按钮" />
<div id="divId" style=" 300px;height: 200px;border:2px solid pink">div原来的文本</div>

<script type="text/javascript">
var ele = document.getElementById("btn");
ele.onclick=function(){
    document.getElementById("divId").innerHTML="<p>新添加的文本</P>";//将原来的文本覆盖了
};
</script>
</body>
</html>

12.案例:点击按钮,在div中加载一张图片    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>    
    <style type="text/css">
        img{
             300px;
            height:300px;
        }
    </style>    
</head>
<body>
<input type="button" id="btn" value="按钮" />
<div id="divId" style="300px; height:300px; border:2px solid pink">div原来的文本</div>

<script type="text/javascript">
var ele = document.getElementById("btn");
ele.onclick=function(){
    //点击按钮,在div中加载一张图片,加载的图片也会应用已经定义的样式
    document.getElementById("divId").innerHTML="<img src='a.jpg'/>";
};
</script>
</body>
</html>

13.案例:动态创建列表(元素创建的第二种方式)    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>    
    <style type="text/css">
        *{
            padding: 0;
            margin: 0;
        }
    </style>    
</head>
<body>
<input type="button" id="btn" value="按钮" />
<div id="divId" style=" 300px;height: 300px;border:2px solid pink">div原来的文本</div>
<script type="text/javascript">
    var names = ["西施","杨玉环","貂蝉","王昭君"];
    var ele = document.getElementById("btn");
    ele.onclick=function(){
        var str = "<ul style='list-style-type:none;cursor:pointer'>";
        for(var i=0;i<names.length;i++){
            str += "<li>"+names[i]+"</li>";
        }
        str += "</ul>";
        document.getElementById("divId").innerHTML=str;
    };
</script>
</body>
</html>

14.第三种元素创建方式    <--返回目录
  var pEle = document.createElement("p");

<input type="button" id="btn" value="按钮" />
<div id="divId" style=" 300px;height: 300px;border:2px solid pink">div原来的文本</div>
<script type="text/javascript">
    document.getElementById("btn").onclick=function(){
        var pEle = document.createElement("p");
        pEle.innerText="这是p标签里面的文本";
        document.getElementById("divId").appendChild(pEle);//在后面追加
    };
</script>

15.案例:动态创建列表(使用第三种元素创建方式)    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>    
    <style type="text/css">
        *{
            padding: 0;
            margin: 0;
        }
    </style>    
</head>
<body>
<input type="button" id="btn" value="按钮" />
<div id="divId" style=" 300px;height: 300px;border:2px solid pink">div原来的文本</div>
<script type="text/javascript">
    var names = ["a","b","c"];
    document.getElementById("btn").onclick=function(){
        var parent = document.getElementById("divId");
        var ulNode = document.createElement("ul");
        parent.appendChild(ulNode);

        for(var i=0;i<names.length;i++){
            var node = document.createElement("li");
            node.innerText=names[i];
            ulNode.appendChild(node);
            node.onmouseover = mouseoverHandler;
            node.onmouseout = mouseoutHandler;
        }
    };
    var mouseoverHandler = function (){
        this.style.backgroundColor = "#ccc";
    };
    var mouseoutHandler = function (){
        this.style.backgroundColor = "";
    };
</script>
</body>
</html>

16.动态创建表格(使用第三种元素创建方式)    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>        
</head>
<body>
<input type="button" id="btn" value="按钮" />
<div id="divId" style=" 300px;height: 300px;border:2px solid pink">div原来的文本</div>
<script type="text/javascript">
    var names = [
        {"name":"百度","href":"http://www.baidu.com"},
        {"name":"谷歌","href":"http://www.google.com"},
    ];
    document.getElementById("btn").onclick=function(){
        //创建table元素,并添加到div元素下
        var parent = document.getElementById("divId");
        var table = document.createElement("table");
        table.border = "1";

        parent.appendChild(table);
        for(var i=0;i<names.length;i++){
            var node = names[i];
            //创建tr元素,并添加到table元素下
            var tr = document.createElement("tr");
            table.appendChild(tr);
            //创建第一列,并添加到tr下
            var td = document.createElement("td");
            td.innerText = node.name;
            tr.appendChild(td);
            //创建第二列,并添加到tr下
            var td = document.createElement("td");
            td.innerHTML = "<a href="+node.href+">"+node.name+"</a>";
            tr.appendChild(td);
        }
    };
</script>
</body>
</html>

17.操作元素的一些方法    <--返回目录
    * parentEle.appendChild(node);//追加子元素
    * parentEle.insertBefore(newChild,refChild);//在指定的元素refEle之前插入newEle
      parentEle.insertBefore(newChild,parentEle.firstElementChild);//在div里面最前面插入newEle

    * parentEle.replaceChild(newChild,refChild);//替换
    * parentEle.removeChild(parentEle.firstElementChild);//删除第一个子元素
    * 删除所有子元素
        while(parentEle.firstElementChild){
            parentEle.removeChild(parentEle.firstElementChild);//删除第一个子元素
        }

18.点击按钮,创建元素(只创建一次)    <--返回目录
    * 有则删除,无则创建,即创建之前先判断是否存在,存在删除,然后创建
    * 或者,创建之前先判断是否存在,存在就什么也不做,不存在就创建。

19.为元素绑定多个事件    <--返回目录
    * ele.addEventListener(type,listener,useCapture);//可以为同一个元素绑定多个相同的事件,谷歌火狐都支持,IE8不支持
        - 参数一:{string}type 事件的类型,没有on前缀
        - 参数二:{Function}listener 事件处理函数
        - 参数三:{boolean}useCapture 目前就写false,不解释

    * ele.attachEvent("onclick",fn);谷歌火狐不支持,IE8支持

 * 区别
  addEventListener 谷歌、火狐、IE11支持,IE8不支持
  attachEvent 谷歌、火狐不支持,IE11不支持,IE8支持

ele.addEventListener("click", function(){
    console.log(this); // this为ele这个对象
}, false);
ele.attachEvent("onclick", function(){
    console.log(this); // this为window这个对象
});

20.为元素绑定事件的兼容代码    <--返回目录
  为任意元素,绑定任意的事件,事件处理函数

function addEventListener(ele,type,fn){
    //判断浏览器是否支持这个方法
    if(ele.addEventListener){
        ele.addEventListener(type,fn,false);
    }else if(ele.attachEvent){
        ele.attachEvent("on"+type,fn);
    }else{
        ele["on"+type]=fn;
    }
}

21.解绑事件的三种方式    <--返回目录

  第一种:ele.onclick=null;

  注意:用什么方式绑定事件,就应该用对应的方式解绑事件

<input type="button" id="btn" value="按钮" />
<input type="button" id="btn2" value="解绑事件" />
<script type="text/javascript">
    document.getElementById("btn").onclick=function(){
        alert(1);
    };
    document.getElementById("btn2").onclick=function(){
        document.getElementById("btn").onclick=null;
    };
</script>

  第二种:ele.removeEventListener("click",命名函数的名字,false);

  IE8不支持addEventListener和removeEventListener

<input type="button" id="btn" value="按钮" />
<input type="button" id="btn2" value="解绑事件" />
<script type="text/javascript">
    var ele = document.getElementById("btn");
    ele.addEventListener("click",f1,false);
    ele.addEventListener("click",f2,false);

    //移除第二个绑定事件
    document.getElementById("btn2").onclick=function(){
        ele.removeEventListener("click",f1,false);
    };
    function f1(){
        console.log(1);
    }
    function f2(){
        console.log(2);
    }
</script>

  第三种:
  谷歌、火狐不支持,IE8支持

<input type="button" id="btn" value="按钮" />
<input type="button" id="btn2" value="解绑事件" />
<script type="text/javascript">
    var ele = document.getElementById("btn");
    ele.attachEvent("onclick",f1,false);
    ele.attachEvent("onclick",f2,false);

    //移除第二个绑定事件
    document.getElementById("btn2").onclick=function(){
        ele.detachEvent("onclick",f1);
    };
    function f1(){
        console.log(1);
    }
    function f2(){
        console.log(2);
    }
</script>

22.解绑事件的兼容代码    <--返回目录

//为任意的一个元素解绑任意事件、任意响应函数
function removeEventListener(ele,type,fnName){
    if(ele.removeEventListener){
        ele.removeEventListener(type,fnName,false);
    }else if(ele.detachEvent){
        ele.detachEvent("on"+type,fnName);
    }else{
        ele["on"+type]=null;
    }
}

  注意:以后,一般都使用兼容代码,不使用ele.onclick=null;为了以防多个人给同一个元素绑定了相同的事件

23.事件冒泡、阻止事件冒泡    <--返回目录
    * 事件冒泡:多个元素嵌套,这些元素都绑定了相同的事件,如果里面的元素的事件触发了,外面的元素的事件也自动触发。
    
    * 阻止事件冒泡:
        - window.event.cancelBubble = true; // IE特有的,谷歌支持,火狐不支持
        - e.stopPropagation(); // 谷歌火狐支持,IE不支持

24.事件的3个阶段    <--返回目录
    * 事件捕获阶段:从外向里
    * 事件目标阶段
    * 事件冒泡阶段:从里向外
    
    * addEventListener(,,false|true)
        - false:从目标阶段开始,从里向外冒泡
        - true:从外到里开始捕获,直到目标阶段【直到捕获事件的触发目标】
        - 一般默认使用false,很少用true

25.为同一个元素绑定多个不同事件,事件使用同一个处理函数    <--返回目录

<input type="button" id="btn" value="按钮" />
<script type="text/javascript">
    var ele = document.getElementById("btn");
    ele.onclick = fun;
    ele.onmouseover = fun;
    ele.onmouseout = fun;
    function fun(e){
        switch(e.type){
            case "click":
                console.log("鼠标点击事件");
                break;
            case "mouseover":
                console.log("鼠标进入事件");
                break;
            case "mouseout":
                console.log("鼠标离开事件");
                break;
        }
    }
</script>

26.案例:模拟百度搜索    <--返回目录

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>标题</title>    
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        ul{
            list-style-type: none;
        }
    </style>    
</head>
<body>
<div>
    <input type="text" id="txt" style=" 200px;"/>
    <input type="button" id="btn" value="搜索"/>
    <div id="divId" style=" 200px;display: none;border: 1px solid #ccc"></div>    
</div>
<script type="text/javascript">
    var keywords = ["我爱你","我喜欢你","我不喜欢你"];
    var txtEle = document.getElementById("txt");
    txtEle.onkeyup = function() {
        //获取文本框输入的内容
        var text = this.value;
        var tempArr = [];//用于存放匹配上的数据
        //把文本框输入的内容与数组中的数据进行对比,匹配上的数据添加到tempArr中
        for(var i=0;i<keywords.length;i++){
            console.log(text.length);
            if(text.length>0 && keywords[i].indexOf(text)==0){
                tempArr.push(keywords[i]);//追加
            }
        }
        console.log(tempArr);

        var div = document.getElementById("divId");
        //如果tempArr中有数据,创建列表
        if(tempArr.length>0){
            //先清空div中内容
            while(div.firstElementChild){
                div.removeChild(div.firstElementChild);//删除第一个子元素
            }
            var ul = document.createElement("ul");
            div.appendChild(ul);
            //根据tempArr的数据创建列表,添加到div中
            for(var j=0;j<tempArr.length;j++){
                var li = document.createElement("li");
                li.innerText = tempArr[j];
                ul.appendChild(li);

                //为li标签添加鼠标进入和移出事件
                li.onmouseover = function(){
                    this.style.backgroundColor = "#888";
                };
                li.onmouseout = function(){
                    this.style.backgroundColor = "";
                };
                //为li标签添加鼠标点击事件
                li.onclick = function(){
                    //将li标签内的文本添加到输入框中
                    txtEle.value = this.innerText;
                    //将div隐藏
                    div.style.display = "none";
                };
            }
            //使得div显示
            div.style.display = "block";
        }else{
            div.style.display = "none";
        }
    }
</script>
</body>
</html>

---

原文地址:https://www.cnblogs.com/xy-ouyang/p/12185293.html