<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
body{
color: blue;
}
.ct,.ct1{
width: 100px;
height: 100px;
border: 1px solid red;
background-color: yellow;
margin: 20px;
}
.box,.box1{
width: 50px;
height: 50px;
background-color: blue;
}
.ct.hover, .ct1.hover{
border-color: blue;
background-color: pink;
}
.box3{
list-style: none;
background: yellow;
margin: 0;
padding: 0;
}
.box3>li{
background: pink;
margin: 5px;
padding: 10px;
}
.box3>li.hover{
background-color: blue;
}
.msg{
display: none;
}
</style>
</head>
<body>
<button id="btn">點(diǎn)我</button>
<button id="btn1">點(diǎn)我1</button>
<div class="ct" style="font-size: 20px">
<div class="box">hello</div>
</div>
<div class="ct1">
<div class="box1"></div>
</div>
<input id="input-name" type="text">
<form id="form" action="/upload">
<input id="username" name="username" type="text">
<p class="msg"></p>
<input id="btn-submit" type="submit" value="注冊(cè)">
</form>

<script>
function $(selector){
return document.querySelector(selector);
}
//方便書(shū)寫(xiě)而已
$('#btn').addEventListener('click', function(){
console.log('click')
console.log(this)
}) //在控制臺(tái)運(yùn)行,得到:click和button對(duì)象
$('#btn1').addEventListener('dblclick', function(){
console.log('dblclick')
console.log(this)
})
//dblclick就是事件雙擊,運(yùn)行同理得到結(jié)果。
$('.ct').addEventListener('mouseover', function(){
console.log('mouseover')
console.log(this)
// this.style.borderColor = 'blue'
this.classList.add('hover')
})
//mouseover鼠標(biāo)放上去的時(shí)候,這個(gè)事件,類似于放上去就能翻譯這種效果的。
執(zhí)行觸發(fā)了事件后,這里的樣式發(fā)生了改變,簡(jiǎn)單的就直接this.style.borderColor修改,復(fù)雜的樣式就直接在this.classList.add個(gè)class比較好。
$('.ct').addEventListener('mouseout', function(){
console.log('mouseout...')
// this.style.borderColor = 'red'
this.classList.remove('hover')
})
//mouseout鼠標(biāo)移出事件,然后執(zhí)行方法,,,
//有時(shí)候會(huì)有類似的bug出現(xiàn),鼠標(biāo)放上去,觸發(fā)事件,執(zhí)行一些動(dòng)畫(huà)方法,
//于是元素動(dòng)了,等到元素動(dòng)到鼠標(biāo)指不到了,事件不觸發(fā)了,
//動(dòng)畫(huà)又沒(méi)了,又不動(dòng)了,不動(dòng),鼠標(biāo)又指向了然后又循環(huán)起來(lái)了,,,
$('.ct1').addEventListener('mouseenter', function(){
console.log('mouseenter...')
//this.style.borderColor = 'blue'
this.classList.add('hover')
})
//mouseenter運(yùn)行貌似跟mouseover一樣啊,再重新試驗(yàn)nouseover,mouseout下:
父元素有子元素嵌套著,穿過(guò)這些嵌套時(shí),只要區(qū)域發(fā)生變化,就out,進(jìn)入新區(qū)域就over,也就是有孩子時(shí),穿過(guò)孩子也要算out,然后新的over。
而mouseenter和mouseleave就是指這個(gè)元素的區(qū)域,區(qū)域里多少孩子區(qū)域不管,所以這個(gè)比較實(shí)用。
$('.ct1').addEventListener('mouseleave', function(){
console.log('mouseleave...')
//this.style.borderColor = 'blue'
this.classList.remove('hover')
})
$('#input-name').addEventListener('focus', function(){
console.log('focus...')
console.log(this.value)
})
//focus用戶激活的狀態(tài),獲取焦點(diǎn),選中可以操作,比如input,被選中,可以輸入的時(shí)候。
$('#input-name').addEventListener('blur', function(){
console.log('blur...')
console.log(this.value)
})
//blur對(duì)應(yīng)focus,是失去焦點(diǎn),沒(méi)被選中,,,這時(shí)候可以做一些事情,比如判斷是否輸入格式正確。
$('#input-name').addEventListener('keyup', function(e){
console.log('keyup...')
console.log(this.value)
console.log(e)
// this.value = this.value.toUpperCase()
})
//keyup按下鍵盤(pán),松開(kāi)時(shí)才觸發(fā)。keydown是按下就觸發(fā)。
$('#input-name').addEventListener('change', function(e){
console.log('change...')
console.log(this.value)
console.log(e)
this.value = this.value.toUpperCase()
})
//內(nèi)容發(fā)生改變,并焦點(diǎn)移開(kāi),觸發(fā)change。
$('#form').addEventListener('submit', function(e){
e.preventDefault(); //阻止默認(rèn)事件提交
if(/^\w{6,12}$/.test($('#username').value)){
$('#form').submit();
}else{
$('#form .msg').innerText = '出錯(cuò)了'
$('#form .msg').style.display = 'block'
console.log(' no submit...');
}
})
//submit提交事件,可以form.submit這樣寫(xiě),也可addEventListener。
//判斷用戶名輸入是否正確,正確提交,不正確就出現(xiàn)報(bào)錯(cuò)的message,不提交。
window.addEventListener('scroll', function(e){
console.log('scroll..')
})
//scroll滾動(dòng)事件,這里說(shuō)一下,滾動(dòng)一格,是好幾次的事件觸發(fā),滾動(dòng)好多格,事件觸發(fā)很多,性能消耗,這時(shí)候可以用函數(shù)節(jié)流,以最后一次滾動(dòng)為觸發(fā)事件,否則取消scroll事件,不讓偵聽(tīng)到,設(shè)置計(jì)時(shí)器300毫秒,這段時(shí)間有滾動(dòng)就清零計(jì)時(shí)器,沒(méi)有就是觸發(fā)。
window.addEventListener('resize', function(e){
console.log('resize..')
})
//resize是窗口變了的事件,窗口變化執(zhí)行不像滾動(dòng)變化頻率高,也可以做函數(shù)節(jié)流。
//頁(yè)面所有資源加載完成
window.onload = function(){
console.log('window loaded')
}
//onload所有的內(nèi)部外部的東西都準(zhǔn)備好了,圖片可以看了,時(shí)機(jī)很晚。
//DOM 結(jié)構(gòu)解析完成
document.addEventListener('DOMContentLoaded', function(){
console.log('DOMContentLoaded ')
})
//DOMContentLoaded就是DOM結(jié)構(gòu)渲染完成,不一定看到效果,不一定css渲染完成,很早。這時(shí)候,如果在head里有script標(biāo)簽針對(duì)body的元素,就沒(méi)有效果了,怎么辦?
//在JS文件內(nèi)容外,用事件DOMContentLoaded包裹下,放到head里就可以了。
console.log($('img').width) //0,這時(shí)候執(zhí)行,圖片在網(wǎng)絡(luò)請(qǐng)求和收取解析圖片過(guò)程中,img只是一個(gè)空標(biāo)簽,所以是0。
$('img').onload = function(){
console.log(this.width) //此時(shí)才能得到圖片的真實(shí)大小,onload圖片已經(jīng)加載好了。
}
//最后window.loaded也就onload
</script>
</body>
</html>
還有很多事件不一一細(xì)說(shuō)了,可以自己用到了,再拓展了。
自定義事件
我覺(jué)得,不是自定義的事件,比如click之類的,首先聲明了這個(gè)click是個(gè)事件,然后,這個(gè)事件是如何觸發(fā)的,也要聲明,有了這兩個(gè),基本就簡(jiǎn)單了:一個(gè)套路走下去,先綁定事件,然后確定偵聽(tīng)事件的元素,最后,偵聽(tīng)元素偵聽(tīng)到事件后,要執(zhí)行什么東東。嗯,我也算是理了下這個(gè)事件的小邏輯了哦。這算是奧義哦哦哦。
我想模擬一個(gè)瀏覽器沒(méi)有的事件哦哦,,,
var EventCenter = {
on: function(type, handler){
document.addEventListener(type, handler)
}, //有一個(gè)on的方法,聲明(事件,處理方法)。
fire: function(type, data){
return document.dispatchEvent(new CustomEvent(type, {
detail: data
}))
}
}
//聲明一個(gè)對(duì)象EventCenter
EventCenter.on('hello', function(e){
console.log(e.detail)
}) //EventCenter.on聽(tīng)到hello時(shí),執(zhí)行后面的方法,輸出當(dāng)前事件的內(nèi)容。
EventCenter.fire('hello', '你好') //這里把事件hello觸發(fā)傳播出來(lái)了
這里的意思我先說(shuō)一下,自己理解的,可能有些野路子啊,剛開(kāi)始聲明了對(duì)象嘛,對(duì)象里內(nèi)容on里用了addEventListener就明白了,它這部分是最終要聽(tīng)到事件也就是那個(gè)參數(shù)type值,然后要執(zhí)行后面那個(gè)handler代指的方法啊。
對(duì)象里的那個(gè)fire,就是專門(mén)為了聲明事件并如何觸發(fā)事件并傳播到on那里而存在滴。其實(shí)查了資料,對(duì)document.dispatchEvent還是半懂不懂的,記住就是為了聲明并觸發(fā)參數(shù)type這個(gè)事件就行了,至于第二個(gè)參數(shù),感覺(jué)不是釘死的,看自己的需求方法了,這里是'你好',正好也是事件的內(nèi)容的賦值了,正好也是事件觸發(fā)的輸出結(jié)果了哦。
document.dispatchEvent 是document觸發(fā)并傳播的哦,剛開(kāi)始狹隘成fire了,其實(shí)fire只是一個(gè)代指而已。
document.addEventListener 同理,是document偵聽(tīng)事件并執(zhí)行的。
element.dispatchEvent() 等同于完成觸發(fā)并傳播事件了。
new CustomEvent(evt,對(duì)應(yīng)數(shù)據(jù)) 可以聲明一個(gè)事件。
例子:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<style>
.box{
width:300px;
height:100px;
border:1px solid;
}
</style>
</head>
<body>
<div class="box box1">
<input type="text">
</div>
<div class="box box2"></div>
<script>
var EventCenter = {
on: function(type, handler){
document.addEventListener(type, handler)
},
fire: function(type, data){
return document.dispatchEvent(new CustomEvent(type, {
detail: data
}))
}
}
document.querySelector('.box input').oninput =
function(){
EventCenter.fire('box1input',this.value)
}
EventCenter.on('box1input',function(e){
document.querySelector('.box2').innerText=e.detail
})
</script>
</body>
</html>
效果如圖: