javascript WEBAPI_DOM 知识整理_V1.0

目录

  1. 什么是webAPI
  2. 什么是dom
  3. 如何获取元素
  4. 如何注册事件、删除事件
  5. 如何操作元素内容、属性
  6. 元素、节点操作
  7. dom事件流、事件对象
  8. 阻止默认行为、阻止事件冒泡、事件委托
  9. 常用键盘事件

1.webAPI的理解

  webAPI是操作浏览器功能和页面元素的API(函数或对象方法),与浏览器相关的API对应于BOM,与页面元素相关对应于DOM;

2.DOM的理解

  dom即文档对象模型 --document object model

  一个页面即一个文档,页面中的内容(标签、文本、属性、注释)即节点;

  文档与节点通过树形结构表达关系,就形成了文档树,即DOM树;

  注意点: 标签节点即元素节点,亦称为‘元素’;

 3.获取元素

 相关知识:除使用以下方法,还可使用jquery中的获取元素方法

<body>
    <ul>
        <li id="byId">根据ID获取元素</li>
        <li>根据tag获取元素</li>
        <li class="byclass">根据类属性获取元素</li>
    </ul>
    <script>
        /*
        H5之前获取元素的方法总结
        document.getElementById()
        document.getElementsByTagName()
        */
        /*
        通过ID属性获取元素
        需要注意该方法,只获取单个元素,所以是Element
        id值前没有#,错误写法:
        document.getElementById('#byId');
        */
        var byId = document.getElementById('byId');
        /*
        输出结果:object
        因为是文档对象模型,即文档以及内部节点,都为对象
        */
        console.log(typeof byId);
        //---------------------------------
        /*
        通过tag标签获取元素
        获取的结果是一个伪数组
        伪数组:有数组的形态,有索引,能进行数组遍历,但是没有数组的Array的方法
        返回的是伪数组,那么如果想要获取第二个li,则使用 lis[1] 来获取 
        */
        var lis = document.getElementsByTagName('li');
        //---------------------------
        /*
        h5获取元素的方法
        document.getElementsByClassName()
        document.querySelector()
        document.querySelectorAll()
        */  
        /*
        通过class属性获取元素
        返回的也是一个伪数组
        */
        var  cls = document.getElementsByClassName('byclass');
        //------------------------
        /*
        querySelector()
        可以根据id class tag来获取单个元素。
        id 和 class 注意前面加#和. 
        通过标签获取,即获取文档中能获取到的第一个li元素
        querySelectorAll() 获取的是一个集合,返回的是一个伪数组
        细心会发现,id属性使用这个方法获取是没有意义的,因为id属性的唯一性,当然使用它也合法
        */
        var queryid = document.querySelector('#byId');
        var queryclass = document.querySelector('.byclass');
        var queryli = document.querySelector('li');
        var queryclasses = document.querySelectorAll('.byclass');
        var querylis = document.querySelectorAll('li');
        var ids = document.querySelectorAll('#byId');
        
        /*
        获取特殊元素:
        document.body   获取body元素
        document.documentElement 获取html元素
        */
        var body = document.body;
        var html = document.documentElement;
        
    </script>
</body>

 4.注册事件、删除事件

<body>
    <button>传统</button>
    <button>侦听</button>
    <button>ie9前侦听</button>
    <script>
        /*
        事件注册三部:
        获取事件源、注册事件、绑定事件程序
        */
        /*
        实例是传统的事件注册方法
        事件类型前需要加 on
        */
        var btns = document.querySelectorAll('button');
        btns[0].onclick = function(){}
        //--------------------------
        /*
        事件侦听注册事件  addEventListener()
        第一个参数是事件类型,字符串形式,不需要加 on 
        对于同一个元素,同一个事件可添加多个侦听器 
        */
        btns[1].addEventListener('click', fn)
        //--------------------------
        /*
        事件侦听注册事件,ie9之前的写法 attachEvent()
        第一个参数是加 on
        */
        btns[2].attachEvent('onclick', fn1)
        //----------------------------------------------
        /*
        删除事件的方法
        */
        /*
        传统删除事件方法
        */
        btns[0].onclick = null;
        /*
        删除 侦听注册事件
        removeEventListener()
        */
        btns[1].removeEventListener('click', fn);
        /*
        删除 ie9之前 侦听注册事件
        */
        btns[2].detachEvent('onclick', fn1);
    </script>
</body>

 5.操作元素内容、属性

<body>
    <div class="innertext"></div>
    <div class="innerhtml"></div>
    <div>
        <img src="" alt="">
        <input type="text">
        <input type="password" id='ipt'>
    </div>
    <script>
        /*
        innerText 和 innerHTML的区别
        innerText: 非标准,不识别HTML标签,去除空格和换行
        innerHtml: 标准,识别HTML标签,不去除空格和换行
        */
        var innertext = document.querySelector('.innertext');
        innertext.innerText = '<button>按钮</button>';
        var innerhtml = document.querySelector('.innerhtml');
        innerhtml.innerHTML = '<button>按钮</button>';
        //--------------------
        /*
        修改元素属性
        获取元素,可以直接赋值改变元素固有属性
        */
        var img = document.querySelector('img');
        img.src = './images/zxy.jpg';
        //对于表单元素同样可通过此来获取或修改属性
        var ipt = document.querySelector('input');
        ipt.value = '请输入内容';
        /*
        样式属性的修改:
        直接修改,
        通过class类名进行修改: 通过其修改,会覆盖之前的类型;此处类没有加.
        */
        ipt.style.backgroundColor = 'red';
        ipt.className = 'first change'
        /*
        自定义属性:
        getAttribute()
        setAttribute()
        removeAttribute()
        */
        ipt.setAttribute('index', 1);
        ipt.getAttribute('index');
        ipt.removeAttribute('index');
        //通过自定义修改class   这种方式也会覆盖之前的class类
        ipt.setAttribute('class', 'second');
        /*
        h5自定义属性,增加的dataset集合
        自定义以data-  开始的属性,都会在dataset集合中,
        可以通过dataset.  dataset[]  来获取属性值 
        */
        var ipt1 = document.querySelector('#ipt');
        ipt1.setAttribute('data-index', 5);
        ipt1.setAttribute('data-life-time', 16);
        console.log(ipt1.dataset.index);
        //当获取复合命名属性时,使用驼峰
        console.log(ipt1.dataset['leftTime']);
    </script>

6.元素节点、操作

