国强极客
有问题请加微信:guoqiang7585
国强极客

4、innerHTML nodeType

4、innerHTML nodeType

一、昨日反馈

1、事件对象

  • IE浏览器获取事件对象: window.event;
  • 非IE:使用的是事件处理函数的形参
  • 兼容性的写法:var e = window.event||evt;

2、获取页面中的节点

  • document.getEle….By…
  • document.querySelector(‘css选择器’);
  • document.querySelectorAll(‘css选择器’);
<ul>
    <li>刘备</li>
    <li>关羽</li>
    <li>张飞</li>
</ul>
<script>
    /*** 演示查找页面中的元素 **/
    //var liu = document.getElementsByTagName('li')[0];
    //var liu = document.querySelector('li'); //只查找符号条件的第一个元素
    var ul = document.querySelector('ul');
    var liu = ul.firstElementChild;
    liu.style.color = 'red';

    /*** 创建并添加元素 ***/
    //创建一个<li>曹操</li>,并放到ul中
    var li = document.createElement('li'); //创建li这个标签节点
    var text = document.createTextNode('曹操');
    li.appendChild(text); //把文本节点放到li中
    document.querySelector('ul').appendChild(li);
</script>

二、今日目标

  • 1、能够对属性类型的节点进行增删改查操作(重点)
  • 2、能够学会使用innerHTML和innerText(重点)
  • 3、知道通过nodeValue可以获得文本类型的节点的值
  • 4、知道nodeType表示什么
  • 5、能够掌握三种绑定事件的方式(重点)
  • 6、能够知道事件处理函数中this表示什么(重点、难点)
  • 7、能够知道如何移除事件
  • 8、能够通过事件对象的keyCode获取键盘的对应值
  • 9、了解什么是冒泡事件及会阻止冒泡事件的发生
  • 10、能够会用一种办法阻止标签的默认行为

三、DOM之属性节点操作

属性不能单独存在,一定属于一个标签。所有,操作属性,前提必须找到标签。

1、获取元素的属性

attributes:元素标签的所有属性

getAttribute(); :获取元素的属性。只能获取有具体值的属性 属性吗=‘属性值’

var t = input.getAttribute('type'); //getAttribute(); 获取type属性

元素.属性:获取元素的属性,能够获取类似于readOnly、cheCked等属性

var t2 = input.type; //获取type属性 能够获取类似于readOnly、checked等属性

2、添加/修改元素的属性

  • 元素节点.setAttribute(属性名,属性值)
  • 元素节点.属性名 = 值
<input type="text" name="tel" />
<script>
    //setAttribute方法
    var input = document.querySelector('input');
    input.setAttribute('name', 'email'); //修改,修改input的name值为email
    input.setAttribute('value', '你好'); //添加,添加value属性,值为你好
    //元素.属性名 = 值;
    input.size = 5;
    input.value = 'hello';
    input.disabled = true; // true表示禁用,false表示非禁用状态
</script>

如果要设置checked、readonly、disabled,则需要设置它的值为true或false。

3、删除元素的属性

  • 元素节点.removeAttribute(属性名) 删除一个属性

4、判断元素是否有哪个属性

  • elementNode.hasAttribute(属性名) 检测是否有某个属性,有返回true,没有返回false
<input type="text" name="tel" />
<script>
    var input = document.querySelector('input');
    //删除input的name属性
    input.removeAttribute('name');

    //判断元素的属性是否存在
    console.log(input.hasAttribute('name')); //false,上面删除了
    console.log(input.hasAttribute('type')); //true
</script>

总结:

  • 节点分为元素类型的节点和属性类型的节点,也包括文本类型的节点。

元素/标签类型的节点:

增: document.createElement()、document.createTextNode()、父节点.appendChild()、父节点.insertBefore()
删:父节点.removeChild();
改:父节点.replaceChild();
查:document.getEle….By…     document.querySelector()

属性类型的节点:

增:元素.setAttribute(属性名, 值);   元素.属性名 = 值;
删:元素.removeAttribute(属性名);
改:元素.setAttribute(属性名, 值);   元素.属性名 = 值;
查:元素.attributes;  元素.getAttribute(属性名);  元素.属性名;

四、DOM对象的通用属性

innerHTML:获取/设置元素里的html内容

innerText:获取/设置元素里面的文本内容

演示获取标签里面内容的代码:

演示获取标签里面内容的代码:

