JavaScript事件
- 特效是由事件触发的
- 事件源:任何一个html元素(节点)都是一个事件源
- 一个事件源可以添加多个事件
- 键盘事件:keypress键盘事件,keyup抬起,keydown按下 文档:load加载 表单:focus获得焦点,blur失去焦点,submit提交事件,change改变事件 其他:scroll滚动事件,select start选择事件
2. 事件中的Event对象
- 只要事件发生就会产生一个event事件
- 事件发生后创建对象
- Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
- 事件通常与函数结合使用,函数不会在事件发生前被执行
2.1. event事件对象常见的属性和方法
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 标准 |
e.srcElement | 返回触发事件的对象 非标准ie6-8使用 |
e.type | 返回事件的类型,比如:click,mouseover 不带on |
e.returnValue | 该属性阻止默认事件(默认行为) ie6-8,比如不让链接跳转 |
e.preventDefault() | 该属性阻止默认事件(默认行为)标准,比如不让链接跳转 |
e.stopPropagation() | 阻止冒泡 【标准】 |
e.cancelBubble | 阻止冒泡【ie】 |
2.2. 阻止默认事件的发生
补充一个知识点:点击a标签的时候,想要将默认的跳转去除掉,添加自己的跳转方式 对于a标签来说,默认的行为就是进行页面跳转,如果不想让a标签进行跳转,可以在注册事件中使用return false
<a id="link" href="http://www.baidu.com">这是a</a>
<script>
var link = document.getElementById("link");
link.onclick = function() {
alert("嘻嘻");
return false; //阻止页面跳转
}
</script>
2.3. 阻止默认事件的发生
对于一些标签来说,他们拥有自己的事件,比如:a标签可以跳转,submit/button可以提交表单,reset可以重置按钮,那么如果想要给这些按钮添加事件,并且不让他执行对应的默认事件的话,就需要使用自制时间发生; 阻止默认事件的方法有两种:使用的是事件对象的方法来阻止event.stopPropagation();
- 如果是使用 on+事件名 或者 attachEvent() 添加的事件 使用 return false;
- 如果是使用 addEventListener 添加的事件 使用 event.preventDefault();
<a id="link" href="http://www.baidu.com">这是a</a>
<script>
var link = document.getElementById("link");
// 阻止方法一
link.onclick = function() {
alert("嘻嘻");
// 取消默认事件
return false;
}
// 阻止方法二
link.addEventListener('click',function(event){
var ev = event || window.event;
alert('我在京东');
// 取消默认事件
ev.preventDefault();
});
</script>
将两种方法进行封装
// 封装 - 取消默认事件
function preventDef(event){
var ev = event || window.event;
if(ev.preventDefault){
ev.preventDefault();
}else{
ev.returnValue = false;
}
}
2.4. 事件流-事件冒泡机制
参考文档:https://blog.csdn.net/qq_51066068/article/details/124249346
气泡从水底开始往上升,由深到浅,升到最上面。在上升的过程中,气泡会经过不同深度层次的水。 相对应地:这个气泡就相当于我们这里的事件,而水则相当于我们的整个dom树; 事件从dom 树的底层,层层往上传递,直至传递到dom的根节点。 当子元素与父元素有相同的事件时,当子元素被触发时父元素也会被触发冒泡机制
在不同浏览器中,冒泡的程度不同
IE 6.0: div -> body -> html -> document
其他浏览器: div -> body -> html -> document -> window
注意:并不是所有的事件都能冒泡,以下事件不冒泡:blur、focus、load、unload
阻止冒泡的方法
标准浏览器 和 ie浏览器
w3c:event.stopPropagation()
IE:event.cancelBubble = true
兼容写法
if(event && event.stopPropagation){ // w3c标准
event.stopPropagation();
}else{ // IE系列 IE 678
event.cancelBubble = true;
}
<style>
#father{
width: 300px;
height: 300px;
background-color: #f00;
margin: auto;
}
</style>
</head>
<body>
<div id="father">
<button id="btn">点击</button>
</div>
<script>
window.onload = function(){
var father = document.getElementById('father');
var btn = document.getElementById('btn');
father.onclick = function(){
if(event&&event.stopPropagation){ // w3c标准,阻止冒泡事件
event.stopPropagation();
}else{ // IE系列 ie678
event.cancelBubble = true;
}
alert('father点击');
}
btn.onclick = function(){
if(event&&event.stopPropagation){ // w3c标准,阻止冒泡事件
event.stopPropagation();
}else{ // IE系列 ie678
event.cancelBubble = true;
}
alert('btn点击');
}
document.onclick = function(){
alert('文档点击');
}
}
</script>
谁需要组织冒泡,就在对应的操作前,添加阻止冒泡事件
面试题-Javascript的事件流模型都有什么? “事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播 “事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的 “DOM事件流”:三个阶段:事件捕获,成为目标阶段,事件冒泡
使用addEventListener实现事件冒泡
默认冒泡顺序是从内往外进行冒泡
<style>
.body{
width: 100%;
height: 100%;
background-color: #f00;
}
.warp{
width: 300px;
height: 300px;
background-color: #0f0;
}
.inner{
width: 100px;
height: 100px;
background-color: #00f;
}
</style>
<body>
<div class="warp">
<div class="inner"></div>
</div>
</body>
<script>
var inner = document.querySelector('.inner');
var warp = document.querySelector('.warp');
// 给按钮添加点击事件
inner.addEventListener('click',fun2);
function fun2(){
console.log('inner被点击');
}
warp.addEventListener('click',fun1);
function fun1(){
console.log('warp被点击');
}
document.body.addEventListener('click',fun3);
function fun3(){
console.log('body被点击');
}
</script>
可以通过给addEventListener添加第三个参数值,更改冒泡的顺序
useCapture=true 默认值, false. true 代表以事件捕获形式触发事件, false 代表以事件冒泡形式触发事件
<style>
.body{
width: 100%;
height: 100%;
background-color: #f00;
}
.warp{
width: 300px;
height: 300px;
background-color: #0f0;
}
.inner{
width: 100px;
height: 100px;
background-color: #00f;
}
</style>
<body>
<div class="warp">
<div class="inner"></div>
</div>
</body>
<script>
var inner = document.querySelector('.inner');
var warp = document.querySelector('.warp');
// 给按钮添加点击事件
inner.addEventListener('click',fun2,useCapture=true);
function fun2(){
console.log('inner被点击');
}
warp.addEventListener('click',fun1,useCapture=true);
function fun1(){
console.log('warp被点击');
}
document.body.addEventListener('click',fun3,useCapture=true);
function fun3(){
console.log('body被点击');
}
</script>
2.5. 事件委托【在dom对象后面讲】
需求:只做一个鲜花网手机端购物车效果 点击能够添加一个商品,在商品上点击删除能够删除这个商品
<button>点击添加商品</button>
<div class="show">
<p>暂时没有商品</p>
<ul>
<li data-index="11">老的商品1</li>
<li data-index="12">老的商品2</li>
<li data-index="13">老的商品3</li>
</ul>
</div>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}
li{
height: 80px;
border: 1px solid #f00;
margin: 10px;
}
</style>
<script>
var op = document.querySelector('.show p');
var oLi = document.querySelectorAll('ul li');
var oUi = document.querySelectorAll('ul');
if(oUl.length==0){
op.style.display = 'block';
}else{
op.style.display = 'none';
}
// 给商品添加删除功能
for(var i=0;i<oLi.length;i++){
oLi[i].onclick = function(){
// console.log(this); 获取元素本身
// console.log(this.dataset); 获取元素下面自定义的data属性
console.log(this.dataset.index); // 获取index参数值
}
}
// 点击按钮添加商品
var n = 20;
oBtn.onclick = function(){
n++;
// 第一种添加方案
// oUl.innerHTML += `<li data-index=${n}>新的商品</li>`;
// 第二种添加方案
var li = document.createElement('li');
li.setAttribute('data-index',n);
li.innerHTML = '新商品';
oUl.appendChild(li);
}
// 给商品添加删除功能
// 不实用事件委托:新添加的列表没有绑定事件
for(var i=0;i<oLi.length;i++){
oLi[i].onclick = function(){
// console.log(this); 获取元素本身
// console.log(this.dataset); 获取元素下面自定义的data属性
console.log(this.dataset.index); // 获取index参数值
}
}
// 使用事件委托
oUl.onclick = function(e){
// e.currentTarget 当前绑定事件的元素
console.log(e.currentTarget);
// e.target:触发事件的目标元素,不一定是当前元素,也有可能是当前元素的后代元素
// 因为后代元素触发的事件也会冒泡从而触发当前元素的事件
console.log(e.target);
// 判断是否是li标签
if(e.target.tagName == 'LI'){
console.log(e.target.parentNode.dataset.index);
}
}
</script>
事件委托的优点:
1.减少事件注册,节省内存
2.在table上代理所有td的click事件
3.在ul上代理所有li的click事件
4.简化了dom节点更新时,相应事件的更新。
5.不用在新添加的li上绑定click事件
6.当删除某个li时,不用移解绑元素上的click事件【引出堆栈,内存泄漏,垃圾回收机制】
事件委托的缺点:
1.事件委托基于冒泡,对于不冒泡的事件不支持
2.层级过多,冒泡过程中,可能会被某层阻止掉
3.理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在table上代理td,而不是在document上代理td。
4.把所有事件都用代理就可能会出现事件误判。比如,在document中代理了所有button的click事件,另外的人在引用改js时,可能不知道,造成单击button触发了两个click事件。
2.6. 事件封装
// 绑定事件 - 判断是否是ie浏览器
// obj-某个对象 EType - 某个事件 fun - fun函数
function addEvent(obj, EType, fun) {
if (obj.addEventListener) {
obj.addEventListener(EType, fun);
} else if (obj.attachEvent) {
obj.attachEvent("on" + EType, fun);
} else {
obj["on" + EType] = fun;
}
}
// 移除元素事件
function removeEvent(obj, EType, fun) {
if (obj.removeEventListener) {
obj.removeEventListener(EType, fun);
} else if (obj.detachEvent) {
obj.detachEvent("on" + EType, fun);
} else {
obj["on" + EType] = null;
}
}
// 取消默认行为
function preventDefaultFun(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
// 阻止事件传播
function stopPropagationFun(event) {
if (event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
}
2.7 e.target和this的区别
区别: e.target返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素) e.currentTarget 当前绑定事件的元素
<div class="box">box盒子</div>
<ul class="list">
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
<li>列表4</li>
</ul>
<script>
var oBox = document.getElementsByClassName('box')[0];
var oList = document.getElementsByClassName('list')[0];
oBox.onclick = function(e){
console.log(this); // div
console.log(e.target); // div
}
oList.onclick = function(e){
// e.target指向的是被点击的对象,谁触发了这个事件,就是谁,li能够拥有点击事件,是因为事件冒泡
console.log(this); // ul
console.log(e.target); // li
}
</script>
3. JS触发事件的方式有哪些
方法一:在js获取元素/标签
元素.事件名称 = 匿名函数 / function(){}
var oBox = document.querySelector('.box');
oBox.onclick = function(){
console.log(oBox);
}
方法二: 元素.事件名称 = 函数名称
var oBox = document.querySelector('.box');
oBox.onclick = changeColor;
function changeColor(){
oBox.style.backgroundColor = 'red';
}
方法三: 在html中触发
onclick = "代码段 / 函数调用" 如果是函数的调用,可以传递一个参数,this(表示的是当前的标签)
<div class="box" onclick="changeColor(this,'green')"></div>
<script>
function changeColor(getThis,color1){
console.log(getThis);
getThis.style.backgroundColor = color1;
}
</script>
4.鼠标事件
事件 | 说明 |
---|---|
onclick | 鼠标点击某个对象 |
ondblclick | 鼠标双击某个对象 |
onmouseover | 鼠标被移到某元素之上 |
onmouseout | 鼠标从某元素移开 |
onmousemove | 鼠标被移动 |
onmousedown | 某个鼠标按键被按下 |
onmouseup | 某个鼠标按键被松开 |
oncontextmenu | 右键事件 |
onmousewheel | 当滚轮被滚动的时候 |
<!-- 给一个元素添加多个点击事件 -->
<style>
.box{
width: 300px;
height: 300px;
border: 1px solid #f00;
}
</style>
<div class="box"></div>
<script>
var oBox = document.querySelector('.box');
// 单击
oBox.onclick = function(){
console.log(this);
this.style.backgroundColor='red';
}
// 鼠标悬浮
oBox.onmouseover = function(){
this.style.backgroundColor='blue';
}
// 鼠标离开
oBox.onmouseout = function(){
this.style.backgroundColor='green';
}
// 双击
oBox.ondblclick = function(){
this.style.backgroundColor='pink';
}
var x = 0;
// 鼠标移动
oBox.onmousemove = function(){
console.log(x++);
// this.style.backgroundColor='orange';
}
</script>
onmouseenter 和 onmouseover的区别
1、onmouseover、onmouseout:鼠标经过时自身触发事件,经过其子元素时也触发该事件; 支持冒泡
2、onmouseenter、onmouseleave:鼠标经过时自身触发事件,经过其子元素时不触发该事件。不支持冒泡
5. 键盘事件
导语:页面中有时候想要提交表单数据,直接按下enter就可以提交了;或者在玩游戏的时候可以通过WASD这四个按键来控制上下左右的方向,这就是通过键盘事件来操作的
****事件 | ****说明 |
---|---|
onkeypress[使用的比较少] | 键盘的某个键被按下 |
onkeydown | 键盘的某个键被按下或按住 |
onkeyup | 键盘的某个键被松开 |
一个onkeydown+onkeyup = 鼠标单击事件,想要区分键盘上的每个按键,是通过键盘的keyCode值来判断的,所以想要知道按下的是哪个按键,可以使用event.keyCode
onkeydown 只要是按下的状态,就会一直触发当前事件
onkeyup 只有弹起的那一瞬间,才会触发
案例:通过上下左右四个键,控制div移动
<div class="box" style=" margin-left: 0px;margin-top: 0px;"></div>
<script>
var oBox = document.querySelector('.box');
document.onkeyup = function(){
if(event.keyCode==39){
oBox.style.marginLeft = parseFloat(oBox.style.marginLeft)+5 + 'px';
console.log(parseFloat(oBox.style.marginLeft)+5);
}else if(event.keyCode==37){
oBox.style.marginLeft = parseFloat(oBox.style.marginLeft)-5 + 'px';
}else if(event.keyCode==83){
oBox.style.marginTop = parseFloat(oBox.style.marginTop)+5 + 'px';
}
}
</script>
注意:js中的.style添加的是行内样式,获取的也是行内样式 默认清空下标签没有margin-left值的话,获取之后转为float类型的时候,会变成NaN,所以:记得给标签添加默认的行内css样式
当然最好的方法还是通过left,top这些值来改变元素的位置,这样代码会更简单
6. 光标事件
事件 | 说明 |
---|---|
onfocus | 元素获得焦点 |
onblur | 元素失去焦点 |
// 获取焦点,让value消失;失去焦点,显示提示信息
<input type="radio" name="" id="inp" value="请输入用户名">
<script>
var oInp = document.getElementById('inp');
oInp.onfocus = function(){
oInp.value = '';
}
oInp.onblur = function(){
oInp.value = '请输入用户名';
}
</script>
案例:模拟小米官网搜索框效果
需求:input获取焦点显示下拉菜单信息,失去焦点,隐藏信息
<style>
ul{
display: none;
}
</style>
<input type="radio" name="" id="inp" placeholder="小米">
<ul>
<li>全部商品</li>
<li>小米</li>
<li>红米</li>
<li>电脑</li>
<li>平板</li>
<li>笔记本</li>
</ul>
<script>
// 小米官网 input效果
// 给inp添加获取焦点的事件
// 显示ul
// 给inp添加失去焦点的事件
// 隐藏ul
var oInp = document.getElementById('inp');
var oUl = document.querySelector('ul');
oInp.onfocus = function(){
oUl.style.display = "block";
}
oInp.onblur = function(){
oUl.style.display = 'none';
}
</script>
7. 窗口事件
事件 | 说明 |
---|---|
onresize | 览器窗口被调整大小时发生 |
8. 表单事件
导语:onsubmit,onreset相对来说用的比较少 onchange:onselect 属性可用于以下元素内:以及 在百度文库中,当我们选中文本的内容的时候,会显示 搜索/复制/发送到手机/翻译 等内容,这时候就可以使用onselect
事件 | 说明 |
---|---|
onsubmit | 提交按钮被点击 |
onreset | 重置按钮被点击 |
onselect | 文本内容被选定 |
onchange | 用户改变表单元素的内容 |
oninput | 在用户输入时触发 |
<form id='form1' action="a.php" onsubmit="alert('hello '+uname.value)" onreset="alert('world')">
用户名:<input type="text" name="uname" id=""><br/>
密码:<input type="password" name="pwd" id=""><br/>
<textarea name="" id="" cols="30" rows="10">
我的名字叫张三
</textarea>
<input type="submit" name="" id="">
<input type="reset" name="" id="">
</form>
文本被选中
// 给多行文版框添加 选择的功能
var text = document.querySelector('textarea');
text.onselect = function(){
console.log('123456789');
}
onchange 内容发生改变
// 只用多行文本发生会触发
text.onchange = function(){
console.log('页面内容发生改变');
}
// 表单中的任意一个内容发生改变,都会触发onchange
var form1 = document.getElementById('form1');
form1.onchange = function(){
console.log('change');
}
注意:onselect 属性可用于以下元素内:< input type="file" >、< input type="password">、< input type="text">、< keygen> 以及 < textarea>.
注意2:oninput事件类似于 onchange 事件。不同之处在于 oninput 事件在元素值发生变化是立即触发, onchange 在元素失去焦点时触发。另外一点不同是 onchange 事件也可以作用于 <keygen> 和 <select> 元素。
9. 单选框和复选框被选中
复选框是否被选中需要判断复选框中的checked的值 true:选中 false:没选中
基础案例
<input type="checkbox" id='inp'/>
<script>
var oInp = document.querySelector('#inp');
oInp.onclick = function(){
console.log(this.checked);
}
</script>
案例:购物车案例-将选中的商品价格进行计算
<table border='1' width="500">
<tr>
<td>选择</td>
<td>商品名称</td>
<td>商品价格</td>
</tr>
<tr>
<td>
<input type="checkbox" class="sel"/>
</td>
<td>上衣</td>
<td class="price">100</td>
</tr>
<tr>
<td><input type="checkbox" class="sel"/></td>
<td>裤子</td>
<td class="price">200</td>
</tr>
<tr>
<td><input type="checkbox" class="sel"/></td>
<td>包包</td>
<td class="price">300</td>
</tr>
<tr>
<td>全选:<input type="checkbox"/></td>
<td colspan="2" id='totlePrice'>总价:0</td>
</tr>
</table>
<script>
// 1. 单选 - 给复选框添加一个事件
// 2. 判断复选框的状态
// 3. checked=true计算 / 否则不用计算
// 4. 0-checked-price 1-checked-price 2-checked-price
var oSel = document.querySelectorAll('.sel');
var oPrice = document.querySelectorAll('.price');
var totlePrice = document.querySelector('#totlePrice');
var sum = 0;
for(var i=0;i<oSel.length;i++){
oSel[i].index = i;
oSel[i].onclick = function(){
if(this.checked){
// 计算总价
sum += parseFloat(oPrice[this.index].innerHTML);
}else{
sum -= parseFloat(oPrice[this.index].innerHTML);
}
totlePrice.innerHTML = "总价:"+sum;
}
}
</script>
10. 加载事件
导语:正常情况下,js代码是可以写在head标签中,也可以写在/body结束的后面;但是当我们把js代码写在head中,并且js代码中有获取页面html标签的操作的时候,这时候的js代码就会报错
表示没有 “无法读取null属性(读取'innerHTML')”,也就是没有获取到对象,这时候可以在所有js的代码外面天际onload的;表示,html页面内容加载完毕之后,在执行js代码
****事件 | ****说明 |
---|---|
onload | 页面或图像加载完成 |
onbeforeunload | 页面卸载前执行 |
<script>
// 页面加载完之后再执行js
window.onload = function(){
var oBox = document.getElementById('box');
console.log(oBox.innerHTML);
}
</script>
<div id='box'>hello world</div>
// 如果页面中有滚动事件,滚动之后,想要重新刷新页面的时候,滚动条在最上面,可以使用这个方式
window.onbeforeunload = function () {
window.scrollTo(0, 0);
}
11. 滚动事件
****事件 | ****说明 |
---|---|
onscroll | 窗口发生滚动 |
scrollTo | 滚动到指定位置【增加】 |
方法一: window.scrollTo(x-coord,y-coord)
x-coord 是文档中的横轴坐标。
y-coord 是文档中的纵轴坐标。
比如: window.scrollTo(x-coord,y-coord)
x-coord 是文档中的横轴坐标。
y-coord 是文档中的纵轴坐标。
比如:window.scrollTo(0,1000); // 垂直滚动到1000的位置
方法二: window.scrollTo(options) // option为对象格式 window.scrollTo(options) // option为对象格式
- top 等同于 y-coord
- left 等同于 x-coord
- behavior 类型String,表示滚动行为,支持参数 smooth(平滑滚动),instant(瞬间滚动),默认值auto,实测效果等同于instant
基础案例1:只要页面发生滚动,就触发滚动事件
<style>
body{
height: 10000px;
}
</style>
<script>
var i=1;
window.onscroll = function(){
console.log(i++);
}
</script>
- 文档可视区域高度(屏幕的高度) document.documentElement.clientHeight
- 文档高度(整个html页面的高度) document.documentElement.scrollHeight
- 文档滚动高度(标准浏览器生效) document.documentElement.scrollTop
- 文档滚动高度(IE浏览器有效) document.body.scrollTop
- 获得当前坐标的X,Y坐标 x=event.clientX; Y=event.clientY
- 获取当前元素的宽度和高度,定位的left和top/元素上面内容的高度
height=ele.offsetHeight;
width=ele.offsetWidth
left = ele.offsetLeft
top = ele.offsetTop
常用的尺寸获取方式:
获取页面滚动上去的高度:document.documentElement.scrollTop/document.body.scrollTop
获取当前元素的宽度和高度:ele.offsetHeight/ele.offsetWidth
获取窗口的宽度和高度:window.innerHeight
获取文档的宽度和高度:document.documentElement.scrollHeight
12. js中两种添加事件的方式
- 方式一 :on+事件名
- 方法二:添加事件监听
1.方式一 :on+事件名
// 添加事件关联
oneDiv.onclick = function() {
console.log("+++++");
}
oneDiv.onclick = function() {
console.log("-----");
}
// 取消事件关联
oneDiv.onclick = null;
oneDiv.onclick = false;
2.方法二:添加事件监听【推荐使用】
语法1:element.addEventListener(event, function, useCapture)
Event: 必须。字符串,指定事件名。
注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。
Function: 必须。指定要事件触发时执行的函数。
useCapture: 可选。布尔值,(默认值, false. true 代表以事件捕获形式触发事件, false 代表以事件冒泡形式触发事件)
// 添加事件关联
function fun1() {
console.log("++++++");
}
function fun2() {
console.log("-----");
}
oneDiv.addEventListener("click", fun1);
oneDiv.addEventListener("click", fun2);
oneDiv.addEventListener("click", function() {
console.log('你好');
});
// 取消事件关联
oneDiv.removeEventListener("click", fun1);
3.addEventListener的兼容性
// 其他浏览器
oneDiv.addEventListener("click", fun1);
oneDiv.removeEventListener("click", fun1);
// IE 低版本浏览器
Ie浏览器中的on关键词不能少
oneDiv.attachEvent("onclick", fun1);
oneDiv.detachEvent("onclick", fun1);
- 对比onclick和addEventListener
1.addEventListener可以对同一个元素绑定多个事件【相同事件】,执行顺序从上到下依次执行。而onclick同一个元素只能绑定一个【相同】事件,如有多个,后面的事件会覆盖前面的事件。
2.addEventListener的第三个参数为布尔类型,默认为false,也就是执行的冒泡机制,如为true,则执行捕获机制
3.addEventListener它对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。点击查看dom分类
4.注册addEventListener事件时不需要写on,而onclick方式则必须加on
5.在移除事件上,onclick使用的是指针指向null,例如document.onclick = null,而addEventListener则使用的是独有的移除方法removeListener(要使用此方法,addEventListener必须执行的是外部函数或存在函数名,不然则不能使用) 6.addEventListener为DOM2级事件绑定,onclick为DOM0级事件绑定
7.IE678只能使用attachEvent,无addEventListener
总结:对于简单事件(同一个元素上只有一个事件)使用行内的onclick更合适。对于复杂事件使用 addeventlistenr 最后可以删除事件。 推荐使用addeventlistenr ,他是现在浏览器的标准,浏览器的兼容性会更好一些
13. DOM CSS动态样式
用js对页面中的元素执行获取css样式 或者 添加对应的css样式的操作,js中获取css样式的方法比较多(obj.style,getComputedStyle,currentStyle),但是设置样式,只能使用obj.style的方式
- obj.style 【获取行内样式】 注意:可以获取样式,也可以设置样式
动态样式
- 动态样式指通过脚本动态控制元素的样式,实现页面显示格式的动态变化。比如:动态滚动的文本、动态移动的图片、可折叠的树形菜单等。
使用style对象访问样式
- 每个HTML标记均具有style属性,相应的,JavaScript脚本中的HTML元素对象都具有style属性,该属性是一个style对象。
- Style对象的属性与CSS样式中的属性一一对应。
元素对象.className="类名"
- 因为属性名class在JS中为关键字,所在此处写做className
var box = document.getElementById("box");
box.style.color="#ff0000";
box.style.width="400px";
box.style.height="300px";
box.style.backgroundColor="#ff0000";
box.style.border="1px solid #f00";
- getComputedStyle 【非IE浏览器下,获取内部样式,或者外部样式】 注意:只能获取不能设置
基本语法: window.getComputedStyle(元素).样式属性
- currentStyle 【IE浏览器下获取内部样式,或者外部样式】
基本语法: 元素.currentStyle.样式属性
- js获取css样式,兼容性写法 一般情况下我们在使用的时候,我们不知道用户使用的是什么浏览器,所以需要对获取元素的方式做浏览器的判断
// 兼容写法
/**
*
* @param obj 获取哪个元素的样式【属性】
* @param attr 样式的名称【属性】
* @returns 返回样式的值【属性值】
*/
function getCss(obj,attr){
if(obj.currentStyle){
return obj.currentStyle[attr];
}else{
return window.getComputedStyle(obj)[attr];
}
}
14. event对象使用技巧
- e.target 获取元素本身 我们可以使用e.target获取元素本身
- e.target.dataset 获取data-绑定的属性
- e.currentTarget 当前绑定事件的元素
15.移动端事件
PC端事件: 鼠标类:click,mouseover,mouseout,mouseleave,mouseenter,mouseup,mousedown 键盘类:keydown,keyup 其他类:blur,focus,change,load 但是对于移动端来说,是不存在鼠标事件和键盘事件的,因为移动端是没有鼠标和键盘的;
移动端事件: 单击事件,双击事件,滑动事件(上滑,下滑,左滑,右滑) 长按事件
摇一摇,重力感应等
案例:鼠标悬浮效果
<style>
.box{
width: 100px;
height: 100px;
background-color: red;
}
.box:hover{
background-color: blue;
}
</style>
<div class="box"></div>
<script>
let box = document.querySelector('.box');
let i=0;
box.onclick = function(){
console.log(++i);
}
</script>
这个效果在PC端是没有问题的,但是在移动端,鼠标悬浮的时候,颜色是不会发生改变的; 移动端是没有鼠标的,也没有鼠标悬浮事件; 移动端的PC事件也有问题,click在移动端大概有300ms的延迟
移动端事件
触摸事件touch只有移动端才有touch事件
touch事件模型
touchsatrt:当手指触摸屏幕时触发,不管当前有多少只手指
touchmove:当手指在屏幕上滑动时连续触发,通常我们再滑屏页面,会调用event.preventDefault()
touchend:当手指离开屏幕时触发
touchcancel:系统通知跟踪触摸时候会触发。例如在触摸过程中突然有人打电话过来取消了当前的操作,此时会触发事件,这个事件用的比较少;
触摸事件的响应顺序:ontouchsatrt > ontouchmove > ontouchend > onclick 300ms延时
移动端为什么不用click
click事件在手机端会出现大概300ms的延迟,实际的执行延迟要比这个大,因为浏览器的内核运行也需要消耗事件。延迟执行的原因是苹果最早在手机上做了一个事件,当双击页面的时候,页面放大,也就是说,在点击页面的300ms之内,如果没有在此触发点击,则认为是单击事件,如果在此触发则认为是双击事件。 但目前,一般在手机web中,不允许缩放,也就没有双击事件,但是click延迟执行会影响用户体验; 谷歌判断点击的条件是 长按呀lang press的事件阀值为700ms,超过700ms就不再触发click事件
去除移动端click300ms延迟
meta标签
<meta name="viewport" content="width=device-width">
即把viewport设置成设备的实际像素,那么就不会有这300ms的延迟,并且这个举动收到了IE/Firefox/Safari(IOS9.3)的支持,也就是说现在的移动端开发可以不用顾虑click会比较迟钝的问题; 如果设置为initial-scale=1.0,在chrome上是可以生效,但是Safari不会:
<meta name="viewport" content="initial-scale=1.0">
css去除
html{touch-action: manipulation;}
fastClick库
截止2015年底,大多数移动浏览器(特别是Chrome和Safari)不再具有300ms的触摸延迟,毕竟再多引入一个js文件对项目也没有什么好处,不推荐使用。
touch事件对象
每个touch事件对象包含的属性如下:
- clientX:触摸目标在视口中的x坐标。
- clientY:触摸目标在视口中的y坐标。
- pageX:触摸目标在页面中的x坐标。
- pageY:触摸目标在页面中的y坐标。
- screenX:触摸目标在屏幕中的x坐标。
- screenY:触摸目标在屏幕中的y坐标。
- identifier:标识触摸的唯一ID。
- target:触摸的DOM节点目标。
- targetTouches: 当前对象上所有触摸点的列表数组
- changeTouches:涉及当前(引发)事件的触摸点的列表数组,常用于手指离开的事件,手指都离开屏幕之后,touches和targetTouches中将不再有只,targetTouches还会有一个只,此值为最后一个离开屏幕的手指的触摸点。