<body>
    <div class="box">
        <span class="erweima">×</span>
    </div>
    <div id="app">
        <ul>
            <li>孙子1</li>
            <li>孙子2</li>
            <li>孙子3</li>
        </ul>
    </div>
    <script>
        /*
        节点的三个基本特性:
        nodeType: 元素节点值为1  属性节点值为2  文本节点值为3
        nodeName: 见案例
        nodeValue: 见案例
        */
        var box = document.querySelector('.box');
        var ewm = document.querySelector('.erweima');
        //nodeName: 'DIV', nodeValue: null
        console.dir(box);
        console.dir(ewm);
        /*
        节点获取:
        parentNode  获取最近的一个父节点
        childNodes  获取所有的子节点
        firstChild   获取第一个子节点
        lastChild  获取最后一个子节点
        */
        var ul = document.querySelector('ul');
        console.log(ul.parentNode); //获取的是最近的父节点  div#app
        var app = document.querySelector('#app');
        console.log(app.childNodes); //获取所有子节点  文本节点(回车) 元素节点(ul) 文本节点(回车)
        console.log(ul.firstChild);  //文本节点
        console.log(ul.lastChild);   //文本节点
    
        /*
        元素节点获取:
        firstElementNode:  获取第一个子元素节点   Ie9以上才支持
        lastElementNode:  获取最后一个子元素节点 IE9以上才支持
        children: 获取所有子元素节点,只获取子元素节点,不包括更深一层的节点  没有兼容性问题
        */
        console.log(ul.firstElementChild); //第一个li
        console.log(ul.lastElementChild); //最后一个li
        console.log(app.children);  //返回 ul   所有子节点 不包括孙节点
        //获取第一个和最后一个子元素的兼容性写法
        console.log(ul.children[0]);
        console.log(ul.children[ul.children.length - 1]);
        /*
        兄弟节点、元素节点获取
        nextSibling:  获取该元素的后一个兄弟节点
        previousSibling: 获取该元素前一个兄弟节点
        nextElementSibling: 获取该元素后一个兄弟元素节点 ,有兼容性问题
        previousElementSibling: 获取该元素前一个兄弟元素节点, 有兼容性问题
        */
        console.log(ul.children[1].nextSibling); //第二个li后的文本节点
        console.log(ul.children[1].previousSibling); //第二个li前的文本节点
        console.log(ul.children[1].nextElementSibling); //第三个li
        console.log(ul.children[1].previousElementSibling); //第一个li
        /*
        动态创建和添加元素节点
        createElement: 创建元素节点  每次创建的元素,只能添加一次,见如下案例
        appendChild: 往父节点中的最后添加节点
        insertBefore: 往父节点中的某个节点前添加节点
        */

        //只会执行 insertBefore  因为createElement 只创建了一个元素
        // var li = document.createElement('li')
        // ul.appendChild(li);
        // ul.insertBefore(li, ul.children[0]);

        var li1 = document.createElement('li');
        var li2 = document.createElement('li')
        ul.appendChild(li1);
        ul.insertBefore(li2, ul.children[0]);
        /*
        创建元素三种方式的区别
        */
        /*
        方式一:页面加载完成后,在调用,会导致页面重绘
        document.write('<div></div>')
        */
        /*
        方式二: 使用字符串拼接得方式
        innerHTML += '<div></div>'
        */
        /*
        对于innerHTML 还可使用数组的方式添加
        var arr = [];
        arr.push('<div></div>')
        innerHTML = arr.join('');
        */
        /*
        方式三: 使用createElement
        */
        /*
        关于创建多个元素,执行效率的比较:
        innerHTML 使用array数组方式,执行效率最快
        createElement 效率次之
        innerHTML 字符串拼接方式  效率最低,会影响性能,所以慎用
        */


        /*
        删除子节点
        removeChild
        */
        ul.removeChild(ul.children[0]);
        /*
        克隆节点:
        浅克隆: cloneNode(false)  只拷贝当前层节点
        深克隆: cloneNode(true)   拷贝节点以及所有层次的子节点
        */
        var qul = ul.cloneNode(false);
        console.log(qul);  //ul
        var sul = ul.cloneNode(true);
        console.log(sul); //包括ul内的li等节点     
    </script>
</body>

7.dom事件流、事件对象

<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        // dom 事件流 三个阶段
        // 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
        // 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。
        // 3. 捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段  document -> html -> body -> father -> son
        // var son = document.querySelector('.son');
        // son.addEventListener('click', function() {
        //     alert('son');
        // }, true);
        // var father = document.querySelector('.father');
        // father.addEventListener('click', function() {
        //     alert('father');
        // }, true);
        // 4. 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段  son -> father ->body -> html -> document
        var son = document.querySelector('.son');
        son.addEventListener('click', function() {
            alert('son');
        }, false);
        var father = document.querySelector('.father');
        father.addEventListener('click', function() {
            alert('father');
        }, false);
        document.addEventListener('click', function() {
            alert('document');
        })

        /*
        事件对象:
        1. event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看
        2. 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
        3. 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键
        4. 这个事件对象我们可以自己命名 比如 event 、 evt、 e
        5. 事件对象也有兼容性问题 ie678 通过 window.event 兼容性的写法  e = e || window.event;
        */
        son.addEventListener('click', function(e){
            e = e || window.event;
            console.log(e);
        })

        /*
        e.target 谁触发这个事件就指向谁
        */
        father.addEventListener('click', function(e){
            e = e || window.event;
            // e.target兼容性写法
            var target = e.target || e.srcElement;
            console.log(target);
            console.log(e.currentTarget);                
        })
        /*
        扩展知识: 事件函数中this 可使用 e.currentTarget 替代,但是不支持ie678
        */
    </script>
