# JS-事件

🐴

# 概念

事件是与浏览器或文档交互的瞬间,如点击按钮,填写表格等,它是JS与HTML之间交互的桥梁。

# 触发事件的方式

  1. 第一种,直接在HTML 内嵌js
<button id="div" onclick="javascript:var a = 1+3; alert(a);" >
    点击我
</button>
  1. 第二种
<button id="div1" onclick="fun()" >
    点击我
</button>

<script>
    function fun(){
        alert("我是第二种方法")
    }
</script>
  1. 第三种
<button id="div2" >
    点击我
</button>
<script>
    document.getElementById("div2").onclick = function (){
        alert("我是第三种方法")
    }
</script>
  1. 第四种
<button id="div3" >
     addEventListener  点击我
</button>

<script>
    function myFun(){
        console.log("触发了")
    }
    document.getElementById("div3").addEventListener('click',myFun)

    setTimeout(function(){
        document.getElementById("div3").removeEventListener("click",myFun)
    },3000)

</script>

# 常用的事件

更多事件查看 (opens new window)

这里讲几个特殊事件:

  • onmouseenter 当鼠标指针移动到元素上时触发。

  • onmouseleave 当鼠标指针移出元素时触发

  • onmouseover 鼠标移到某元素之上。

  • onmouseout 鼠标从某元素移开。

注意

onmouseenteronmouseover 都是移动到元素上时触发,但是区别是onmouseenter移动到子元素上时也会再次触发并且还会再次冒泡到父元素,而onmouseover 只触发一次,当移动到元素的子元素时不会在有再触发也不会在冒泡,

# 事件对象Event

  • Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
  • 事件通常与函数结合使用,函数不会在事件发生前被执行!

Event 对象 是在鼠标键盘事件触发时,注入到触发函数中的,以函数中第一个参数来表示。例如:

var div1 = document.querySelector('.div1')
div1.onmouseenter = function(event){
    //event.target 获取到的是触发的事件源,这里只 id为 div1 的元素
    console.log(event.target) 
}

# 获取 键盘按键信息

let body = document.querySelector('body')
body.onkeydown = function(e){
    // 当键盘按键按下时会输出所按下的按钮名称
        console.log(e.key)
}

# 获取鼠标位置

浏览器的可视坐标 clientX与clientY

let body = document.querySelector('body')
body.onmousemove = function(e){
    console.log('鼠标所在浏览器中的X坐标:'+ e.clientX)
    console.log('鼠标所在浏览器中的Y坐标:'+ e.clientY)
}

需要注意的是: 再给body添加事件时要给body设置高度,因为body默认高度为0

设备屏幕坐标 screenX与 screenY

let body = document.querySelector('body')
body.onmousemove = function(e){
    console.log('鼠标所在设备屏幕中的X坐标:'+ e.screenX)
    console.log('鼠标所在设备屏幕中的Y坐标:'+ e.screenY)
}

movementX 和 movementY 坐标轴

movementXmovementY 鼠标位置是以鼠标进入元素时的x和y轴为初始坐标(0,0), 向左x轴坐标为负值,向右x轴坐标为正值,向上y轴坐标为正值,向下为负值。

let body = document.querySelector('body')
body.onmousemove = function(e){
    console.log('鼠标的X坐标:' + e.movementX)
    console.log('鼠标的Y坐标:'+ e.movementY)
}

# 获取鼠标按钮

onmousedown 事件中我们可以通过 event.button 来获取鼠标按下的信息

以webkit 内核的浏览器为例:

body.onmousedown = function(event){
    console.log("鼠标按下左键为(0):" + event.button)
    console.log("鼠标按下滚轮键为(1):" + event.button)
    console.log("鼠标按下右键为(2):" + event.button)
}
  • 一般浏览器有默认行为,我们想阻止浏览器默认行为可以使用 eventDefault()
document.body.oncontextmenu = function(event){
   event.eventDefault() // 阻止浏览器出现右键菜单栏
}

# 事件的冒泡和捕获

  • 冒泡事件,由里向外,最里层的元素先执行,然后冒泡到外层。

  • 捕获事件,由外向里,最外层的元素先执行,然后传递到内部。

<div class="div1">
    <div class="div2">div2 我先冒泡后捕获</div>
    我先捕获后冒泡
</div>

<script>
    var div1 = document.querySelector('.div1')
    var div2 = document.querySelector('.div2')

    div1.onclick = function(){
        alert("我是div1")
    }
    div2.onclick = function(){
        alert("我是div2")
    }

</script>

# 阻止冒泡

  • 阻止事件冒泡可以使用 stopPropagation()
<div class="div1">
    <div class="div2">div2 我先冒泡后捕获</div>
    我先捕获后冒泡
</div>

<script>
    var div1 = document.querySelector('.div1')
    var div2 = document.querySelector('.div2')

    div1.onclick = function(e){
        alert("我是div1")
    }
    div2.onclick = function(e){
        e.stopPropagation() // 阻止div2事件冒泡
        alert("我是div2")
    }
</script>

# JS事件委托

那什么叫事件委托呢?它还有一个名字叫事件代理,《JavaScript高级程序设计》上讲:事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。下面我们来列举一个简单的例子来引出JS事件委托。

现在我们有这样段代码

<input type="button" id="btn" value="添加li标签"/>
<ul id="ul">
  <li>第一个</li>
  <li>第二个</li>
  <li>第三个</li>
</ul>

我们来给每个li标签添加一个点击事件,并弹出对应标签的内容

var ul = document.getElementById("ul");
var AllLi = ul.getElementsByTagName("li");
var oBtn = document.getElementById("btn");
var iNow =;
for(var i=0; i<AllLi.length; i++){
    AllLi[i].click = function(){
        alert(this.innerText)
    }
}

oBtn.onclick = function(){
   iNow ++;
   var oLi = document.createElement("li");
   oLi.innerHTML = "第"+iNow+"个";
   ul.appendChild(oLi);
}


现在我们点击页面上的每个li标签都会弹出对应的内容,接下来我们点击按钮,新添加几个li标签,然后我们点击新添加的li标签会发现没有任何反应。为什么没有反应呢,这是因为我们上面的方法只能够给页面中已经存在的元素添加事件,使用js后生成的元素时用这种方法是添加不上的。这时我们就要事件委托来处理这种情况了,当然我们还有其它方法,这里只是为了讲解事件委托。

原理

事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。

接下来我们使用事件委托来重写js代码

var oUl = document.getElementById("ul");
var aLi = oUl.getElementsByTagName("li");
var oBtn = document.getElementById("btn");
var iNow = 4;
 
oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == "li"){
      alert(target.innerText)
    }
}

oBtn.onclick = function(){
    iNow ++;
    var oLi = document.createElement("li");
    oLi.innerHTML = "第"+iNow+"个";
    oUl.appendChild(oLi);
}

最近更新时间: 7/2/2021, 11:27:27 AM