一、节点操作
创建节点
docment.createElement('节点')
参数:标签名字符串
这些元素原先不存在,是根据需求动态生成的,所以也成为动态创建元素节点,会将创建好的对象作为返回值返回
创建文本
document.createTextNode('文本')
参数:文本内容字符串,并将新的节点返回
添加节点
1、father.appendChild(child) 追加元素 类似数组中的push()
将一个节点添加到指定父节点的子节点列表的末尾。类似css里面的after伪元素
2、father.insertBefore(child,指定元素)
将一个节点添加到父节点的指定子节点前面。类似css里面的before伪元素
<body><!-- 需求1:在段落p的后面添加一个span标签,添加span的文本内容‘我是一个span’需求2:在段落p的前面添加一个h1标签,添加h1的文本内容,‘我是一个h1’--><div id="box"><p>段落</p></div><button>添加span</button><button>添加h1</button><script>var btns = document.querySelectorAll("button");var p = document.querySelector("p");var box = document.getElementById("box");//需求1btns[0].onclick = function () {// 1.1创建节点var span = document.createElement("span");// 1.2 创建文本内容var spanTest = document.createTextNode("我是一个span");//1.3将文本内容放入到span节点里span.appendChild(spanTest);// 1.2追加节点box.appendChild(span);};//需求2btns[1].onclick = function () {// 2.1 创建节点var h1 = document.createElement("h1");//2.2创建h1文本内容var h1Test = document.createTextNode("我是一个h1");//2.3 将h1Test放入到节点内h1.appendChild(h1Test);//2.4 添加节点box.insertBefore(h1, p);};</script></body>
替换节点
replaceChild()
-可以使用指定的子节点替换已有的子节点
-语法:父节点.replaceChild(新节点,旧节点)
删除节点
写法一、father.removeChild(child)
写法二、child.parentNode.removeChild(child)
可以在DOM中删除一个子节点,返回删除的节点
<body><!-- 需求一:点击按钮1,将《金瓶梅》替换为《水浒传》需求二:点击按钮2,删除《金瓶梅》--><button>按钮1</button><button>按钮2</button><ul><li>《红楼梦》</li><li>《三国演义》</li><li>《西游记》</li><li>《金瓶梅》</li></ul><script>var btns = document.querySelectorAll("button");var ul = document.querySelector("ul");var jpm = ul.children[3];btns[0].onclick = function () {// 创建《水浒传》节点var newLi = document.createElement("li");var newLiTest = document.createTextNode("《水浒传》");newLi.appendChild(newLiTest);// 替换节点ul.replaceChild(newLi, jpm);};btns[1].onclick = function () {// 删除节点写法一ul.removeChild(jpm);// 删除节点写法二// jpm.parentNode.removeChild(jpm);};</script></body>
克隆节点
node.cloneNode() 返回调用该方法的节点的一个副本
参数:布尔值,默认是false
false 只克隆节点本身,不克隆里面的子节点
true 拷贝节点,拷贝内容
<body><!-- 需求:点击按钮克隆div元素--><div id="box">box盒子</div><button>克隆</button><script>var box = document.getElementById("box");document.querySelector("button").onclick = function () {// 克隆节点// var newBox = box.cloneNode();var newBox = box.cloneNode(true);//添加克隆节点box.parentNode.appendChild(newBox);};</script></body>
创建节点另外几种方式
(1)、element.innerHTML
允许更改html元素的内容,可以设置或返回表格行的开始和结束标签之间的HTML,可以解析html标签
(2)、 element.innerText
获取或设置元素的文本----以纯文本的方式直接显示,不可以解析html标签
(3)、document.write()
直接将内容写入页面的内容流,但是文档执行完毕,则会导致页面全部重绘
<body><!-- 需求1:获取ul里面的li内容需求2:在ul里添加《水浒传》到页面中innerHTML、document.write() --><button>获取</button><button>添加</button><ul><li>《红楼梦》</li></ul><script>var btns = document.querySelectorAll("button");var ul = document.querySelector("ul");// 需求1btns[0].onclick = function () {var test1 = ul.innerHTML;// console.log(test1, "test1");var test2 = ul.innerText;// console.log(test2, "test2");};//需求2btns[1].onclick = function () {// 第一种写法// var li = document.createElement("li");// li.innerHTML = "《水浒传》";// ul.appendChild(li);// 第二种写法ul.innerHTML = "<li>《红楼梦》</li><li>《水浒传》</li>";// document.write("<ul><li>《水浒传》</li></ul>");};</script></body>
(4)、insertAdjacentHTML() /əˈdʒeɪsnt/
insertAdjacentHTML() 是Element的API中的一个方法,可以将字符串文本转化为你想要的节点(Node),并且插入到你想要插入的位置中。而且它并不会向innerHTML一样会替换掉已有的节点,而是会插入到指定位置。
语法:element.insertAdjacentHTML(position,text)
参数1: position
顾名思义,就是想要插入的位置,一共有4个固定的值
-
- 'beforebegin':元素element自己的前面。
- 'afterbegin':插入到元素element里面的第一个子节点之前(也就是总是会插入到最前面,例如我插入5个节点,顺序是1、2、3、4、5,那么我就需要以5、4、3、2、1的顺序插入,有一种栈结构先进后出的感觉)。
- 'beforeend':插入元素element里面的最后一个子节点之后(这个比较容易理解,就是插入到最后一个节点后,例如我插入5个节点,顺序是1、2、3、4、5,那就正常的1、2、3、4、5就好啦,但是注意是在已有节点的后面哦)。
- 'afterend':元素element自己的后面。
参数2:text文本
可以结合``字符串使用
<body><button>获取</button><button>添加</button><ul><li>《红楼梦》</li></ul><script>var btns = document.querySelectorAll("button");var ul = document.querySelector("ul");btns[1].onclick = function () {// 第三种写法 insertAdjacentHTML()var li = `<li>《水浒传》</li>`;ul.insertAdjacentHTML('beforeend',li);};</script></body>
二、事件操作
注册事件方式
传统注册方法
利用on开头的事件,例如onclick
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
var btns = document.querySelectorAll("button");btns[0].onclick = function () {alert("1");//不执行};btns[0].onclick = function () {alert("2");//执行};
addEventListener
语法:
addEventListener(type,listener[,useCapture])
同一个元素同一个事件可以注册多个处理函数,按注册顺序依次执行
参数:
type:事件类型字符串,例如click、mouseover,注意这里不用带on
listener:事件处理函数,事件发生时,会调用该监听函数
useCapture:可选,是否在捕获阶段触发事件,需要一个布尔值,默认是false,在冒泡阶段处理程序,如果是true,就是在捕获阶段处理程序(后面事件流时,详细说)
注意:ie8及以下不支持
btns[1].addEventListener("click",function () {alert(1);},false);btns[1].addEventListener("click",function () {alert(2);},false);
attachEvent
语法:
attachEvent(type,listener) 在ie8中可以使用,其他浏览器不能用
参数:
type:事件的字符串,要on
listener:回调函数
注意:
这个方法也可以同时为一个事件绑定多个处理函数,不同的是它后绑定先执行
//在ie8中可以使用,其他浏览器不能用
btns[2].attachEvent("onclick", function () {alert("attachEvent 1");});btns[2].attachEvent("onclick", function () {alert("attachEvent 2");});
解绑事件(删除事件)
传统注册方式解绑
eventTarget.οnclick=null
btns[0].onclick = function () {alert("1");//解绑事件btns[0].onclick = null;};
addEventListener方法注册解绑
eventTarget.removeEventListener(type,listener)
btns[1].addEventListener("click", fun);function fun() {alert(1);btns[1].removeEventListener("click", fun);}
attachEvent 方法注册解绑
eventTarget.detachEvent(eventName,callback)
btns[2].attachEvent("onclick", fun1);
function fun1() {alert("attachEvent 1");btns[2].detachEvent("onclick", fun1);
}
DOM事件流
事件流概述
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播的过程叫事件流
例如:给idiv绑定一个事件,时间流顺序如下
事件流3个阶段
(1)、捕获阶段:从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递(从外向内)
(2)、当前目标阶段:触发自己的事件
(3)、冒泡阶段:当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发(从内向外)
事件流指定阶段
js代码中只能执行捕获或者冒泡其中的一个阶段,其中onclick和attachEvent只能得到冒泡阶段,我们可以通过addEventListener(type,listener[,useCapture])中的第三个参数来分别演示冒泡和捕获
useCapture:可选,是否在捕获阶段触发事件,需要一个布尔值,默认是false,在冒泡阶段处理程序,如果是true,就是在捕获阶段处理程序
<body>给box、box1绑定点击事件,弹出对应的信息需求1:弹出box、box1信息需求2:弹出box1、box信息--><div class="box"><div class="box1"></div></div><script>var boxs = document.querySelectorAll("div");// 需求1// boxs[0].addEventListener(// "click",// function () {// alert("我是box");// },// true// );// boxs[1].addEventListener(// "click",// function () {// alert("我是box1");// },// true// );//需求2boxs[0].addEventListener("click",function () {alert("我是box");},false);boxs[1].addEventListener("click",function () {alert("我是box1");},false);</script></body>
注意:
实际开发中我们很少使用事件捕获,我们更关注事件冒泡
有些事件是没有冒泡的,比如onblur、onfoucs、onmuseenter、onmouseleave
事件冒泡有时我们需要,有时需要避免
事件对象
概念
简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象,它有很多的属性和方法
box1.onmousemove = function (event) {};
注意:
- event 就是一个事件对象,写在我们侦听函数的小括号里面,当形参来看,这个形参,我们可以自己命名,例如event、evt、e等
- 事件对象是当事件触发了,系统自动给我们创建的,不需要我们去传入实参
- 事件对象在ie低版本中有兼容性问题,其兼容性的写法:event = event || window.event;,一般不用考虑
事件对象属性
e.target:返回触发事件的对象
e.type:返回事件的类型,比如:click、mouseover,不带on
e.cancelBubble:阻止冒泡 ie6-8使用(了解)
e.returnValue:阻止默认行为, ie6-8使用(了解)
e.preventDefault():阻止默认行为 非 ie6-8使用
e.stopPropagation():阻止冒泡 非 ie6-8使用
e.offsetX、e.offsetY:获取鼠标相对于当前元素的位置
e.clientX、e.clientY:获取鼠标相对于浏览器可见窗口的坐标
e.pageX、e.pageY:获取鼠标相对于文档页面的坐标
e.screenX,e.screenY:返回鼠标相对于电脑屏幕的x坐标
<body><div class="box"><div class="box1"></div><a href="https://www.baidu.com/">百度</a></div><script>var boxs = document.querySelectorAll("div");var a = document.querySelector("a");boxs[0].addEventListener("click", function (e) {//e.targetconsole.log(e.target, "e");console.log(this, "this");//e.typeconsole.log(e.type, "e.type");});a.onclick = function (e) {// 阻止默认行为e.preventDefault();// 阻止默认行为// return false;// 阻止冒泡e.stopPropagation();};</script></body>
课堂小案例:
当鼠标在box1中移动时,在box2中来显示鼠标的坐标
<body><div id="box1"></div><div id="box2"></div><script type="text/javascript">/* 需求:当鼠标在box1中移动时,在box2中来显示鼠标的坐标 *///获取两个divvar box1 = document.getElementById("box1");var box2 = document.getElementById("box2");box1.onmousemove = function (event) {// event = event || window.event;var x = event.clientX;var y = event.clientY;//在box2中显示鼠标的坐标box2.innerHTML = "x=" + x + "," + "y=" + y;};</script></body>
事件委托(代理、委派)
不给每个子节点单独设置事件监听,而是将事件统一绑定给元素的共同的祖先元素,然后利用冒泡原理影响设置每个子节点
通过事件委派可以减少事件绑定的次数,提高程序的性能
<body><!-- 需求:为每个超链接都绑定单击响应函数 --><button id="btn01">增加链接</button><ul id="u1"><li><a href="#" class="link">链接一</a></li><li><a href="#" class="link">链接二</a></li><li><a href="#" class="link">链接三</a></li></ul><script>//点击按钮,新建超链接var btn01 = document.getElementById("btn01");var u1 = document.querySelector("#u1");btn01.onclick = function () {//新建一个livar li = document.createElement("li");li.innerHTML = '<a href="#" class="link">新建超链接</a>';u1.appendChild(li);};//为ul绑定单击响应函数u1.onclick = function (event) {console.log(event.target);if (event.target.className == "link") {alert("hi");}};</script></body>
常用的键盘事件
键盘事件 | 触发条件 |
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发 |
e.keyCode 返回该键的ASCII值 键盘上每个字符有对应的数字
<body><input type="text" /><script>document.onkeydown = function (e) {console.log(e.keyCode);};//需求: 使文本框不能输入数字var int = document.querySelector("input");int.onkeydown = function (e) {if (e.keyCode >= 48 && e.keyCode <= 57) {/* 在文本框输入内容,属于keyCode的默认行为return false则会取消默认行为 */return false;}};</script></body>