<p><span>你好</span><b>hello</b></p>
<script>
    //获取p元素里面的html内容 -- innerHTML
    //找到p元素
    var p = document.querySelector('p');
    console.log(p.innerHTML);

    //获取p元素里面的文本内容 -- innerText
    console.log(p.innerText);

    /** 设置p元素里面的内容 **/
    p.innerHTML = "<a href='#'>跳转</a>";  //设置p的内容之后,会覆盖掉原来的内容
    p.innerText = '最终文本'; //设置p的内容之后,会覆盖掉原来的内容
</script>

nodeName

nodeName 是只读的
​元素节点的 nodeName 与标签名相同
​属性节点的 nodeName 与属性名相同
​文本节点的 nodeName 始终是 #text
​文档节点的 nodeName 始终是 #document

nodeValue

元素节点的 nodeValue 是 undefined 或 null
​文本节点的 nodeValue 是文本本身
​属性节点的 nodeValue 是属性值

nodeType:调用nodeType属性会得到一个数字,这个数字表示节点的类型

元素 1
属性 2
​文本 3
注释 8
文档 9

下面代码演示了使用nodeValue和nodeType的例子:

下面代码演示了nodeType的其他用法:

<ul>
    <li>hello</li>
    <li>hello</li>
    <li>hello</li>
    <li>hello</li>
</ul>
<script>
    //先找到li
    var li = document.getElementsByTagName('li')[0];
    console.log(li.childNodes[0].nodeValue);

    //查看节点的类型 -- nodeType
    console.log(li.nodeType); // 元素类型的,结果是 1
    console.log(li.childNodes[0].nodeType); //文本类型的,结果是 3

    //使用nodeType的例子
    //先找到ul
    var ul = document.getElementsByTagName('ul')[0];
    //console.log(ul.children);  //children会忽略文本类型的子节点
    //函数,参数是父元素,返回该父元素的所有元素类型的子节点。但是不能使用children,必须使用childNodes
    function getChildren(ele){
        var all = ele.childNodes; //找到所有子元素,包含文本和标签类型
        var result = []; //用于保存元素类型的节点
        for(var i=0; i<all.length; i++){
            if(all[i].nodeType == 1){
                //nodeType是1,说明是标签类型的
                result.push(all[i]);
            }
        }
        return result;
    }

    console.log(getChildren(ul));
</script>

案例 — 全选、反选、取消

<p align="center">
    <a href="javascript:void(0);" id="quanxuan">全选</a>
    <a href="javascript:void(0);" id="fanxuan">反选</a>
    <a href="javascript:void(0);" id="quxiao">取消</a>
</p>

<table border="1" cellpadding="2" cellspacing="0" rules="all" align="center" width="500">
    <tr>
        <th>ID</th>
        <th>标题</th>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="id[]" value="1">
        </td>
        <td>诸葛亮是一个医学家</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="id[]" value="1">
        </td>
        <td>诸葛亮是一个医学家</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="id[]" value="1">
        </td>
        <td>诸葛亮是一个医学家</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="id[]" value="1">
        </td>
        <td>诸葛亮是一个医学家</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="id[]" value="1">
        </td>
        <td>诸葛亮是一个医学家</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="id[]" value="1">
        </td>
        <td>诸葛亮是一个医学家</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" name="id[]" value="1">
        </td>
        <td>诸葛亮是一个医学家</td>
    </tr>
</table>

<script>
    //全选
    //选择a标签,然后绑定单击事件
    document.getElementById('quanxuan').onclick = function(){
        //点击全选后,做的工作都写到这个函数中
        //alert(123);
        //找到所有的input标签
        var inputs = document.getElementsByTagName('input'); //找到所有的input
        //var inputs = document.querySelector('input[type="checkbox"]'); //找到所有的input
        //console.log(inputs);
        for(var i in inputs){
            inputs[i].checked = true;
        }
    };

    //取消
    //选择a标签,然后绑定单击事件
    document.getElementById('quxiao').onclick = function(){
        //点击取消后,做的工作都写到这个函数中
        //alert(123);
        //找到所有的input标签
        var inputs = document.getElementsByTagName('input'); //找到所有的input
        //var inputs = document.querySelector('input[type="checkbox"]'); //找到所有的input
        //console.log(inputs);
        for(var i in inputs){
            inputs[i].checked = false;
        }
    };

    //反选
    document.getElementById('fanxuan').onclick = function () {
        //找到所有的input标签
        var inputs = document.getElementsByTagName('input'); //找到所有的input
        //遍历,设置input的check属性
        for(var i in inputs){
            /*if(inputs[i].checked == true){
                inputs[i].checked = false;
            }else{
                inputs[i].checked = true;
            }*/
            inputs[i].checked = !inputs[i].checked;
        }
    };
