JS之DOM系列

141 阅读4分钟
DOM树:
  • 文档:一个页面就是一个文档
  • 元素
  • 节点:网页中所有内容都是节点
获取DOM元素
- 通过ID获取(getElementById)
- 通过name属性(getElementsByname)
- 通过标签名(getElementsByTagName)
- 通过类名(getElementsByClassName)
- 通过选择器获得一个元素(querySelector)
- 通过选择器获取一组元素(querySelectorAll)
- 获取HTML的方法(document.documentElement)
- 获取body的方法(document.body)
事件(可以被JS检测到的行为,触发--响应机制)
  • 事件三要素:事件源 事件类型 事件处理程序
  • 事件源:要触发的对象
  • 事件类型:怎么触发这个事情
  • 事件处理程序:发生了什么事情,处理结果
操作元素

操作元素内容:

  • element.innerText从起始位置到终止位置,但它除去html标签、空格、换行
    
  • element.innerHTML起始位置到终止位置的全部内容,包括html标签、空格和换行
    
排他思想

排他思想:如果同一组元素,我们想某一个元素实现某种样式,需要用到循环的排他思想算法

  1. 所有元素清除所有样式(干掉其他人)
  2. 给当前元素设置样式(留下我自己)
  3. 注意顺序不能颠倒,首先干掉其他人,再设置自己
  • 百度换肤效果案例:
  1. 循环注册事件;
  2. this.src 为当前图片路径,输出当前路径图片document.body.style.backgroundImage = 'url('+this.src+')'
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>百度换肤效果</title>
  <style>
    body {
      height: 100%;
      background: url(a.jpg) no-repeat top center;
      background-size: cover;
    }

    * {
      margin: 0;
      padding: 0;
    }

    ul,
    li {
      list-style: none;
    }

    .list li img {
      width: 100%;
    }

    .list {
      display: flex;
      justify-content: center;
      margin-top: 100px;
    }

    .list li {
      width: 150px;
      cursor: pointer;
    }

    .trans {
      transition: all .5s;
    }
  </style>
</head>

<body>
  <ul class="list">
    <li><img src="a.jpg" alt=""></li>
    <li><img src="b.png" alt=""></li>
    <li><img src="c.jpg" alt=""></li>
    <li><img src="d.jpg" alt=""></li>
  </ul>

  <script>
  //获取所有的背景
    var imgs = document.querySelector('.list').querySelectorAll('img');
    //循环注册事件
    for (var i = 0; i < imgs.length; i++) {
      imgs[i].onclick = function () {
        document.body.style.className = 'trans';
        document.body.style.backgroundImage = 'url(' + this.src + ')';
      }
    }
  </script>
</body>
</html>
  • 表格隔行变色效果案例:
  1. 鼠标经过(onmouseover)鼠标离开(onmouseout),获取tbody里面所有的tr,遍历tr绑定事件
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        table {
            width: 800px;
            margin: 100px auto;
            text-align: center;
            border-collapse: collapse;
            font-size: 14px;
        }
 
        thead tr {
            height: 30px;
            background-color: rgb(92, 193, 54);
        }
 
        tbody tr {
            height: 30px;
        }
 
        tbody td {
            border-bottom: 1px solid yellowgreen;
            font-size: 12px;
            color: darkgreen;
        }
 
        .bg {
            background-color: darkseagreen;
        }
    </style>
</head>
 
<body>
    <table>
        <thead>
            <tr>
                <th>代码</th>
                <th>名称</th>
                <th>净值</th>
                <th>累计</th>
                <th>前单位</th>
                <th>增长率</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>001</td>
                <td>西兰花</td>
                <td>23</td>
                <td>24</td>
                <td>25</td>
                <td>26%</td>
            </tr>
            <tr>
                <td>002</td>
                <td>西红柿</td>
                <td>23</td>
                <td>24</td>
                <td>25</td>
                <td>26%</td>
            </tr>
            <tr>
                <td>003</td>
                <td>马铃薯</td>
                <td>23</td>
                <td>24</td>
                <td>25</td>
                <td>26%</td>
            </tr>
            <tr>
                <td>004</td>
                <td>奇异果</td>
                <td>23</td>
                <td>24</td>
                <td>25</td>
                <td>26%</td>
            </tr>
        </tbody>
    </table>
    <script>
        // 1. 获取tbody 里的所有行
        var trs = document.querySelector('tbody').querySelectorAll('tr');
 
        // 2. 循环注册事件
        for (var i = 0; i < trs.length; i++) {
            // 鼠标经过更换背景
            trs[i].onmouseover = function () {
                this.className = 'bg';
            }
 
            // 鼠标离开背景初始化
            trs[i].onmouseout = function () {
                this.className = '';
            }
        }
    </script>
</body>
 
