• Javascript面向对象基础


    DOM简介

    • DOM的概念

      • 文档对象模型(Document Object Model,简称DOM),是 W3C 组织推荐的处理可扩展标记语言(html或者xhtml)的标准编程接口。
      • W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。
    • DOM树

      • 文档:一个页面就是一个文档,DOM中使用document表示
      • 节点:网页中的所有内容,在文档树中都是节点(标签、属性、文本、注释等),使用node表示
      • 标签节点:网页中的所有标签,通常称为元素节点,又简称为“元素”,使用element表示

    获取元素

    • 根据ID获取
      • 语法:document.getElementById(id)
      • 作用:根据ID获取元素对象
      • 参数:id值,区分大小写的字符串
      • 返回值:元素对象 或 null
        <body>
            <div id="time">2019-9-9</div>
            <script>
                var timer = document.getElementById('time');
                console.log(timer);
                console.log(typeof timer);
                // console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法
                console.dir(timer);
            </script>
        </body>
    
    • 根据标签名获取元素
      • 语法:document.getElementsByTagName('标签名') 或者 element.getElementsByTagName('标签名')
      • 作用:根据标签名获取元素对象
      • 参数:标签名
      • 返回值:元素对象集合(伪数组,数组元素是元素对象)
    <body>
        <ul>
            <li>知否知否,应是等你好久11</li>
            <li>知否知否,应是等你好久22</li>
            <li>知否知否,应是等你好久33</li>
            <li>知否知否,应是等你好久44</li>
            <li>知否知否,应是等你好久55</li>
        </ul>
        <ul id="nav">
            <li>生僻字</li>
            <li>生僻字</li>
            <li>生僻字</li>
            <li>生僻字</li>
            <li>生僻字</li>
        </ul>
        <script>
            // 1.返回的是 获取过来元素对象的集合 以伪数组的形式存储的
            var lis = document.getElementsByTagName('li');
            console.log(lis);
            console.log(lis[0]);
            // 2. 我们想要依次打印里面的元素对象我们可以采取遍历的方式
            for (var i = 0; i < lis.length; i++) {
                console.log(lis[i]);
            }
            // 3. element.getElementsByTagName()  可以得到这个元素里面的某些标签
            var nav = document.getElementById('nav'); // 这个获得nav 元素
            var navLis = nav.getElementsByTagName('li');
            console.log(navLis);
        </script>
    </body>
    
    • H5新增获取元素方式
      • 根据类名返回元素对象集合:document.getElementsByClassName('类名');
      • 根据指定选择器返回第一个元素对象:document.querySelector('选择器');
      • 根据指定选择器返回:document.querySelectorAll('选择器');
      • 注意:querySelector 和 querySelectorAll里面的选择器需要加符号('#nav')
    <body>
        <div class="box">盒子1</div>
        <div class="box">盒子2</div>
        <div id="nav">
            <ul>
                <li>首页</li>
                <li>产品</li>
            </ul>
        </div>
        <script>
            // 1. getElementsByClassName 根据类名获得某些元素集合
            var boxs = document.getElementsByClassName('box');
            console.log(boxs);
            // 2. querySelector 返回指定选择器的第一个元素对象  切记 里面的选择器需要加符号 .box  #nav
            var firstBox = document.querySelector('.box');
            console.log(firstBox);
            var nav = document.querySelector('#nav');
            console.log(nav);
            var li = document.querySelector('li');
            console.log(li);
            // 3. querySelectorAll()返回指定选择器的所有元素对象集合
            var allBox = document.querySelectorAll('.box');
            console.log(allBox);
            var lis = document.querySelectorAll('li');
            console.log(lis);
        </script>
    </body>
    
    • 获取特殊元素(body,html)
      • 获取body元素:document.body
      • 获取html元素:document.documentElement

    操作元素

    • 改变元素的内容(获取或设置)
      • 从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉:element.innerText
      • 起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行:element.HTML
    <body>
        <button>显示当前系统时间</button>
        <div>某个时间</div>
        <p>1123</p>
        <script>
            // 当我们点击了按钮,  div里面的文字会发生变化
            // 1. 获取元素 
            var btn = document.querySelector('button');
            var div = document.querySelector('div');
            // 2.注册事件
            btn.onclick = function() {
                // div.innerText = '2019-6-6';
                div.innerHTML = getDate();
            }
            function getDate() {
                var date = new Date();
                // 我们写一个 2019年 5月 1日 星期三
                var year = date.getFullYear();
                var month = date.getMonth() + 1;
                var dates = date.getDate();
                var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
                var day = date.getDay();
                return '今天是:' + year + '年' + month + '月' + dates + '日 ' + arr[day];
            }
        </script>
    </body>
    
    • innerTextinnerHTML 的区别
      • 获取内容时的区别:innerText 会去除空格和换行,而 innerHTML 会保留空格和换行
      • 设置内容时的区别:innerText 不会识别html,而 innerHTML 会识别
    <body>
        <div></div>
        <p>
            我是文字
            <span>123</span>
        </p>
        <script>
            // innerText 和 innerHTML的区别 
            // 1. innerText 不识别html标签 非标准  去除空格和换行
            var div = document.querySelector('div');
            // div.innerText = '<strong>今天是:</strong> 2019';
            // 2. innerHTML 识别html标签 W3C标准 保留空格和换行的
            div.innerHTML = '<strong>今天是:</strong> 2019';
            // 这两个属性是可读写的  可以获取元素里面的内容
            var p = document.querySelector('p');
            console.log(p.innerText);
            console.log(p.innerHTML);
        </script>
    </body>
    
    • 常用元素的属性操作
      • innerText innerHTML
      • src href
      • id alt title
      • 获取属性的值:元素对象.属性名
      • 设置属性的值:元素对象.属性名 = 值
    <body>
        <button id="ldh">刘德华</button>
        <button id="zxy">张学友</button> <br>
        <img src="images/ldh.jpg" alt="" title="刘德华">
        <script>
            // 修改元素属性  src
            // 1. 获取元素
            var ldh = document.getElementById('ldh');
            var zxy = document.getElementById('zxy');
            var img = document.querySelector('img');
            // 2. 注册事件  处理程序
            zxy.onclick = function() {
                img.src = 'images/zxy.jpg';
                img.title = '张学友思密达';
            }
            ldh.onclick = function() {
                img.src = 'images/ldh.jpg';
                img.title = '刘德华';
            }
        </script>
    </body>
    
    • 表单元素的属性操作
      • 利用DOM可以操作如下表单元素的属性:type value checked selected disabled
      • 获取属性的值:元素对象.属性名
      • 设置属性的值:元素对象.属性名 = 值
    <body>
        <button>按钮</button>
        <input type="text" value="输入内容">
        <script>
            // 1. 获取元素
            var btn = document.querySelector('button');
            var input = document.querySelector('input');
            // 2. 注册事件 处理程序
            btn.onclick = function() {
                // 表单里面的值 文字内容是通过 value 来修改的
                input.value = '被点击了';
                // 如果想要某个表单被禁用 不能再点击 disabled  我们想要这个按钮 button禁用
                // btn.disabled = true;
                this.disabled = true;
                // this 指向的是事件函数的调用者 btn
            }
        </script>
    </body>
    
    • 样式属性操作
      • 行内样式操作:element.style
        • 元素对象.style.样式属性 = 值;
        • JS里面的样式采取驼峰命名法,比如fontSize、backgroundColor
        • JS修改style样式操作,产生的是行内样式,CSS权重比较高
      • 类名样式操作:element.className
        • 元素对象.className = 值;
        • 如果样式修改较多,可以采取操作类名方式更改元素样式
        • class因为是个保留字,因此使用className来操作元素类名属性
        • className会直接更改元素的类名,会覆盖原先的类名
    <body>
        <div></div>
        <script>
            // 1. 获取元素
            var div = document.querySelector('div');
            // 2. 注册事件 处理程序
            div.onclick = function() {
                // div.style里面的属性 采取驼峰命名法 
                this.style.backgroundColor = 'purple';
                this.style.width = '250px';
            }
        </script>
    </body>
    
    <body>
        <div class="first">文本</div>
        <script>
            // 1. 使用 element.style 获得修改元素样式  如果样式比较少 或者 功能简单的情况下使用
            var test = document.querySelector('div');
            test.onclick = function() {
                // this.style.backgroundColor = 'purple';
                // this.style.color = '#fff';
                // this.style.fontSize = '25px';
                // this.style.marginTop = '100px';
    
                // 2. 我们可以通过 修改元素的className更改元素的样式 适合于样式较多或者功能复杂的情况
                // 3. 如果想要保留原先的类名,我们可以这么做 多类名选择器
                // this.className = 'change';
                this.className = 'first change';
            }
        </script>
    </body>
    
    • 获取属性值
      • 获取属性值:element.属性
        • 获取内置属性值(元素本身自带的属性)
      • 获取自定义属性值:element.getAttribute('属性')
        • 主要获得自定义的属性
        <div id="demo" index="1" class="nav"></div>
        <script>
            var div = document.querySelector('div');
            // 1. 获取元素的属性值
            // (1) element.属性
            console.log(div.id);
            //(2) element.getAttribute('属性')  get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index
            console.log(div.getAttribute('id'));
            console.log(div.getAttribute('index'));
    	</script>
    
    • 设置属性值
      • 设置属性值:element.属性 = '值'
      • 设置自定义属性值:element.setAttribute('属性','值')
      div.id = 'test';
      div.className = 'navs';
      
      div.setAttribute('index', 2);
      div.setAttribute('class', 'footer'); 
      // class 特殊  这里面写的就是class 不是className
    
    • 移出属性
      • element.removeAttribute('属性')
      div.removeAttribute('index');
    
    • H5自定义属性

      • 自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
      • 自定义属性获取是通过getAttribute(‘属性’) 获取。
      • 但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。
    • 设置H5自定义属性

      • H5规定自定义属性以 data- 开头,作为属性名并且赋值
      <div data-index='1' id='div'></div>
      <script>
        var div = document.getElementById('div');
        div.setAttribute('data-index','2');
      </script>
    
    • 获取H5自定义属性
      • 兼容性获取:element.getAttribute('data-index');
      • H5新增(IE 11才开始支持):element.dataset.index 或者 element.dataset[index]
        <div getTime="20" data-index="2" data-list-name="andy"></div>
        <script>
            var div = document.querySelector('div');
            // console.log(div.getTime);
            console.log(div.getAttribute('getTime'));
            div.setAttribute('data-time', 20);
            console.log(div.getAttribute('data-index'));
            console.log(div.getAttribute('data-list-name'));
            // h5新增的获取自定义属性的方法 它只能获取data-开头的
            // dataset 是一个集合里面存放了所有以data开头的自定义属性
            console.log(div.dataset);
            console.log(div.dataset.index);
            console.log(div.dataset['index']);
            // 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
            console.log(div.dataset.listName);
            console.log(div.dataset['listName']);
        </script>
    

    节点操作

    • 节点概述

      • 网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
      • HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
      • 一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
        • 元素节点 nodeType 为1
        • 属性节点 nodeType 为2
        • 文本节点 nodeType 为3 (文本节点包含文字、空格、换行等)
      • 我们在实际开发中,节点操作主要操作的是元素节点
    • 节点层级

      • 利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系
    • 父级节点

      • node.parentNode
      • 该属性可返回某节点的父节点,注意是最近的一个父节点
      • 如果指定的节点没有父节点,则返回null
        <div class="demo">
            <div class="box">
                <span class="erweima">×</span>
            </div>
        </div>
        <script>
            // 1. 父节点 parentNode
            var erweima = document.querySelector('.erweima');
            // var box = document.querySelector('.box');
            // 得到的是离元素最近的父级节点(亲爸爸) 如果找不到父节点就返回为 null
            console.log(erweima.parentNode);
        </script>
    
    • 子节点
      • 所有子节点
        • parentNode.childNodes (标准)
        • 返回包含指定节点的子节点的集合,该集合为即时更新的集合
        • 返回值里包含了所有的子节点,包括元素节点,文本节点等
        • 如果只想要获得里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes
      • 子元素节点
        • parentNode.children (非标准)
        • 该属性是一个只读属性,返回所有的子元素节点,它只返回子元素节点,其余节点不返回
        • 虽然children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用
        <ul>
            <li>我是li</li>
            <li>我是li</li>
            <li>我是li</li>
            <li>我是li</li>
        </ul>
        <script>
            // DOM 提供的方法(API)获取
            var ul = document.querySelector('ul');
            var lis = ul.querySelectorAll('li');
            // 1. 子节点  childNodes 所有的子节点 包含 元素节点 文本节点等等
            console.log(ul.childNodes);
            console.log(ul.childNodes[0].nodeType);
            console.log(ul.childNodes[1].nodeType);
            // 2. children 获取所有的子元素节点 也是我们实际开发常用的
            console.log(ul.children);
        </script>
    
    • 第一个子节点

      • parentNode.firstChild
      • 返回第一个子节点,找不到则返回null,同样,也是包含所有的节点
    • 最后一个子节点

      • parentNode.lastChild
      • 返回最后一个子节点,找不到则返回null,同样,也是包含所有的节点
    • 第一个子元素节点(IE 9以上支持)

      • parentNode.firstElementChild
      • 返回第一个子元素节点,找不到则返回null
    • 最后一个子元素节点(IE 9以上支持)

      • parentNode.lastElementChild
      • 返回最后一个子元素节点,找不到则返回null
    • 日常开发

      • 获取第一个子元素节点:parentNode.children[0]
      • 获取最后一个子元素节点:parentNode.children[parentNode.children.length-1]
        <ol>
            <li>我是li1</li>
            <li>我是li2</li>
            <li>我是li3</li>
            <li>我是li4</li>
            <li>我是li5</li>
        </ol>
        <script>
            var ol = document.querySelector('ol');
            // 1. firstChild 第一个子节点 不管是文本节点还是元素节点
            console.log(ol.firstChild);
            console.log(ol.lastChild);
            // 2. firstElementChild 返回第一个子元素节点 ie9才支持
            console.log(ol.firstElementChild);
            console.log(ol.lastElementChild);
            // 3. 实际开发的写法  既没有兼容性问题又返回第一个子元素
            console.log(ol.children[0]);
            console.log(ol.children[ol.children.length - 1]);
        </script>
    
    • 下一个兄弟节点

      • node.nextSibling
      • 返回当前元素的下一个兄弟节点,找不到则返回null
    • 上一个兄弟节点

      • node.previousSibling
      • 返回当前元素上一个兄弟节点,找不到则返回null
        <div>我是div</div>
        <span>我是span</span>
        <script>
            var div = document.querySelector('div');
            // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等
            console.log(div.nextSibling);
            console.log(div.previousSibling);
            // 2. nextElementSibling 得到下一个兄弟元素节点
            console.log(div.nextElementSibling);
            console.log(div.previousElementSibling);
        </script>
    
    • 下一个兄弟元素节点((IE 9以上支持))

      • node.nextElementSibling
      • 返回当前元素下一个兄弟元素节点,找不到则返回null
    • 上一个兄弟元素节点((IE 9以上支持))

      • node.previousElementSibling
      • 返回当前元素上一个兄弟节点,找不到则返回null
    • 兼容性解决方案(封装一个兼容性函数)

       function getNextElementSibling(element) {
          var el = element;
          while (el = el.nextSibling) {
            if (el.nodeType === 1) {
                return el;
            }
          }
          return null;
        }  
    
    • 创建节点

      • document.createElement('tagName')
      • 动态创建元素节点
    • 添加节点

      • node.appendChild(child)
        • 此方法将一个节点添加到指定父节点的子节点列表末尾
      • node.insertBefore(child, 指定元素)
        • 此方法将一个节点添加到指定父节点的子节点列表前面
        <ul>
            <li>123</li>
        </ul>
        <script>
            // 1. 创建节点元素节点
            var li = document.createElement('li');
            // 2. 添加节点 node.appendChild(child)  node 父级  child 是子级 后面追加元素
            var ul = document.querySelector('ul');
            ul.appendChild(li);
            // 3. 添加节点 node.insertBefore(child, 指定元素);
            var lili = document.createElement('li');
            ul.insertBefore(lili, ul.children[0]);
            // 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
        </script>
    
    • 删除节点
      • node.removeChild()
      • 此方法从 node节点中删除一个子节点,返回删除的节点。
        <button>删除</button>
        <ul>
            <li>熊大</li>
            <li>熊二</li>
            <li>光头强</li>
        </ul>
        <script>
            // 1.获取元素
            var ul = document.querySelector('ul');
            var btn = document.querySelector('button');
            // 2. 删除元素  node.removeChild(child)
            // ul.removeChild(ul.children[0]);
            // 3. 点击按钮依次删除里面的孩子
            btn.onclick = function() {
                if (ul.children.length == 0) {
                    this.disabled = true;
                } else {
                    ul.removeChild(ul.children[0]);
                }
            }
        </script>
    
    • 复制(克隆)节点
      • node.cloneNode()
      • 此方法返回调用该方法的节点的一个副本,也称拷贝节点
      • 如果括号参数为空或者为false,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点。
      • 如果括号参数为true,则是深拷贝,即会克隆复制节点本身以及里面所有的子节点。
        <ul>
            <li>1111</li>
            <li>2</li>
            <li>3</li>
        </ul>
        <script>
            var ul = document.querySelector('ul');
            // 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
            // 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
            var lili = ul.children[0].cloneNode(true);
            ul.appendChild(lili);
        </script>
    

    创建元素的三种方式

    • document.write();

      • 直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
    • element.innerHTML

      • 将内容写入某个DOM节点,不会导致页面全部重绘
      • 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
    • createElement()

      • 创建多个元素效率稍低一点点,但是结构更清晰
    • 不同浏览器下,element.innerHTML 效率要比 createElement()

        <script>
            // 三种创建元素方式区别 
            // 1. document.write() 创建元素  如果页面文档流加载完毕,再调用这句话会导致页面重绘
             var btn = document.querySelector('button');
             btn.onclick = function() {
                 document.write('<div>123</div>');
             }
    
            // 2. innerHTML 创建元素
            var inner = document.querySelector('.inner');
             for (var i = 0; i <= 100; i++) {
                 inner.innerHTML += '<a href="#">百度</a>'
             }
    
            var arr = [];
            for (var i = 0; i <= 100; i++) {
                arr.push('<a href="#">百度</a>');
            }
            inner.innerHTML = arr.join('');
    
            // 3. document.createElement() 创建元素
            var create = document.querySelector('.create');
            for (var i = 0; i <= 100; i++) {
                var a = document.createElement('a');
                create.appendChild(a);
            }
        </script>
    

    innerTHMLcreateElement效率对比

    • innerHTML字符串拼接方式(效率低)
        (function () {
            var d1 = +new Date();
            for (var i = 0; i < 1000; i++) {
                document.body.innerHTML += '<div style="100px; height:2px; border:1px solid blue;"></div>';
            }
            var d2 = +new Date();
            console.log(d2 - d1);
        })();
    
    • createElement方式(效率一般)
        (function () {
            var d1 = +new Date();
            for (var i = 0; i < 1000; i++) {
                var div = document.createElement('div');
                div.style.width = '100px';
                div.style.height = '2px';
                div.style.border = '1px solid red';
                document.body.appendChild(div);
            }
            var d2 = +new Date();
            console.log(d2 - d1);
        })();
    
    • innerHTML数组方式(效率高)
        (function () {
            var d1 = +new Date();
            var array = [];
            for (var i = 0; i < 1000; i++) {
                array.push('<div style="100px; height:2px; border:1px solid blue;"></div>');
            }
            document.body.innerHTML = array.join('');
            var d2 = +new Date();
            console.log(d2 - d1);
        })();
    

    DOM的核心总结

    • 概述

      • 对于JavaScript,为了能够使JavaScript操作HTML,JavaScript就有了一套自己的DOM编程接口
      • 对于HTML,DOM使得HTML形成了一棵DOM树,包含文档、元素、节点
      • 关于DOM操作,我们主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。
    • 创建

      • document.write();
      • element.innerHTML 与数组结合,效率最高
      • createElement()
    • 增加

      • node.appendChild(child) 末尾追加
      • node.insertBefore(child, 指定元素) 前置追加
    • 删除

      • node.removeChild() 返回删除节点
    • 修改

      • 修改元素属性:src href title
      • 修改普通元素内容:innerHTML innerText
      • 修改表单元素:value type disabled
      • 修改元素样式:style className
    • 查询

      • DOM提供的API方法:getElementById getElementByTagName
      • H5提供的新方法:querySelector querySelectorAll
      • 利用节点操作获取元素:parentNode children previousElementSibling nextElementSibling
    • 属性操作

      • setAttribute 设置DOM的属性值
      • getAttribute 得到DOM的属性值
      • removeAttribute 移除属性
  • 相关阅读:
    升级python
    python内置函数整理
    import 搜索路径
    webpy 解决中文出现UnicodeDecodeError: 'ascii' codec can't decode byte 问题
    未预期的符号 `$'{ '' 附近有语法错误
    python引入模块时import与from ... import的区别
    "Native table 'performance_schema'.'session_variables' has the wrong structure") [SQL: "SHOW VARIABLES LIKE 'sql_mode'"]
    git命令
    Redis简介
    MongoDB基本操作
  • 原文地址:https://www.cnblogs.com/SharkJiao/p/13550081.html
Copyright © 2020-2023  润新知