</script>

五、DOM获取元素的位置

  • offsetLeft 元素在网页中水平坐标值
  • offsetTop 元素在网页中垂直坐标值
  • offsetWidth 元素在页面中占据的宽度
  • offsetHeight 元素在页面中占据的高度
  • scrollLeft 滚动条在容器中水平滚动的距离,多用于浏览器的滚动条
  • scrollTop 滚动条在容器中垂直滚动的距离,多用于浏览器的滚动条

有的浏览器只要一刷新,滚动条就会到最顶部,做左侧,所以需要绑定滚动事件
这部分内容一般用于窗口显示,异步加载等。目前可以作为了解的内容,等学习了jQuery,jQuery中有封装好的兼容各个浏览器的方法。

六、事件绑定与移除

事件绑定就是添加事件,那么为谁添加事件呢?可以为页面中的所有标签(元素、节点)添加事件,大到整个文档(document),小到其中一个标签都可以添加事件。

在为一个节点添加事件的时候,有三种方式:

  • 直接在标签中添加,即使用onclick、onmouseover等HTML属性;
  • DOM的方式添加,即通过dom方法获取节点,然后为其绑定事件;
  • 使用addEventListener或attachEvent(IE8及更低版本浏览器)。

为一个标签添加事件之后,还可以删除这个事件。

1、为DOM对象添加事件

最基本的语法:
DOM对象.事件 = 处理函数;

有些时候,可以先定义处理函数,然后在绑定事件:

事件处理函数中,this表示什么?

2、直接在HTML标签中添加事件

通过html标签的on….属性(onclick、onmouseover…),来添加事件。

如果说,单击按钮的时候,要执行的代码非常多,则可以将代码封装成函数,然后onclick的时候,调用函数即可,函数中的this是window对象。

如果上面两种绑定事件的方式都存在,执行哪一种?优先执行DOM方式绑定的事件

上面两种方式绑定事件,都可以通过设置事件处理函数为null来去取事件:

document.getElementById('btn').onclick = null;//取消事件

3、事件监听使用addEventListener或attachEvent方法添加事件

使用下面的方法为DOM对象添加事件,也叫做事件监听。

  • IE浏览器中用:元素节点.attachEvent(事件名, 事件处理函数);
  • 火狐浏览器用:元素节点.addEventListener(事件名, 事件处理函数);// 事件名不要带on

为了兼容各个浏览器,可以自定义一个兼容的函数,来为元素绑定事件:

button id="btn">点击测试</button>
<script>
    var btn = document.getElementById('btn');
    /*********** 自定义事件监听函数 ***********/
    function addEvent(ele, type, fn){
        if(window.addEventListener){
            ele.addEventListener(type, fn);
        }else{
            ele.attachEvent('on' + type, fn);
        }
    }
    //测试自定义函数是否可用
    function m(){
        alert(111);
    }
    addEvent(btn, 'click', m);
    
    function n(){
        alert(222);
    }
    addEvent(btn, 'click', n);//绑定两个相同的事件
    </script>

事件监听方式添加的事件,特点是可以为一个元素绑定多个同类型的事件。

通过事件监听方法添加的事件,也可以被移除,移除的方法是:

  • 火狐:元素节点.removeEventListener(事件名, 处理函数); //事件名不要带on
  • IE:元素节点.dettachEvent(事件名 处理函数);

也可以自定义一个兼容各个浏览器的移除事件监听的方法:

/*** 自定义事件监听移除函数 ***/
    function removeEvent(ele, type, fn){
        if(window.removeEventListener){
            ele.removeEventListener(type, fn);
        }else{
            ele.detachEvent('on' + type, fn);
        }
    }
    //调用移除方法,测试
    removeEvent(btn, 'click', m);

七、事件对象相关属性和方法使用

事件对象存在于事件处理函数中。不同的浏览器获取事件对象的方式也不同,IE始终使用window.event来当做事件对象,非IE浏览器使用事件处理函数的形参当做事件对象。