</html>
  • 表单全选和取消全选案例:
  1. 全选和取消全选:所有的复选框状态跟随全选按钮 checked 为 true 被选中;
  2. 所有复选框被选中,全选框也被选中:遍历所有复选框绑定点击事件,判断是否都被选中,若都选中,全选框被选中;若没全选中,全选框不被选中
  3. 利用flag = true 判断复选框是否选中,if(!某[i].checked){flag= false;break} 并把flag 赋给全选框.checked,判断其是否选中(true)
    <div class="wrap">
        <table>
            <thead>
                <tr>
                    <th>
                        <input type="checkbox" id="j_cbAll" />
                    </th>
                    <th>商品</th>
                    <th>价钱</th>
                </tr>
            </thead>
            <tbody id="j_tb">
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>iPhone8</td>
                    <td>8000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>iPad Pro</td>
                    <td>5000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>iPad Air</td>
                    <td>2000</td>
                </tr>
                <tr>
                    <td>
                        <input type="checkbox" />
                    </td>
                    <td>Apple Watch</td>
                    <td>2000</td>
                </tr>

            </tbody>
        </table>
    </div>
    <script>
        var j_cbAll = document.querySelector('#j_cbAll');
        var ipts = document.querySelector('#j_tb').querySelectorAll('input')
        j_cbAll.onclick = function() {
            for (var i = 0; i < ipts.length; i++) {
                ipts[i].checked = this.checked;
            }
        }

        for (var i = 0; i < ipts.length; i++) {
            ipts[i].onclick = function() {
                flag = true;
                for (i = 0; i < ipts.length; i++) {
                    if (!ipts[i].checked) {
                        flag = false;
                        break;
                    }
                }
                j_cbAll.checked = flag;
            }
        }
    </script>
</body>
属性
  • 获取属性值:
    • element.属性
    • element.getAttribute('属性') 主要针对于自定义属性
  • 设置属性值:
    • element.属性 = '值'(设置内置属性值)
    • element.setAttribute('属性','值') 主要针对自定义属性
  • 移除属性:
    • element.removeAttribute('属性') 自定义属性目的:
  1. 保存并使用数据。有些数据可以保存到页面中而不保存到数据库中
  2. 自定义属性通过element.getAttribute('属性')获取
  3. 自定义属性以data-开头作为属性名,规范防止歧义

获取元素通常使用两种方式:DOM提供的方法获取元素;利用节点层级关系获取元素

节点(元素节点1、属性节点2、文本节点3)操作:
1. 父节点:element.parentNode
2. 子节点:element.childNodes
3. 获取所有的子元素节点:element.children
4. 获取节点任意子节点:element.children[index]
5. 获取最后一个子节点:element.children[element.children.length - 1]
6. 兄弟节点:
    - element.nextSibling/previousSibling(包含元素、文本节点等等)
    - element.nextElementSibling/previousElementSibling(元素节点)
7. 创建节点:document.createElement('tagName')
8. 添加节点:
    - node.appendChild(child) node-父级 child-子级
    - node.insertBefore(child,指定元素)  添加在指定元素的前面
9. 删除节点:node.removeChild(child)	
10.复制节点:node.cloneNode();
    - 括号内为空或者false,浅拷贝,只克隆本身节点
    - 括号内为true,深拷贝,复制本身及其所有子节点
		  
  • 发布留言案例:
  1. 事件,判断textarea中是否有内容,如果textarea.value == '',return false;
  2. 否则创建元素li,li.innerHTML = textarea.value添加到最前边ul.insertBefore(li,ul.children[0])
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
  </head>
  <body>
     <textarea name="" id="" cols="30" rows="10"></textarea>
     <button>提交</button>
     <ul>
     </ul>
     <script>
         //获取元素
         var textarea = document.querySelector('textarea');
         var btn = document.querySelector('button')
         var ul = document.querySelector('ul')
         //绑定事件
         btn.onclick = function(){
             if (textarea.value === ''){
                 alert('内容不能为空,请入内容')
             }else{
             var li = document.createElement('li');// 创建li元素
             ul.appendChild(li)                    //增加元素节点
             li.innerHTML=textarea.value + "<a href='javascript:;'>删除</a>" ;        //赋值元素内容,并且增加删除按钮 JavaScript:;防止跳转
 
             var as = document.querySelectorAll('a');  // 思路:删除当前元素的父元素,因为它包含了a和li内容,也就是li
             for (var i =0 ;i<as.length;i++){
                 as[i].onclick = function(){
                     //node.removeChild(child); 删除的是li 当前a所在的li this.parentNode
                     ul.removeChild(this.parentNode)
                 }
             }
             }
           
         }
     </script>
 </body>
</html>

DOM重点核心:创建、增、删、改、查、属性操作、事件操作。

创建:
-  document.write
-  innerHTML
-  createElement
增:
- appendChild
- insertBefore
删:removeChild
改:主要修改元素属性
查:querySelector querySelectorAll等等
属性操作:setAttribute getAttribute removeAttribute
事件操作:onclick onmouseover onmouseout onfocus onblur 等
注册事件:方法监听注册事件eventTarget.addEventListener('type',listener[,useCapture])
删除事件:eventTarget.removeEventListener('type',fn)
DOM事件流

(事件发生时会在元素节点之间按照特定的顺序传播):事件捕获阶段,事件冒泡阶段

  1. js代码中只能执行捕获或者冒泡中的一个阶段。
  2. onclick和attachEvent只能得到冒泡阶段
  3. 捕获阶段 如果addEventListener第三个参数是true 那么则处于捕获阶段
  4. 冒泡阶段 如果addEventListener的第三个参数是false或者省略 那么则处于冒泡阶段
  • 事件对象:只有有了事件才会存在,事件对象是我们事件的一系列相关数据的集合
  • 阻止冒泡事件: 阻止方法:e.stopPropagation/e.cancelBubble = ture;
  • 事件委托: 事件委托原理:不是每个子节点单独设置事件监听器,而事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。