web APIs:DOM

文档对象模型(Document Object Model,简称DOM )),是W3C组织推荐的处理可扩展标记语言(HTML或者XML )的标准编程接口

DOM树,所有都看做对象

文档:一个页面就是一个文档,DOM中使用document表示

元素︰页面中的所有标签都是元素,DOM中使用element表示

节点∶网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示

 

1、获取元素

根据ID获取:getElementById(),返回一个匹配到ID的DOM Element对象。若在当前Document下没有找到,则返回null。

根据标签名获取:getElementByTagName(),返回的是一个伪数组的集合,若为空,返回空伪数组;其元素对象是动态的。可以element.getElementByTagName()获取父元素下子元素内容,不包含父元素,一般给父元素添加id指定  

通过HTML5新增的方法获取:querySelector('选择器'),返回第一个元素;getElementByClassName();querySelectorAll('选择器'),返回所有符合条件元素,为数组, .class为类,#nav为id,标签不用加。H5下新增,需要兼容,该方法返回集合

特殊元素获取: document.body、document.documentElement

若要获取某些元素,可以用 getElementById().getElementByTagName()或其他组合

 

 

2、事件:触发响应机制,如鼠标点击

事件源  var btn = document.getElementById('btn');

事件类型  btn.onclick 绑定事件

事件处理程序 btn.onclick = function(){ alert('点击') }

 

3、操作元素

改变内容:.innerText,替换内容,不识别html标签和空格换行;.innerHTML 替换内容,识别html标签,保留空格和换行

修改元素属性:1、获取元素id或者标签等  2、注册事件 id.onclick   3、属性修改   cjj.onclick = fuction(){ img.src = '路径' }  点击改变图片

修改表单属性:type、value、checked、selected、disabled

修改样式属性:element.style()行内样式操作,新建行内样式style, 行内样式权重高、element.className(新类名)类内样式操作,引用新类,新类会覆盖旧类

获取元素属性:element.getAttribute('属性'); 该属性不但可以调用内置属性,还可以使用自定义属性,或者element.dataset.index / element.dataset['index'];

自定义属性:以data- 开头   data-list-name

element.getAttribute('data-list-name');  /  element.dataset.listName  / element.dataset['listName'];  dataset在ie11以上

 

更改元素属性:element.setAttribute('属性' , '值'); 这个可以用来设置索引号,对事件内外进行传参。比如点击这个按钮,内部要使用这个按钮所对应的索引号,无法直接传参,可以在事件之前使用set设置索引,然后内部用get获得

 var lis = document.querySelectorAll('li');
 var ps = document.querySelectorAll('p');
 for (var i = 0; i < lis.length; i++) {
        lis[i].setAttribute('index', i);   //设置形参
        lis[i].onclick = function () {   //形参
            this.className = 'select';
            var index = this.getAttribute('index');//类似传参
            ps[index].style.display = 'block';    //实参输入
        }
    }

移出元素属性:element.removeAttribute('属性' , '值');

 

4、节点操作:利用父子兄节点关系获取元素;逻辑性强,但是兼容性稍差

nodeType、nodeName、nodeValue

获取节点:父节点 parentNode,得到最近的父系节点,若找不到则返回null

<div class = ' box'>
    <span class = 'erweima'></span>
</div>

var erweima = document.querySelector( ' .erweima'); 
// varIbox = document.querySelector( '.box ');
erweima.parentNode;

同理,子节点 parentNode.childNodes; 包括文本,空格换行等,所有有时候会获取无用节点,利用判断nodeType获取真正需要的节点;不经常使用,一般使用 parentNode.children获取子元素节点

获得第一个、最后一个子节点 parentNode.firstChild; / parentNode.lastChild; 获得第一个、最后一个子元素节点 parentNode.firstElementChild; / parentNode.lastElementChild; 

兄节点:node.nextSibling  /  node.previousSibling,包含元素与文本;获取兄弟元素节点 node.nextElementSibling / node.previousElementSibling

 

创建节点:document.createElement('tagName'); 动态创建元素节点;

创建好后还要添加:node.appendChild('字节点'); node父级,该方法为后置添加;node.insertBefore(child, 指定元素) 指定位置添加,类似添加伪元素,若指定位置没有元素,也可添加,因为没有元素时返回undefined,如ul下无li,打印ul.children[0]返回undefined

 

删除节点:node.removeChild(child) 父节点删除子节点

如果是使用事件进行节点添加,当添加了新节点后,如果要对新节点进行 操作,需要在创建节点的内部实时更新节点并更新所获取的节点数组

    btn[0].onclick = function () {
        if (text.value != null) {
            var lis = document.createElement('li');
            lis.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
            comment.insertBefore(lis, comment.children[0]);   //添加节点
        }

        var del = document.querySelectorAll('a'); //添加了新的节点,需要在内部更新节点,在外部的话无法实时更新
        for (var i = 0; i < del.length; i++) {
            del[i].onclick = function () {
                comment.removeChild(comment.children[0]);   //内部删除
            }
        }
    }