1、获取键盘的keyCode值

<input type="text" id="btn" />
<script>
    document.getElementById('btn').onkeyup = function (evt) {
        //IE获取事件对象的方法:window.event;
        //非IE浏览器获取事件对象的方式:处理函数是形参
        var e = window.event||evt; //兼容各个浏览器的获取事件对象的方式
        //console.log(e);
        //通过事件对象可以获取键盘的keyCode值
        var keyCode = e.keyCode; //获得的keyCode可以用于判断用户按的是哪个键
        console.log(keyCode);
    };
</script>

2、冒泡事件及阻止冒泡事件的发生

什么是冒泡事件?

上述小例子中,点击元素的子元素,会透过子元素触发元素本身的事件,这就是冒泡事件。
有些时候要的就是这个效果,可以不做任何处理;有些时候不希望有冒泡事件发生,那么可以通过事件对象的方法来阻止冒泡的发生。
阻止冒泡事件的发生有:

  • 标准浏览器使用 evt.stopPropagation(); //evt指的是事件对象
  • IE内核浏览器使用 window.event.cancelBubble = true;

可以封装一个兼容各个浏览器的阻止冒泡的方法:

<style>
        #d1{
            width:200px;
            height:200px;
            background-color: brown;
        }
        #d2{
            width:100px;
            height:100px;
            background-color: chartreuse;
        }
    </style>
<div id="d1">
    <div id="d2"></div>
</div>
<script>
    /** 阻止冒泡函数 **/
    function zuzhi(evt){
        if(window.event){
            window.event.cancelBubble = true;
        }else{
            evt.stopPropagation(); //evt指的是事件对象
        }
    }

    //分别给两个div绑定单击事件
    document.getElementById('d1').onclick = function () {
        alert(11111);
    };
    document.getElementById('d2').onclick = function (evt) {
        alert(22222);
        //阻止冒泡发生
        zuzhi(evt);
    };
</script>

3、阻止标签的默认行为

默认行为就是html标签的一些默认行为,比如点击a标签会跳转,比如点击了submit按钮表单会提交。这些都属于标签的默认行为。
有些时候,点击了a标签或者submit按钮后不希望执行标签的默认行为,这时候就需要阻止默认行为。
阻止默认行为:

  • 标准浏览器:evt.preventDefault();
  • IE内核浏览器:window.event.returnValue = false;
<a href="13冒泡事件.html">跳转</a>

<form name="f1" action="07全选.html" method="post">
    用户名:<input type="text" name="username"><br>
    密 码:<input type="password" name="pwd"><br>
    <input type="submit" id="sub" value="提交">
</form>

<script>
    /********* 阻止标签的默认行为 *********/
    //形参evt标签标准浏览器的事件对象
    function zuzhi(evt){
        if(window.event){
            //IE浏览器
            window.event.returnValue = false;
        }else{
            //非IE浏览器
            evt.preventDefault();
        }
    }

    //测试
    document.getElementById('sub').onclick = function (evt) {
        //检测用户名是否为空
        if(document.f1.username.value == ''){
            alert('用户名不能为空');
            //阻止表单提交
            zuzhi(evt);
            //return false; //return false也可以阻止表单提交
        }
    };
</script>

八、案例–可编辑的表格

1、完成html+css

   *{
            margin:0;
            padding:0;
            border:0 none;
        }
        table,th,td{
            border:solid 1px #1b272e;
            border-collapse: collapse; /*合并边框*/
        }
        table{
            width:400px;
            margin:10px auto; /*左右居中对齐*/
        }
        th,td{
            width:50%;
            padding:3px;
        }
<table>
    <thead>
    <tr>
        <th>ID</th>
        <th>姓名</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>1</td>
        <td>林冲</td>
    </tr>
    <tr>
        <td>2</td>
        <td>武松</td>
    </tr>
    <tr>
        <td>3</td>
        <td>金莲</td>
    </tr>
    <tr>
        <td>4</td>
        <td>武大</td>
    </tr>
    <tr>
        <td>5</td>
        <td>杨志</td>
    </tr>
    <tr>
        <td>6</td>
        <td>曹浩</td>
    </tr>
    </tbody>
</table>

2、JS做隔行换色

 //隔行换色
    //找到所有的tbody中的tr
    var trs = document.querySelectorAll('tbody tr');
    //console.log(trs);
    for(var i=0; i<trs.length; i++){
        if(i%2 == 0){
            trs[i].style.backgroundColor = '#d4d4d4';
        }
    }

