1. 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中触发
如果是函数的调用,可以传递一个参数,this(表示的是当前的标签)
<div class="box" onclick="changeColor(this,'green')"></div>
<script>
function changeColor(getThis,color1){
console.log(getThis);
getThis.style.backgroundColor = color1;
}
</script>
鼠标事件
事件 | 说明 |
onclick | 鼠标点击某个对象 |
ondblclick | 鼠标双击某个对象 |
onmouseover | 鼠标被移到某元素之上 |
onmouseout | 鼠标从某元素移开 |
onmousemove | 鼠标被移动 |
onmousedown | 某个鼠标按键被按下 |
onmouseup | 某个鼠标按键被松开 |
oncontextmenu | 右键事件 |
onmousewheel | 当滚轮被滚动的时候 |
onmouseenter 和 onmouseover的区别
- onmouseover、onmouseout:鼠标经过时自身触发事件,经过其子元素时也触发该事件;(父亲有的东西,儿子也有) ,支持冒泡
- onmouseenter、onmouseleave:鼠标经过时自身触发事件,经过其子元素时不触发该事件。(父亲的东西就是父亲的,不归儿子所有) ,不支持冒泡
<!-- 给一个元素添加多个点击事件 -->
<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>
键盘事件
页面中有时候想要提交表单数据,直接按下enter就可以提交了;或者在玩游戏的时候可以通过WASD这四个按键来控制上下左右的方向,这就是通过键盘事件来操作的
事件 | ****说明 |
onkeypress[使用的比较少] | 键盘的某个键被按下 |
onkeydown | 键盘的某个键被按下或按住 |
onkeyup | 键盘的某个键被松开 |
一个onkeydown+onkeyup 相当于 鼠标单击事件的过程,想要区分键盘上的每个按键,是通过键盘的keyCode值来判断的,所以想要知道按下的是哪个按键,可以使用event.keyCode onkeydown 只要是按下的状态,就会一直触发当前事件 onkeyup 只有弹起的那一瞬间,才会触发
//获取对应的键盘值
document.onkeyup = function(){
console.log(event.keyCode);
}
案例:通过上下左右四个键,控制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>
最好的方法还是通过left,top这些值来改变元素的位置,这样代码会更简单
光标事件
事件 | 说明 |
onfocus | 元素获得焦点 |
onblur | 元素失去焦点 |
案例:模拟小米官网搜索框效果
<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>
表单事件
事件 | 说明 |
onsubmit | 提交按钮被点击 |
onreset | 重置按钮被点击 |
onselect | 文本内容被选定 |
onchange | 用户改变表单元素的内容 |
oninput | 在用户输入时触发 |
onsubmit,onreset相对来说用的比较少
onchange,onselect 属性可用于以下元素内:以及 在百度文库中,当我们选中文本的内容的时候,会显示 搜索/复制/发送到手机/翻译 等内容,这时候就可以使用onselect
文本被选中
// 给多行文版框添加 选择的功能
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>.
- oninput事件类似于 onchange 事件。不同之处在于 oninput 事件在元素值发生变化是立即触发, onchange 在元素失去焦点时触发。另外一点不同是 onchange 事件也可以作用于 <keygen> 和 <select> 元素。
单选框和复选框被选中
复选框是否被选中需要判断复选框中的checked的值 true:选中 false:没选中
购物车案例
<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>
加载事件
导语:正常情况下,js代码是可以写在head标签中,也可以写在/body结束的后面;但是当我们把js代码写在head中,并且js代码中有获取页面html标签的操作的时候,这时候的js代码就会报错1
表示没有 “无法读取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>
窗口事件
事件 | 说明 |
onresize | 览器窗口被调整大小时发生 |
滚动事件
事件 | 说明 |
onscroll | 窗口发生滚动 |
scrollTo | 滚动到指定位置【增加】 |
-
文档可视区域高度(屏幕的高度) 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
楼层导航
<style>
* {
margin: 0;
padding: 0;
}
ul,li {
list-style: none;
}
.header {
position: fixed;
left: 0;
top: 0;
height: 40px;
width: 100%;
background-color: rgb(238, 215, 110);
line-height: 40px;
}
.header ul {
display: flex;
justify-content: space-around;
}
.header ul li.active {
color: #f00;
}
.empty {
height: 40px;
}
.product {
background-color: rgb(178, 204, 238);
height: 500px;
}
.ratings {
background-color: rgb(178, 238, 218);
height: 200px;
}
.detail {
background-color: rgb(231, 238, 190);
height: 900px;
}
.recommend {
background-color: rgb(241, 202, 220);
height: 800px;
}
</style>
<div class="header">
<ul>
<li class="active">商品</li>
<li>评价</li>
<li>详情</li>
<li>推荐</li>
</ul>
</div>
<div class="empty"></div>
<div class="product floor">
商品
</div>
<div class="ratings floor">
评价
</div>
<div class="detail floor">
详情
</div>
<div class="recommend floor">
推荐
</div>
<script>
//单击切换楼层
var navList = document.getElementsByClassName('header')[0].getElementsByTagName('li');
var floorList = document.getElementsByClassName('floor');
navList[2].onclick = function(){
// 排他思想
for(var i=0;i<navList.length;i++){
navList[i].classList.remove("active");
}
// 给当前元素添加active
this.classList.add("active")
// window.scrollTo(0,floorList[1].offsetTop - 40)
window.scrollTo({
top: floorList[2].offsetTop - 40,
behavior: 'smooth'
})
};
/*
定时器实现楼层导航
var floor = document.querySelectorAll('.floor')
var lis = document.querySelectorAll('.header li')
var arr = []
for (var i = 0; i < floor.length; i++) {
arr.push(floor[i].offsetTop)
}
for (let i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
for (var j = 0; j < lis.length; j++) {
lis[j].className = ''
}
this.className = 'active'
timer = setInterval(function () {
var top = document.documentElement.scrollTop;
if (top > arr[i] - 40) {
top -= 1
} else if (top < arr[i] - 40) {
top += 1
} else {
top = arr[i] - 40
clearInterval(timer)
}
document.documentElement.scrollTop = top;
}, 5);
}
}
*/
</script>
点击按钮返回顶部
<style>
body{
height: 3000px;
}
div{
padding: 20px 3px;
background-color: pink;
position: fixed;
right: 10px;
bottom: 10px;
display: none;
}
</style>
<body>
<div id='box'>返回顶部</div>
</body>
<script>
var oBox= document.getElementById('box');
window.onscroll=function(){
var top = document.documentElement.scrollTop||document.body.scrollTop;
if(top>=200){
oBox.style.display = 'block';
}else{
oBox.style.display = 'none';
}
oBox.onclick=function(){
setInterval(goTop,10)
}
function goTop(){
var top = document.documentElement.scrollTop||document.body.scrollTop;
if(top>0){
top -= 50;
document.documentElement.scrollTop = top;
}
}
}
</script>
js中两种添加事件的方式
-
方式一 :on+事件名
-
方法二:添加事件监听
方式一 :on+事件名
// 添加事件关联
oneDiv.onclick = function() {
console.log("+++++");
}
oneDiv.onclick = function() {
console.log("-----");
}
// 取消事件关联
oneDiv.onclick = null;
oneDiv.onclick = false;
方法二:添加事件监听【推荐使用】
语法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);
事件中的Event对象
-
只要事件发生就会产生一个event事件
-
事件发生后创建对象
-
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
-
事件通常与函数结合使用,函数不会在事件发生前被执行
event事件对象常见的属性和方法
****事件对象属性方法 | ****说明 |
e.target | 返回触发事件的对象 标准 |
e.srcElement | 返回触发事件的对象 非标准ie6-8使用 |
e.type | 返回事件的类型,比如:click,mouseover 不带on |
e.returnValue | 该属性阻止默认事件(默认行为) ie6-8,比如不让链接跳转 |
e.preventDefault() | 该属性阻止默认事件(默认行为)标准,比如不让链接跳转 |
e.stopPropagation() | 阻止冒泡 【标准】 |
e.cancelBubble | 阻止冒泡【ie】 |
阻止默认事件的发生
点击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>
对于一些标签来说,他们拥有自己的事件,比如: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;
}
}
事件流-事件冒泡机制
参考文档:面试题7:Js事件流,事件冒泡(IE事件流)_事件冒泡面试题-CSDN博客
气泡从水底开始往上升,由深到浅,升到最上面。在上升的过程中,气泡会经过不同深度层次的水。
相对应地:这个气泡就相当于我们这里的事件,而水则相当于我们的整个dom树; 事件从dom 树的底层,层层往上传递,直至传递到dom的根节点。
当子元素与父元素有相同的事件时,当子元素被触发时父元素也会被触发冒泡机制
在不同浏览器中,冒泡的程度不同
IE 6.0: div -> body -> html -> document
其他浏览器: div -> body -> html -> document -> window
注意:并不是所有的事件都能冒泡,以下事件不冒泡:blur、focus、load、unload
<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(){
alert('father点击');
}
btn.onclick = function(){
alert('btn点击');
}
document.onclick = function(){
alert('文档点击');
}
}
</script>
阻止冒泡的方法
标准浏览器 和 ie浏览器 w3c:event.stopPropagation() IE: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>
事件委托
需求:只做一个鲜花网手机端购物车效果 点击能够添加一个商品,在商品上点击删除能够删除这个商品
<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事件。
事件封装
// 绑定事件 - 判断是否是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;
}
}
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>
移动端事件
触摸事件touch只有移动端才有touch事件
touch事件模型
touchsatrt:当手指触摸屏幕时触发,不管当前有多少只手指
touchmove:当手指在屏幕上滑动时连续触发,通常我们再滑屏页面,会调用event.preventDefault()
touchend:当手指离开屏幕时触发
touchcancel:系统通知跟踪触摸时候会触发。例如在触摸过程中突然有人打电话过来取消了当前的操作,此时会触发事件,这个事件用的比较少;
触摸事件的响应顺序:ontouchsatrt > ontouchmove > ontouchend > onclick 300ms延时
去除移动端click300ms延迟
meta标签
<meta name="viewport" content="width=device-width">
css去除
html{touch-action: manipulation;}
touch事件对象
每个touch事件对象包含的属性如下:
-
clientX:触摸目标在视口中的x坐标。
-
clientY:触摸目标在视口中的y坐标。
-
pageX:触摸目标在页面中的x坐标。
-
pageY:触摸目标在页面中的y坐标。
-
screenX:触摸目标在屏幕中的x坐标。
-
screenY:触摸目标在屏幕中的y坐标。
-
identifier:标识触摸的唯一ID。
-
target:触摸的DOM节点目标。
-
targetTouches: 当前对象上所有触摸点的列表数组
-
changeTouches:涉及当前(引发)事件的触摸点的列表数组,常用于手指离开的事件,手指都离开屏幕之后,touches和targetTouches中将不再有只,targetTouches还会有一个只,此值为最后一个离开屏幕的手指的触摸点。