如果不是使用事件进行节点添加,则无所谓

var tbody = document.querySelector('tbody');
    for (var i = 0; i < datas.length; i++) {
        var tr = document.createElement('tr');
        tbody.appendChild(tr);
        for (var j in datas[i]) {
            var td = document.createElement('td'); //循环创建td
            td.innerHTML = datas[i][j];
            tr.appendChild(td);
        }
        var td = document.createElement('td'); //循环创建td
        td.innerHTML = '<a href="JavaScript:;">删除</a>';
        tr.appendChild(td);

        
        
    }
    var a = document.querySelectorAll('a');
    for (var i = 0; i < a.length; i++) {
            a[i].onclick = function () {
                tbody.removeChild(this.parentNode.parentNode)
            }
        }

 

复制节点:node.cloneNode(); ,如果括号内为空或者false,则为浅拷贝,只拷贝节点本身,不拷贝子节点 加true则全复制;克隆后也一样需要添加

 三种动态创建元素

document.write();,全部重绘,不常用;

element.innerHTML; 如果循环创建多个元素的时候,如果直接使用innerHTML拼接多个字符串,效率较低,可以使用创建数组的方式,将多个字符串先放进数组,再数组转字符串,再一次绘制innerHTML,效率较高

 document.createElement();  创建多个元素时比innerHTML快很多,但是和数组结构化后的innerHTML比效率稍低,但是结构清晰

 

事件高级:

注册事件/绑定事件:传统都以on开头,有唯一性,一一对应,一个按钮执行一个事件,后面的新增函数会覆盖旧的;另一种为事件监听

事件监听注册:element.addEventLisener( type, listener[, useCapture]); 同一元素同一事件可以注册多个监听器  type = 'click'  不带on  /ie9之前用attachEvent   需要带‘on’

事件解绑:执行n次之后不执行,传统解绑,onclick = ‘null’  ;监听器 element.removeEventLisener( type, listener[, useCapture]);   

    var divs = document.querySelectorAll('div');
        divs[0].onclick = function() {
                alert(11);
                // 1. 传统方式删除事件
                divs[0].onclick = null;
            }
// 2. removeEventListener 删除事件 divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号 function fn() { alert(22); divs[1].removeEventListener('click', fn); }
// 3. detachEvent divs[2].attachEvent('onclick', fn1); function fn1() { alert(33); divs[2].detachEvent('onclick', fn1); }

 

DOM事件流  

 

事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播(先后关系),这个传播过程即DOM事件流。

1.JS代码中只能执行捕获或者冒泡其中的一个阶段

2. onclick 和 attachEvent (ie)只能得到冒泡阶段。

element.addEventLisener第三个参数为true时,执行捕获阶段,相反false或者省略,则执行冒泡 

 

事件对象  btn.onclick = function(event){ }

event / e: 与事件,如onclick相关的一系列信息,如键盘,鼠标

 

需要注意,当事件绑定的对象为事件触发(点击)对象时,target和this相同;但是,比如ul绑定事件,但是触发的不一定是ul,可能是li,冒泡,target和this不相同

 阻止事件默认行为,如点击链接不跳转:e.preventDefault();  e.returnValue ; return false也可以,但是后面代码不执行,一般放在最后

阻止冒泡:e.stopPropagation();   //  .cancelBubble() ie678下

 

冒泡的应用:事件委托

事件委派:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。

比如:给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。如此一来只操作了一次DOM,效率大大提高

 

禁止鼠标右键:contextmenu   禁止选中文字:selectstart

鼠标事件MouseEvent  click、mousemove

键盘事件KeyboardEvent  keyup、keydown、keypress该不识别功能键 shift、左右箭头等。keydown和up要注意场合来使用,比如点击某键触发文本框,应该用keyup键盘弹起后触发,否则按键值将输入

调用参数keyCode打印所按按钮的ascii码值,判断是哪一个按钮。keyup/down不区分大小写,press区分

 

3、pageshow和load事件

三种情况都会刷新页面都会触发load事件:1. a标签的超链接;2.F5或者刷新按钮(强制刷新);3.前进后退按钮

火狐中有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里,所以此时后退按钮不能刷新页面。

此时可以使用pageshow事件来触发。这个事件在页面显示时触发,无论页面是否来自缓存,在重新加载页面中,pageshow会在load事件触发后触发。

根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件给window添加。

 

4、change事件

监听元素,若元素发生改变,则执行函数

check.addEventListener('change', function(){    //状态一旦改变
    if(this.checked){     //如果是checked状态
   
     }
     else{              //unchecked状态
     } 
})

 

posted @ 2021-08-20 11:01  Jacky02  阅读(40)  评论(0)    收藏  举报