目录
定义
DOM(文档对象模型):是W3C推荐的处理可拓展性标记语言(HTML/XML)的标准编程接口。
DOM树
文档(document):一个页面就是一个文档。
元素(element):页面中所有标签都是元素。
节点(node):网页中所有内容都是节点(标签、文本、属性、注释等)
一、获取元素
1、根据ID获取
document.getElementById('参数')
2、根据标签名获取
document.getElementsByTagName()
- 返回的是获取过来的元素对象的集合 以伪数值的形式存储
- 若页面中没有这个元素 返回一个空的伪数组
拓展:获取某个元素(父元素)内部指定标签名的子元素
element.getElementsByTagName('标签名')
- 父元素必须是单个对象 不能是数组等 获取时不包括父元素自己
3、H5新增方法获取——均是以伪数组的形式返回
(1)根据类名获取某些元素的集合
document.getElementsByClassName()
(2)返回指定选择器的第一个元素对象
document.querySelector('选择器')
里面的选择器要加符号:eg标签名——'div',类名——'.box',ID名——'#nav'
(3)返回指定选择器的所有元素对象集合
document.querySelectorAll()
4、获取某些特殊元素(body、html)
(1)document.body 返回body元素对象
(2)document.documentElement 返回html元素对象
二、事件
1、定义
可以被JavaScript侦测到的行为 触发——响应机制
2、事件三要素
事件源 事件类型 事件处理程序
<body>
<!-- 获取事件源 -->
<button id="btn">唐伯虎</button>
<script>
// 注册事件 事件类型 鼠标点击onclick
var btn = document.getElementById('btn');
// 事件处理程序 通过一个函数赋值的方式
btn.onclick = function(){
alert('点秋香');
}
</script>
</body>
三、操作元素
1、改变元素内容
(1)element.innerText
- 不识别html标签 非标准
- 去除空格和换行
(2)element.innerHtml
- 识别html标签 W3C标准
- 保留空格和换行
2、改变元素属性
(1)获取属性值
element.属性
element.getAttribute('属性');
区别:
- element.属性 获取内置属性值(元素本身自带的属性)
- element.getAttribute('属性'); 主要获得自定义的属性(标准)我们程序员自定义的属性
(2)改变元素属性值
element.属性='值'
element.setAttribute('属性','值'); 主要针对于自定义属性
(3)移除元素属性值
removeAttribute(属性)
<body>
<div id="demo" index="1" class="nav"></div>
<script>
// 1.获取元素的属性值
// (1)element.属性
console.log(div.id); //demo
// (2)element.getAttribute('属性') get获取 attribute 属性
// 自定义属性:程序员自己添加的属性
console.log(element.getAttribute('id')); //demo
console.log(element.getAttribute('index')); //1
//2.设置元素属性值
// (1)element.属性='值'
div.id = 'test';
div.className = 'nnnavs';
// (2)element.setAttribute('属性','值'); 主要针对于自定义属性
div.setAttribute('index',2);
div.setAttribute('class','special'); //class比较特殊 这里就是使用class 而不是className
// (3)移除属性 removeAttribute(属性)
div.removeAttribute('index');
</script>
</body>
案例:点击切换照片
<script>
//先获取元素
var box = document.getElementById('box');
var img = document.querySelector('img');
//注册事件 处理程序
box.onclick = function(){
//点击的时候更换照片以及照片的title
img.src='images/xxx.jpg';
img.title='我是新的照片';
}
</script>
3、改变表单元素
利用DOM可以操作表单元素属性:type、value、checked、selected、disabled
注意:表单里面的值 文字内容是通过value来修改的
input.value = '我被修改了';
//如果想要某个表单被禁用 不用再被点击 disabled
input.disabled = true;
4、修改样式属性
(1)element.style
- 行内样式操作 产生的是行内样式 权重比css高
- 采用驼峰命名法
//将背景颜色改成紫色
属性名.style.backgroundColor = 'purple';
(2)element.className
- 类名样式操作 会覆盖原先的类名
- 适用于样式修改较多的情况
</head>
<style>
.change {
color:rgb(161, 66, 66);
font-size:25px;
}
</style>
</head>
<body>
<div>文本</div>
<!-- //多样式情况 -->
<!-- <div class="first">文本</div> -->
<script>
var text = document.querySelector('div');
text.onclick = function(){
text.className = 'change';
// text.className = 'first change';
}
</script>
<body>
5、排他思想:首先先排除其他人 然后再设置自己的样式
如果有同一组元素,我们想要某一个元素实现某种样式,需要用到循环的排他思想
(1)所有元素全部清除样式(干掉其他人)
(2)给当前元素设置样式(留下我自己)
(3)注意顺序不能颠倒,首先干掉其他人,再设置自己
<body>
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<script>
//1、获取所有按钮元素
var btns = document.getElementsByTagName('button');
//btns得到的是伪数组 里面的每一个元素 btns[i]
for(var i=0; i<btns.length; i++){
btns[i].onclick = function(){
//将所有的按钮的背景颜色都去掉
for(var i=0; i<btns.length; i++){
btns[i].style.backgroundColor = '';
}
//2.再让当前元素背景颜色为pink
btn[i].style.backgroundColor = 'pink';
}
}
</script>
</body>
6、H5新增的自定义属性
自定义属性目的:是为了保存并使用数据,有些数据可以保存到页面中而不用保存在数据库中。
(1)设置H5自定义属性
为了更容易判断元素的内置属性和自定义属性。H5规定自定义属性以 data- 开头作为属性名并且赋值。
比如:<div data-index = '1></div> 或者使用JS设置 element.setAttribute('data-index',2);
(2)获取H5自定义属性
兼容性获取
element.getAttribute('data-index');
H5新增
element.dataset.index
element.dataset['index']
- ie 11 才支持
- 如果自定义属性里面有多个-链接的单词 获取时采用驼峰命名法
- dataset 是一个集合 里面存放了所有以data开头的自定义属性
<body>
<div getTime="20" data-index="'2" data-list-name="andy"></div>
<script>
var div = document.querySelector('div');
// 兼容性获取属性值的方法
div.getAttribute('getTime');
div.getAttribute('data-index');
div.getAttribute('data-list-name');
// H5新增的获取自定义属性值的方法 只能获取data-开头的自定义属性
div.dataset.index;
div.dataset['index'];
// 如果自定义属性里面有多个-链接的单词 获取时采用驼峰命名法
div.dataset.listName;
div.dataset['listName'];
</script>
</body>
四、节点操作
一般的,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
- 元素节点 nodeType 为 1 (主要操作)
- 属性节点 nodeType 为 2
- 文本节点 nodeType 为 3(文本节点包括文字、空行、换行等)
1、父级节点
node.parentNode
- parentNode 属性可返回某节点的父节点(最近的的一个父节点)
- 如果指定的节点没有父节点则返回null
<body>
<div class="demo">
<div class="box">
<span class="erweima">x</span>
</div>
</div>
<script>
// 1.父节点 parentNode
var erweima = document.querySelector('.erweima');
// 得到的是离元素最近的父级节点
console.log(erweima.parentNode);//返回为box
</script>
</body>
2、子节点
parentNode.childNodes(标准)
- 返回包含指定节点的子节点的集合(实时更新)
- 注意:返回值里面包含了所有的子节点,包括元素节点,文本节点等,如果只想要获得里面的元素节点,则需要专门处理。所以我们一般不提倡使用childNodes
parentNode.children(非标准) 重点掌握
- 它是一个只读属性 只返回所有的元素节点 其余节点不返回 实际开发常用
<body>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<script>
var ul = document.querySelector('ul');
var lis = ul.querySelectorAll('li');
// 1.子节点 childNodes 所有的子节点 包含元素节点 文本节点等等
console.log(ul.childNodes); // 集合有9个值
console.log(ul.chileNodes[0].nodeType); //3
console.log(ul.chileNodes[1].nodeType); //1
// 获得里面的元素节点
for(var i = 0; i<ul.childNodes.length; i++){
if(ul.childNodes[i].nodeType == 1) {
console.log(ul.childNodes[i]);
}
}
// 2.children 获取所有的子元素节点 实际开发常用
console.log(ul.children);
</script>
</body>
parentNodes.firstChild
- 返回第一个子元素节点 找不到返回null
- 包含所有的节点
parentNodes.lastChild
- 返回第一个子元素节点 找不到返回null
- 包含所有的节点
parentNodes.firstElementChild
- 返回第一个子元素节点 找不到返回null
- 存在兼容性问题 IE9以上才支持
parentNodes.lastElementChild
- 返回最后一个子元素节点 找不到返回null
- 存在兼容性问题 IE9以上才支持
实际开发的写法 既没有兼容性问题又返回相应的指定的子元素
parent.children[parent.children.length - 1]
<body>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
</ol>
<script>
var ol = document.querySelector('ol');
// 1.firstChild 第一个子节点 不管是文本节点还是元素节点
console.log(ol.firstChild); //#text
console.log(ol.lastChild); //#text
// 2.firstElementChild 返回第一个子元素节点
console.log(ol.firstElementChild); //<li>我是li1</li>
console.log(ol.lastElementChild); //<li>我是li4</li>
</script>
</body>
案例:下拉菜单
案例分析:
- 导航栏里面的li都要有鼠标经过效果 所以需要循环注册鼠标事件
- 核心原理:当鼠标经过li里面的第二个孩子ul显示 当鼠标离开 ul隐藏
<head>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
a {
color: #333;
text-decoration: none;
}
.nav {
margin: 100px;
}
.nav>li{
position: relative;
float: left;
width: 80px;
height: 41px;
text-align: center;
}
.nav li a {
display: block;
width: 100%;
height: 100%;
line-height: 41px;
}
.nav>li>a:hover {
background-color: #eee;
}
.nav ul {
display: none;
position: absolute;
top: 41px;
left: 0;
width: 100%;
border-left: 1px solid #fecc5b;
border-right: 1px solid #fecc5b;
}
.nav ul li {
border-bottom: 1px solid #fecc5b;
}
.nav ul li a:hover {
background-color: #fff5da;
}
</style>
</head>
<body>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li><a href="#">私信</a></li>
<li><a href="#">评论</a></li>
<li><a href="#">@我</a></li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li><a href="#">私信</a></li>
<li><a href="#">评论</a></li>
<li><a href="#">@我</a></li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li><a href="#">私信</a></li>
<li><a href="#">评论</a></li>
<li><a href="#">@我</a></li>
</ul>
</li>
</ul>
<script>
//获取元素
var nav = document.querySelector('.nav');
var lis = nav.children; //得到4个小li
//循环注册事件
for(var i = 0; i<lis.length; i++){
lis[i].onmouseover = function() {
this.children[1].style.display = 'block';
}
lis[i].onmouseout = function() {
this.children[1].style.display = 'none';
}
}
</script>
</body>
3、兄弟节点
node.nextSibling
- 返回当前元素的下一个兄弟节点 找不到返回null
- 包含所有的元素节点(文本节点 元素节点等)
node.previousSibling
- 返回当前元素的上一个兄弟节点 找不到返回null
- 包含所有的元素节点(文本节点 元素节点等)
node.nextElementSibling
- 返回当前元素的下一个兄弟元素节点 找不到返回null
- 存在兼容性问题 IE9以上才支持
node.previousElementSibling
- 返回当前元素的上一个兄弟元素节点 找不到返回null
- 存在兼容性问题 IE9以上才支持
<body>
<div>我是div</div>
<span>我是span</span>
<script>
var div = document.querySelector('div');
// 1.nextSibling 得到下一个兄弟节点 包含元素节点 文本节点等
console.log(div.nextSibling); //#text
// 2.previousSibling 得到上一个兄弟节点 包含元素节点 文本节点等
console.log(div.previousSibling); //#text
// 3.nextElementSibling 得到下一个兄弟元素节点
console.log(div.nextElementSibling); //<span>我是span</span>
// 4.previousElementSibling 得到上一个兄弟元素节点
console.log(div.previousElementSibling); //null
</script>
</body>
解决兼容性以及只获取元素节点的方法——封装一个兼容性函数
function getNextElementSibling(element) {
var el = element;
while(el = el.nextSibling) {
if(el.nodeType === 1) {
return el;
}
}
return null;
}
4、创建节点
document.createElement(‘tagName’);
- 动态创建元素节点
5、添加节点
node.appendChild(child);
- 将一个节点添加到指定父节点的子节点列表末尾 类似于css里面的after伪元素
node.insertBefore(child,指定元素)
- 将一个节点添加到指定父节点的指定节点前面 类似于css里面的before伪元素
<body>
<ul>
<li>123</li>
</ul>
<script>
// 1.创建节点元素节点
var li = document.createElement('li');
// 2.添加节点 node.appendChild(child) node 父级 child 子级 后面追加元素 类似于数组的push
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>
</body>
6、删除节点
node.removeChild(child)
- 从DOM中删除一个子节点 返回删除的节点
<body>
<button>删除</button>
<ul>
<li>光头强</li>
<li>熊大</li>
<li>熊二</li>
</ul>
<script>
// 1.获取元素
var btn = document.querySelector("button");
var ul = document.querySelector("ul");
// 2.注册事件 点击按钮依次删除里面的孩子
btn.onclick = function () {
if (ul.children.length == 0) {
this.disabled = true;
} else {
// 删除元素 node.children(child)
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
案例
简单版发布留言
- 核心思路:点击按钮之后,就动态创建一个li, 添加到ul里面
- 创建li的同时,把文本域里面的值通过li.innerHTML赋值给li
- 如果想要新的留言后面显示就用appendChild
- 如果想要新的留言前面显示就用insertBefore
删除留言
- 当我们把文本域里面的值赋值给li的时候,多添加一个删除的链接
- 需要把所有的链接获取过来,当我们点击当前的链接的时候,删除当前链接所在的li
- 阻止链接跳转需要添加JavaScript:void(0);或者 javascript:;
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
}
textarea {
width: 200px;
height: 100px;
border: 1px solid pink;
outline: none;
resize: none;
}
ul {
margin-top: 50px;
}
li {
width: 300px;
padding: 5px;
background-color: pink;
color: red;
font-size: 14px;
margin: 15px 0;
}
li a {
float: right;
}
</style>
</head>
<body>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul></ul>
<script>
//1.获取元素
var text = document.querySelector("textarea");
var ul = document.querySelector("ul");
var btn = document.querySelector("button");
// 2.注册事件
btn.onclick = function () {
if (text.value == "") {
alert("请输入内容");
return false;
} else {
// (1)创建元素
var li = document.createElement("li");
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
// (2)添加元素
// ul.appendChild(li); 在后面添加
ul.insertBefore(li, ul.children[0]); //在前面添加
// (3)删除元素 删除的是当前链接的li 它的父亲
var as = document.querySelectorAll("a");
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>
7、复制节点(克隆节点)
node.cloneNode()
- 返回调用该方法的节点的一个副本
- 如果括号参数为空或者为false,则是浅拷贝 即只复制标签,不复制里面的内容
- 如果括号参数为true,则是深拷贝 复制标签和里面的内容
<body>
<ul>
<li>111</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
// 复制节点 node.cloneNode()
var lili = ul.children[0].cloneNode(true);
ul.appendChild(lili);
</script>
</body>
8、三种动态创建元素的区别
- document.write()
- element.innerHTML
- document.createElement()
区别:
- document.write 是直接将内容写到页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
- innerHTML 是将内容写到某个DOM节点,不会导致页面全部重绘
- innerHTML创建多个元素效率更高(采用数组形式拼接,不要采用字符串拼接),但是结构稍微复杂
- createElement()创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下,innerHTML采取数值形式拼接时,效率要比createElement高
五、事件操作
1、注册事件(绑定事件):给元素添加事件
(1)传统注册方式
- 利用on开头的事件onclick
- <button onclick = "alert(hi~)" ></button>
- btn.onclick = function() {}
特点:
注册事件的唯一性。同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。
(2)方法监听注册方式
- w3c标准 推荐方式
- addEventListener() 它是一个方法
- IE9之前的IE 不支持此方法 可使用 attachEvent()代替
特点:
同一个元素同一个事件可以注册多个监听器,会按照注册顺序依次执行
eventTarget.addEventListener(type,listener[, useCapture])
eventTarget.addEventListener()方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
该方法接收三个参数:
- type:事件类型字符串,比如click、mouseover,注意这里不要带on
- listener:事件处理函数,事件发生时,会调用该监听函数
- useCapture:可选参数,是一个布尔值,默认是false
<body>
<button>传统方式注册事件</button>
<button>事件侦听注册事件</button>
<script>
var btns = document.querySelectorAll("button");
// 1.传统方式注册事件
btns[0].onclick = function () {
alert("hi~");
};
// 2.事件侦听注册事件 addEventListener
// (1)里面的时间类型是字符串 必定加引号 而且不带on
// (2)同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener("click", function () {
alert("hello1111");
});
btns[1].addEventListener("click", function () {
alert("hello2222");
});
</script>
</body>
注册事件兼容性解决方案
<script>
function addEventListener(element, eventName, fn) {
// 判断当前浏览器是否支持addEventListener方法
if (element.addEventListener) {
element.addEventListener(eventName, fn); //第三个参数 默认是false
} else if (element.attachEvent) {
element.attachEvent("on" + eventName, fn);
} else {
// 相当于 element.onclick = fn
element["on" + eventName] = fn;
}
}
</script>
兼容性处理的原则:首先照顾大多数浏览器,再处理特殊浏览器
2.删除事件
(1)传统删除方式
eventTarget.onclick = null;
(2)方法监听删除方式
eventTarget.removeEventListener(type, listener[, useCapture]);
eventTarget.detachEvent(eventNameWithOn, callback);
删除事件兼容性解决方案
function removeEventListener(element, eventName, fn) {
// 判断当前浏览器是否支持removeEventListener方法
if (element.removeEventListener) {
element.removeEventListener(eventName, fn); //第三个参数 默认是false
} else if (element.detachEvent) {
element.detachEvent("on" + eventName, fn);
} else {
element["on" + eventName] = null;
}
}
六、DOM事件流
事件流:描述的是从页面中接收事件的顺序。
DOM事件流:事件发生时会给元素节点之间按照特定是顺序传播 这个传播过程即DOM事件流
三个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
注意:
- JS代码中只能执行捕获或者冒泡其中的一个阶段
- onclick 和 attachEvent 只能得到冒泡阶段
- addEventListener(type, listener[, useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认false),表示在事件冒泡阶段调用事件处理程序
- 实际开发中我们很少使用事件捕获,更关注事件冒泡
- 有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave
事件对象
官方解释:event对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。
简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象,它有很多属性和方法。
使用语法:
这个event是形参,系统帮我们设定为事件对象,不需要传递实参过去
当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)
eventTarget.onclick = function(event){}
eventTarget.addEventListener('click', function(event){})
//这个event就是事件对象 还喜欢写成evt e
比如:
- 谁绑定了这个事件。
- 鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置
- 键盘触发事件的话,会得到键盘的相关信息,如按下哪个键
兼容性问题:
在IE678中 浏览器不会给方法传递参数 如果需要的话 需要到window.event中获取查找
解决:e = e || window.event;
<script>
var div = document.querySelector('div');
// div.onclick = function(e){
// e = e || window.event;
// console.log(e);
// }
div.addEventListener('click',function(e){
console.log(e);
})
</script>
事件对象的常见属性和方法
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 标准 |
e.srcElement | 返回触发事件的对象 非标准 ie6-8使用 |
e.type | 返回事件的类型 比如 click mouseover 不带on |
e.cancelBubble | 阻止冒泡 非标准 ie6-8使用 |
e.returnValue | 阻止默认事件(默认行为)非标准 ie6-8使用 比如不让链接跳转 |
e.preventDefault() | 阻止默认事件(默认行为)标准 比如不让链接跳转 |
e.stopPropagation() | 阻止冒泡 标准 |
1、e.target 与 this 的区别
e.target 返回的是触发事件的对象(元素)
this返回的是绑定事件的对象(元素)
<body>
<ul>
<li>123</li>
<li>123</li>
<li>123</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click',function(e){
//我们给ul绑定了事件 那么this 就指向ul
console.log(this); //<ul>...</ul>
//e.target指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target指向的就是li
console.log(e.target);//<li>...</li>
})
</script>
</body>
2、返回事件类型
<body>
<div>哈哈哈</div>
<script>
// 返回事件类型
var div = document.querySelector('div');
div.addEventListener('click',fn);
div.addEventListener('mouseover',fn);
div.addEventListener('mouseout',fn);
function fn(e){
console.log(e.type); //根据触发情况返回click mouseover mouseout
}
</script>
</body>
3、阻止默认行为(事件) 让链接不跳转
e.preventDefault()
e.returnValue
<body>
<a href="baidu.com">百度</a>
<script>
// 阻止默认行为(事件) 让链接不跳转 或者提交按钮不提交
var a = document.querySelector('a');
a.addEventListener('click', function(e){
e.preventDefault();
})
// 传统的注册方式
a.onclick = function(e){
// 普通浏览器 e.preventDefault(); 方法
e.preventDefault();
// 低版本浏览器IE678 returnValue 属性
e.returnValue;
// return false也能阻止默认行为 没有兼容性问题 特点 return后面的代码不执行了而且只限于传统的注册方式
return false;
}
</script>
</body>
4、阻止事件冒泡的两种方式
e.stopPropagation()
e.cancelBubble
<body>
<div class="father">
<div class="son">son儿子</div>
</div>
<script>
// 阻止冒泡 dom标准 stopPropagation()
var son = document.querySelector('.son');
son.addEventListener('click',function(e){
alert('son');
if(e && e.stopPropagation){
e.stopPropagation();
}else{
window.event.cancelBubble = true;
}
},false);
var father = document.querySelector('.father');
father.addEventListener('click',function(){
alert('father');
},false);
</script>
</body>
5、事件委托(代理、委派)
原理
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
作用:只操作了一次DOM,提高了程序的性能
<body>
<ul>
<li>zhi</li>
<li>我是2</li>
<li>我是3</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click',function(e){
// alert("我弹出来啦");
// e.target这个可以得到我们点击的对象
e.target.style.backgroundColor = 'pink';
})
</script>
</body>
6、常用鼠标事件
(1)禁止鼠标右键菜单 contextmenu
(2)禁止鼠标选中文字(selectstart 开始选中)
<body>
我是一段不愿意分享的文字
<script>
// 1.contextmenu 禁用右键菜单
document.addEventListener('contextmenu',function(e){
e.preventDefault();
})
// 2.禁止选中文字 selectstart
document.addEventListener('selectstart',function(e){
e.preventDefault();
})
</script>
</body>
(3)鼠标事件MouseEvent
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标 IE9+支持 |
e.pageY | 返回鼠标相对于文档页面的Y坐标 IE9+支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
<script>
document.addEventListener('click',function(e){
console.log(e.pageX);
console.log(e.pageY);
})
</script>
(4)键盘事件KeyboardEvent
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被松开时触发 但它不识别功能键(ctrl、shift等) |
- 如果使用addEventListener不需要加on
- 三个事件的执行顺序是:keydown--keypress--keyup
键盘事件对象属性——keyCode 返回该键的ASCII值
- onkeydown 和 onkeyup不区分字母大小写,onkeypress区分字母大小写
- 在实际开发中,我们更多的使用keydown和keyup,它能识别所有的键(包括功能键)
- keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
<script>
// keyup 按键被松开时触发(两种写法都可以) 不区分字母大小写 a和A都是65
// document.onkeyup = function(){
// console.log('我弹起来了');
// }
document.addEventListener("keyup", function (e) {
console.log("up:" + e.keyCode);
// 我们可以利用keyCode返回的ASCII码值来判断用户按下了哪个键
if (e.keyCode === 65) {
alert("你按下的是a键");
} else {
alert("你按下的不是a键");
}
});
// keydown 按键被按下时触发 识别功能键 不区分字母大小写 a和A都是65
document.addEventListener("keydown", function (e) {
console.log("down:" + e.keyCode);
});
// keypress 按键被按下时触发 不识别功能键 区分字母大小写 a是97 A是65
document.addEventListener("keypress", function (e) {
console.log("press:" + e.keyCode);
});
</script>