3、给姓名所在的td添加单击事件

4、单击td,创建input并放到td中

5、设置input的样式和td一样

//兼容各个浏览器的获取完整css样式的写法
    function getStyle(node, styleName){
        if(node.currentStyle){
            //说明是IE
            return node.currentStyle[styleName];
        }else{
            return getComputedStyle(node)[styleName];
        }
    }

设置input的样式,并获取焦点:

6、给input绑定事件完全确定和取消功能

完整代码

<style>
        *{
            margin:0;
            padding:0;
            border:0 none;
        }
        table,th,td{
            border:solid 1px #1b272e;
            border-collapse: collapse; /*合并边框*/
        }
        table{
            width:400px;
            margin:10px auto; /*左右居中对齐*/
        }
        th,td{
            width:50%;
            padding:3px;
        }
    </style>
<table>
    <thead>
    <tr>
        <th>ID</th>
        <th>姓名</th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>1</td>
        <td>林冲</td>
    </tr>
    <tr>
        <td>2</td>
        <td>武松</td>
    </tr>
    <tr>
        <td>3</td>
        <td>金莲</td>
    </tr>
    <tr>
        <td>4</td>
        <td>武大</td>
    </tr>
    <tr>
        <td>5</td>
        <td>杨志</td>
    </tr>
    <tr>
        <td>6</td>
        <td>曹浩</td>
    </tr>
    </tbody>
</table>

<script>

    //兼容各个浏览器的获取完整css样式的写法
    function getStyle(node, styleName){
        if(node.currentStyle){
            //说明是IE
            return node.currentStyle[styleName];
        }else{
            return getComputedStyle(node)[styleName];
        }
    }

    //隔行换色
    //找到所有的tbody中的tr
    var trs = document.querySelectorAll('tbody tr');
    //console.log(trs);
    for(var i=0; i<trs.length; i++){
        if(i%2 == 0){
            trs[i].style.backgroundColor = '#d4d4d4';
        }
    }

    //找姓名所在的td
    var tds = document.querySelectorAll('tbody td:nth-child(2n)');
    //console.log(tds); //
    //循环,为每个符合条件的td绑定单击事件
    for(var i=0; i<tds.length; i++){
        //循环过程中,为每个td绑定单击事件
        tds[i].onclick = function(){
            //alert(123);
            // 创建一个input,设置input的样式和当前td样式一致。
            //input的value值应该是当前td中的文本

            //将this赋值给一个变量
            var td = this;

            //判断,如果说当前的td中有一个input了,就不要执行下面的代码了
            if(td.children.length >= 1){
                return false;
            }

            //保存td中的文本
            var text = td.innerText;
            //清空td
            td.innerHTML = '';
            //创建input
            var input = document.createElement('input');
            //设置input的样式
            input.style.width = getStyle(td, 'width');  // getConmputedStyle  currentStyle
            input.style.height = getStyle(td, 'height');
            input.style.backgroundColor = getStyle(td, 'backgroundColor');
            input.style.fontSize = getStyle(td, 'fontSize');
            input.style.outline = 'none';
            //设置input的value值
            input.value = text;
            //把input放到td中
            td.appendChild(input);
            //让input获取焦点
            input.focus();

            //绑定键盘事件
            input.onkeyup = function (evt) {
                var e = window.event||evt;
                var keyCode = e.keyCode;
                if(keyCode == 13){ //表示按了回车,表示确定
                    td.innerHTML = ''; //先清空td中的input
                    td.innerHTML = this.value;
                }
                if(keyCode == 27){ //按ESC键表示取消
                    td.innerHTML = ''; //先清空td中的input
                    td.innerHTML = text;
                }
            };
            //失去焦点,表示取消修改
            /*input.onblur = function () {
                td.innerHTML = text;
            };*/

        };
    }
</script>
赞赏
对内容有疑问,请加我微信:guoqiang7585

国强极客

文章作者

博客站长,有问题请加微信【guoqiang7585】。

国强极客

4、innerHTML nodeType
一、昨日反馈 1、事件对象 IE浏览器获取事件对象: window.event; 非IE:使用的是事件处理函数的形参 兼容性的写法:var e = window.event||evt; 2、获取页面中的节点 documen…
扫描二维码继续阅读
2019-12-06