JS基础回顾_事件基础
this 指向
- addEventListener: dom
- attachEvent: dom
- onXXX: window
如何解决 IE 的 bug?
div.attachEvent('click', function () {
handle.call(div)
})
function handle() {
// 事件处理函数
}
考虑兼容性的事件处理函数
/**
* 考虑兼容性的事件处理函数
*/
function addEvent(element, type, handle) {
if (element.addEventListener) {
element.addEventListener(type, handle, false)
} else if (element.attachEvent) {
element.attachEvent('on' + type, function () {
handle.call(element) // 改变this指向
})
} else {
element['on' + type] = handle
}
}
addEventListener 一个事件处理函数只能被绑定一次。这和 attachEvent(IE)不同。
<!-- log -->
<button id="event_test_1">点我</button>
<script>
let element = document.getElementById('event_test_1')
element.addEventListener('click', test, false)
element.addEventListener('click', test, false)
function test() {
alert('click')
}
</script>
<!-- log -->
<button id="event_test_2">点我</button>
<script>
let element = document.getElementById('event_test_2')
element.addEventListener(
'click',
function () {
alert('click')
},
false
)
element.addEventListener(
'click',
function () {
alert('click')
},
false
)
</script>
解除事件绑定函数
ele.onclick = false / null
ele.removeEventListen(type, fn, false)
ele.detachEvent('on' + type, fn)
冒泡和捕获
事件冒泡:结构上自子元素传递到父元素
1
2
3
1
2
3
// run
let thePop = document.getElementById('thePop')
{
let div1 = thePop.getElementsByClassName('div1')[0]
let div2 = thePop.getElementsByClassName('div2')[0]
let div3 = thePop.getElementsByClassName('div3')[0]
div1.addEventListener(
'click',
function () {
alert('div1')
},
false
)
div2.addEventListener(
'click',
function () {
alert('div2')
},
false
)
div3.addEventListener(
'click',
function () {
alert('div3')
},
false
)
}
{
let theCatch = document.getElementById('theCatch')
let div1 = theCatch.getElementsByClassName('div1')[0]
let div2 = theCatch.getElementsByClassName('div2')[0]
let div3 = theCatch.getElementsByClassName('div3')[0]
div1.addEventListener(
'click',
function () {
alert('div1')
},
true
)
div2.addEventListener(
'click',
function () {
alert('div2')
},
true
)
div3.addEventListener(
'click',
function () {
alert('div3')
},
true
)
}
事件捕获:只在 Chrome 可用
如果既有捕获也有冒泡,则顺序为
- 捕获
- 事件
- 冒泡
特殊事件不会冒泡和捕获
- focus
- blur
- change
- submit
- reset
- select
取消冒泡
e.stop
e.cancleBubble = true
function stopBubble() {
if (e.stopPropagation) {
e.stopPropagation
} else {
e.cancleBubble = true
}
}
取消默认事件
- return false(仅支持句柄的方式)
- e.preventDefault()
- e.returnValue = false
// no-log
let a = document.getElementById('test_default')
a.onclick = function (e) {
alert('默认事件被取消了')
cancleHandler(e)
}
function cancleHandler(event) {
if (event.preventDefault) {
event.preventDefault()
} else {
event.returnValue = false
}
}
事件源对象
<!-- log -->
<!-- 粗暴方式 -->
<div id="container_1">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
</div>
<script>
let container = document.getElementById('container_1')
let btnList = container.getElementsByTagName('button')
for (let i = 0; i < btnList.length; i++) {
btnList[i].onclick = function () {
alert(this.innerText)
}
}
</script>
<!-- log -->
<!-- 事件委托 -->
<div id="container_2">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<button>5</button>
</div>
<script>
let container = document.getElementById('container_2')
container.onclick = function (e) {
let event = e || window.event
let target = event.target || event.srcElement
alert(target.innerText)
}
</script>
事件委托机制的优点
- 性能好,不需要循环所有的元素一个个地绑定事件
- 灵活,当有新的子元素时不需要重新绑定
拖拽
<!-- log -->
<!-- 鼠标事件,仅在PC端有效 -->
<div id="moving_box_container">
<div id="moving_box" style="left: 0;top: 0; position: absolute; width:50px;height: 50px;background: blueviolet"></div>
</div>
<style>
#moving_box_container {
position: relative;
height: 200px;
max-width: 800px;
margin: 0 auto;
border: 1px solid black;
}
#moving_box {
left: 0;
top: 0;
position: absolute;
z-index: 9999;
width: 50px;
height: 50px;
background: blueviolet;
}
</style>
<script>
let box = document.getElementById('moving_box')
box.onmousedown = function (e) {
// -- 等式:鼠标相对于文档的位置 === 父元素的偏移 + left + 鼠标相对box的位置
// -- 等式:鼠标相对于文档的位置 === 一 + 二 + 三
// 暂存 一 + 三
let disX = e.pageX - parseInt(box.style.left)
let disY = e.pageY - parseInt(box.style.top)
// 防止鼠标移动过快,box监听不到
// box.onmousemove = function (e) {
document.onmousemove = function (e) {
let event = e || window.event
box.style.left = event.pageX - disX + 'px'
box.style.top = event.pageY - disY + 'px'
}
document.onmouseup = function () {
document.onmousemove = null
}
}
</script>

浙公网安备 33010602011771号