事件就是在文档中或者在浏览器窗口中通过某些动作触发。比如,单击,鼠标经过,键盘按下等。事件通常和函数结合使用。
<body>
<div style="height:100px;width:100px;background-color: red;">div>
body>
<script>
var div= document.getElementsByTagName('div')[0]
div.onclick=function(){
console.log('click事件触发')
}
script>
这时候点击div标签后会触发click事件
让div标签绑定两个事件
<body>
<div style="height:100px;width:100px;background-color: red;">div>
body>
<script>
var div= document.getElementsByTagName('div')[0]
div.onclick=function(){
console.log('a')
}
div.onclick=function(){
console.log('b')
}
script>
点击之后没有出现a b 只出现了b
后一个事件会覆盖前一个事件
div.onclick 等同于在div标签上写个onclick属性
<body>
<div style="height:100px;width:100px;background-color: red;" onclick="console.log('a')">div>
body>
点击div标签
和法一相比不用写on了 直接写事件名称
<body>
<div style="height:100px;width:100px;background-color: red;" >div>
body>
<script>
var div= document.getElementsByTagName('div')[0]
div.addEventListener("click",function(){
console.log("click事件")
},false)
script>
点击div标签之后
<body>
<div style="height:100px;width:100px;background-color: red;" >div>
body>
<script>
var div= document.getElementsByTagName('div')[0]
div.addEventListener("click",function(){
console.log("click事件1")
},false)
div.addEventListener("click",function(){
console.log("click事件2")
},false)
script>
点击div标签
会按照绑定的顺序执行
但是 函数值的引用要不同才行
var div = document.getElementsByTagName('div')[0]
div.addEventListener('click', test, false)
div.addEventListener('click', test, false)
function test() {
console.log("触发click事件")
}
这时候点击div只会打印一个
<script>
var div = document.getElementsByTagName('div')[0]
div.onclick = function(){
console.log(this)
}
</script>
点击div标签
<script>
var div = document.getElementsByTagName('div')[0]
div.addEventListener('click', function () {
console.log(this)
},false)
</script>
点击div标签
怎么让程序this指向本身?
<script>
var div = document.getElementsByTagName('div')[0]
div.attachEvent('onclick',function(){
handle.call(div)
})
function handle(){
//事件处理程序
}
</script>
方法:
```html
<script>
var div = document.getElementsByTagName('div')[0]
div.onclick = function () {
console.log('div')
this.onclick=null
}
script>
假如写成这种处理函数那么肯定是解除不了的 因为处理函数是匿名的
<script>
var div = document.getElementsByTagName('div')[0]
div.addEventListener('click', function (e) {
console.log('div')
},false)
script>
正确写法:
<script>
var div = document.getElementsByTagName('div')[0]
div.addEventListener('click', handle, false);
function handle() {
console.log("A")
}
div.removeEventListener('click',handle,false)
script>
若绑定匿名函数,则无法解除
用途:
事件名称 | 说明 |
---|---|
click | click=mousedown+mouseup |
mousedown | 鼠标点击触发(不用放开) |
mouseup | 鼠标点击放开之后触发 |
contextmenu | 右键出现菜单 |
mouseover | 鼠标移入 等于mouseenter |
mouseout | 鼠标移出 等于mouseleave |
mousemove | 鼠标移动触发 |
只有mousedown事件和mouseup事件可以区分出来,为什么?
因为DOM3标准规定:click事件只能监听左键
var div = document.getElementsByTagName('div')[0]
div.onmousedown = function (e) {
console.log(e)
}
当鼠标左键点击之后
事件e的button属性为0
当鼠标中间点击之后
事件e的button属性为1
当鼠标右键点击之后
事件e的button属性为2
onload、onscoll、onsubmit、onchange、onfoucs(获取焦点),onblur(失去焦点)
事件名称 | 说明 |
---|---|
keydown | 键盘按下时触发 |
keyup | 键盘抬起时触发 |
onkeypress | 用户摁下摁键,并且产生一个字符时发生 |
触发顺序:keydown>keypress>keyup
事件名称 | 说明 |
---|---|
input | 当input里的文本有变化会触发 |
change | 先聚焦input在失去焦点(如果input内容变化)会触发 |
blur | 失去焦点 |
focus | 聚焦 |
搜索栏默认内容案例
<input type='text' value="请输入关键字" style='color:#999' onfocus="if(this.value=='请输入关键字'){this.value='';this.style.color='#424242'}" onblur="if(this.value=='') {this.value='请输入用户名' ;this.style.color='#999'}">
<input/>
事件名称 | 说明 |
---|---|
scroll | 当滚动条一滚动触发 |
load | 即当页面都渲染完之后才触发 |
window.onscroll=function(){
console.log(window.pageXoffset + " " + window.pageYoffset);
}
window.onload方法了解,一般不去使用,效率太低了,是最慢执行.
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素(自底向上)
<style>
.wrapper {
width: 300px;
height: 300px;
background-color: red;
}
.content{
width: 200px;
height:200px;
background-color:green;
}
.box{
width:100px;
height:100px;
background-color:orange
}
style>
head>
<body>
<div class="wrapper">
<div class="content">
<div class="box">div>
div>
div>
body>
<script>
var wrapper = document.getElementsByClassName('wrapper')[0];
var content = document.getElementsByClassName('content')[0];
var box = document.getElementsByClassName('box')[0];
wrapper.addEventListener('click',function(){
console.log('wrapper')
},false)
content.addEventListener('click',function(){
console.log('content')
},false)
box.addEventListener('click',function(){
console.log('box')
},false)
script>
点击黄色
点击绿色
点击红色
focus,blur,change,submit,reset,select等事件不冒泡
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)(自顶向下)
IE没有捕获事件
小知识:
除了addEventListener的第三个事件的true可以捕获事件外,
另一种捕获是IE的一个方法setCapture() dom元素执行后可以捕获页面上的所有事件加在dom元素身上触发。有一个对应的函数叫releaseCapture();可以释放。
addEventListener(type,fn,true) 将第三个形参改为true
<style>
.wrapper {
width: 300px;
height: 300px;
background-color: red;
}
.content{
width: 200px;
height:200px;
background-color:green;
}
.box{
width:100px;
height:100px;
background-color:orange
}
style>
head>
<body>
<div class="wrapper">
<div class="content">
<div class="box">div>
div>
div>
body>
<script>
var wrapper = document.getElementsByClassName('wrapper')[0];
var content = document.getElementsByClassName('content')[0];
var box = document.getElementsByClassName('box')[0];
wrapper.addEventListener('click',function(){
console.log('wrapper')
},true)
content.addEventListener('click',function(){
console.log('content')
},true)
box.addEventListener('click',function(){
console.log('box')
},true)
script>
点击黄色
点击绿色
点击红色
和事件冒泡执行顺序相反
因为addEventListener可以绑定多个处理函数
故 当同时存在事件冒泡和事件捕获时 是先触发哪个?
<script>
var wrapper = document.getElementsByClassName('wrapper')[0];
var content = document.getElementsByClassName('content')[0];
var box = document.getElementsByClassName('box')[0];
//捕获
wrapper.addEventListener('click', function () {
console.log('wrapper')
}, true)
content.addEventListener('click', function () {
console.log('content')
}, true)
box.addEventListener('click', function () {
console.log('box')
}, true)
//冒泡
wrapper.addEventListener('click', function () {
console.log('wrapper2')
}, false)
content.addEventListener('click', function () {
console.log('content2')
}, false)
box.addEventListener('click', function () {
console.log('box2')
}, false)
</script>
点击黄色
先捕获,后冒泡
<script>
var wrapper = document.getElementsByClassName('wrapper')[0];
var content = document.getElementsByClassName('content')[0];
var box = document.getElementsByClassName('box')[0];
//冒泡
wrapper.addEventListener('click', function () {
console.log('wrapper')
}, false)
content.addEventListener('click', function () {
console.log('content')
}, false)
box.addEventListener('click', function () {
console.log('box')
}, false)
//取消冒泡事件
box.onclick=function(event){
event.stopPropagation()
}
content.onclick=function(event){
event.stopPropagation()
}
</script>
这时候点击黄色
点击绿色
不支持ie9以下版本
默认事件:
以对象属性的方式注册的事件才能生效
//阻止网页右键菜单
document.oncontextmenu = function () {
return false
}
未取消前:
取消后 在按鼠标右键无反应
document.oncontextmenu = function(e){
e.preventDefault()
}
W3C标准,IE9以下不兼容
兼容IE
document.oncontextmenu = function (e){
e.returnValue = false
}
兼容性写法:
div.onclick = function (e){
var event = e||window.event
}
event.target 火狐只有这个
event.srcElement IE只有这个
这两chrome都有
兼容性写法
div.onclick = function (e){
//取出事件
var event = e || window.event
//取出事件源
var target = event.target ||event.srcElement
}
例如有十个li 要求点击一个li就输出这个li的innerText
方法一:虽然这么写也可以 但是如果有大数量的li则性能不好
<body>
<ul>
<li>1li>
<li>2li>
<li>3li>
<li>4li>
<li>5li>
<li>6li>
<li>7li>
<li>8li>
<li>9li>
<li>10li>
ul>
body>
<script>
var li =document.getElementsByTagName('li')
var len = li.length;
for(var i = 0;i<len;i++){
li[i].onclick=function(){
console.log(this.innerText) //或者innerText
}
}
script>
方法二:
var ul =document.getElementsByTagName('ul')[0]
ul.onclick = function(e){
//取出事件
var event = e || window.event
//取出事件源
var target = event.target ||event.srcElement
//打印出事件源对象的内容 原理就是通过冒泡 点击li一定会冒泡到ul
//冒泡 自底向上冒泡
console.log(target.innerHTML)
}
<ul>
<li>ali>
<li>ali>
<li>ali>
<li>ali>
ul>
使用原生js,addEventListener,给每隔li元素绑定一个click事件输出他们的顺序
法一:let 没有闭包问题
<body>
<ul>
<li>ali>
<li>ali>
<li>ali>
<li>ali>
ul>
body>
<script>
var li =document.getElementsByTagName('li')
for(let i =0 ; i<li.length;i++){
li[i].addEventListener('click',function(){
console.log(i)
})
}
script>
法二:var 解决闭包
<body>
<ul>
<li>ali>
<li>ali>
<li>ali>
<li>ali>
ul>
body>
<script>
var liCol = document.getElementsByTagName('li'),
len = liCol.length;
for (var i = 0; i < len; i++) {
(function (i) {
liCol[i].addEventListener('click', function () {
console.log(i);
});
}(i))
}
script>
function addEvenet(elem,type,handle){
if(elem.addEvenetListener){
elem.addEvenetListener(type,handle,false)
}else if(elem.attachEvent){
elem.attachEvent('on'+type,function(){
handle.call(elem)
})
}else{
elem['on'+type] = handle
}
}
function stopBubble(event){
if(event.stopPropagation){
event.stopPropagation()
}else{
event.cancelBubble=true
}
}
使用的时候直接传入e就可以了
function cancelHandler(e){
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false
}
}
var a = document.getElementsByTagName('a')[0]
a.onclick = function() {
return false
}
点击方块可以拖着移动 ,放开点击会暂停
var div = document.getElementsByTagName('div')[0]
var disX,
disY;
//当鼠标点击之后触发
div.onmousedown = function (e) {
disX=e.pageX-parseInt(div.style.left);
disY=e.pageY-parseInt(div.style.top);
//当鼠标移动之后触发
document.onmousemove=function(e){
var event = e || window.event;
//记录当前鼠标点的位置
// console.log(e.pageX + " " + e.pageY);
div.style.left = event.pageX -disX+ "px";
div.style.top = event.pageY -disY+ "px"
}
//当鼠标再次点击
document.onmouseup =function(e){
document.onmousemove = null
}
}
里面为什么要用document而不是用div是因为如果鼠标移动出浏览器的界面会反应不过来 而document不管你鼠标位置在哪会慢慢跟过去