</body>

8.阻止默认行为、阻止冒泡事件、事件委托

<body>
    <a href="http://www.baidu.com">百度</a>
    <form action="http://www.baidu.com">
        <input type="submit" value="提交" name="sub">
    </form>
    <div class="father">
        <div class="son">son儿子</div>
    </div>
    <ul>
        <li>知否知否,点我应有弹框在手!</li>
        <li>知否知否,点我应有弹框在手!</li>
    </ul>
    <script>
        //  阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交
        var a = document.querySelector('a');
        a.addEventListener('click', function(e) {
                e.preventDefault(); //  dom 标准写法
            })
            // 3. 传统的注册方式
        a.onclick = function(e) {
            // 普通浏览器 e.preventDefault();  方法
            // e.preventDefault();
            // 低版本浏览器 ie678  returnValue  属性
            // e.returnValue;
            // 我们可以利用return false 也能阻止默认行为 没有兼容性问题 特点: return 后面的代码不执行了, 而且只限于传统的注册方式
            return false;
            alert(11);
        }
        /*
        阻止事件冒泡:
        stopPropagation  推荐写法
        cancelBubble  非标准写法
        */
        var son = document.querySelector('.son');
        son.addEventListener('click', function(e){
            alert(11);
            e.stopPropagation();
            // e.cancelbubble = true;
        },false) 

        /*
        事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
        本案例通过父元素冒泡给子元素,让子元素都注册该点击事件。
        */ 

        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e){
            var target = e.target || e.srcElement;
            target.style.backgroundColor = 'pink';
        },false)
    </script>
</body>

9.常用鼠标事件

<body>
    我是一段不愿意分享的文字
    <script>
        // 1. contextmenu 我们可以禁用右键菜单
        document.addEventListener('contextmenu', function(e) {
                e.preventDefault();
            })
            // 2. 禁止选中文字 selectstart
        document.addEventListener('selectstart', function(e) {
            e.preventDefault();

        })

         // 鼠标事件对象 MouseEvent
         document.addEventListener('click', function(e) {
            // 1. client 鼠标在可视区的x和y坐标
            console.log(e.clientX);
            console.log(e.clientY);
            console.log('---------------------');

            // 2. page 鼠标在页面文档的x和y坐标
            console.log(e.pageX);
            console.log(e.pageY);
            console.log('---------------------');

            // 3. screen 鼠标在电脑屏幕的x和y坐标
            console.log(e.screenX);
            console.log(e.screenY);

        })
        /*
        键盘事件:
        三个事件的执行顺序  keydown -- keypress -- keyup
        */
        /*
        keyup 键盘弹起时触发,识别功能键,不区分大小写
        */
        document.addEventListener('keyup', function() {
            console.log('我弹起了');
        })

        //keypress 按键按下的时候触发  不能识别功能键 比如 ctrl shift 左右箭头啊,但区分大小写
        document.addEventListener('keypress', function() {
                console.log('我按下了press');
            })
        //keydown 按键按下的时候触发  能识别功能键 比如 ctrl shift 左右箭头啊,不区分大小写
        document.addEventListener('keydown', function() {
                console.log('我按下了down');
            })
            
    </script>
</body>

 

posted @ 2020-06-04 08:03  fontEnd_whws  阅读(92)  评论(0)    收藏  举报