DOM 0 知識點
<script>
function print(){
console.log(1)
}
X.onclick = print; //是對的
Y.onclick = print();
Z.onclick = print.call();
</script>
<button id='X' onclick='print'>A</button>
<button id='Y' onclick='print()'>B</button> //是對的
<button id='Z' onclick='print.call()'>C</button> //是對的
HTML 中onclick = '要實行的代碼'
,一旦用戶點擊,閱讀就eval(‘要實行的代碼’),這裏不是屬性,不是函數,是一段代碼。
JavaScript 中,一旦用戶點擊,閱讀器就實行X.onclick.call(X,{})
,意義是onclick
是一個函數屬性,而print
是一個屬性,由於它的範例是對象;但下面的print()
的範例是undefined
。
所以在HTML 中必需通報一個要實行的代碼,JavaScript 中必需通報一個函數
DOM 2 知識點
<button id='xxx'>A<button>
xxx.addEventListener('click',function(){
console.log(1)
})
xxx.onclick = function(){
console.log(2)
}
那它們兩個的區別是啥呢?xxx.onclick = function(){}
只是一個屬性,所以它是唯一的,假如這時刻你要綁定2個onclick
事宜就麻煩了。xxx.addEventListener()
它是一個行列,先進先出,就是說先綁定的先觸發。所以它叫做事宜監聽行列,這裡是列隊,xxx
具有一個行列叫做eventlisteners
,你不能直接接見它,但你能夠經由過程addEventListener
去排個隊,假如用戶點擊了,就先觸發排在第一位的函數,排在背面的一次觸發。行列的本質是數組。既然有入隊,那是不是也有出隊:
function f1(){
console.log(1);
}
function f2(){
console.log(2);
}
function f1(){
console.log(3);
}
xxx.addEventListener('click',f1);
xxx.addEventListener('click',f2);
xxx.removeEventListener('click',f1);
xxx.addEventListener('click',f3);
xxx.removeEventListener('click',f3);
末了的效果就是打印:2。
f1 在列隊的過程當中移除了,f3 剛進入行列就移除了。
前面寫輪播的時刻用了one
事宜,它內部是如何的呢?
function f1(){
console.log(1);
xxx.removeEventListener('click',f1);
}
xxx.addEventListener('click',f1);
one
在函數處置懲罰時的末了一句加上脫離行列語句,on
就是沒有出隊這句的,也就是說一向會實行。
JS事宜中的冒泡和捕捉
捕捉事宜:事宜從最外層父元素到最裡層子元素的遞次觸發,叫做捕捉事宜,果document > html > body > div > p > button
冒泡事宜:恰好和捕捉事宜相反,事宜從最裡層子元素到最外層父元素的遞次觸發,叫做冒泡事宜,如:button > p > div > body > html > document
DOM 2 中劃定了同時支撐捕捉事宜和冒泡事宜,用addEventListener()
要領綁定一個事宜處置懲罰函數,其語法:target.addEventListener(type, listener, useCapture);
type
:示意監聽事宜範例的字符串,如clcik
,前面沒有on
listener
:示意監聽的對象或許一個函數useCapture
:示意是不是運用捕捉,接收一個布爾值,true
是觸發捕捉事宜,不寫默許false
觸發用冒泡事宜。
事宜在默許實行的過程當中是先捕捉后冒泡,第三個參數只是讓它在什麼狀態下觸發。假如一個節點捕捉和冒泡事宜同時存在,誰在前誰先實行,和事宜無關。
<div id="s1">s1
<div id="s2">s2</div>
</div>
<script>
s1.addEventListener("click",function(e){
console.log("s1 冒泡事宜"); //4️⃣
},false);
s2.addEventListener("click",function(e){
console.log("s2 冒泡事宜"); //2️⃣
},false);
s1.addEventListener("click",function(e){
console.log("s1 捕捉事宜"); //1️⃣
},true);
s2.addEventListener("click",function(e){
console.log("s2 捕捉事宜"); //3️⃣
},true);
</script>
當我點擊在s2
上面,觸發遞次是s1捕捉事宜
> s2冒泡事宜
> s2捕捉事宜
> s1冒泡事宜
事宜代辦:事宜會在冒泡階段向上流傳到父節點,因而能夠把子節點的監聽函數定義在父節點上,由父節點的監聽函數一致處置懲罰多個子元素的事宜。這類要領叫做事宜的代辦(delegation)。
<ul id="colors">
<li>red</li>
<li>yellow</li>
<li>blue</li>
<li>green</li>
<li>black</li>
<li>white</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (event) {
if (event.target.tagName.toLowerCase() === 'li') {
// some code
}
});
</script>
來看一個詳細例子:獵取li
內里的文本,用事宜流要領
var ul = document.querySelector('ul');
ul.addEventListener('click',showColor,false);
function showColor(e){
var x = e.target;
if(x.nodeName.toLowerCase() === 'li'){
console.log('The color is ' + x.innerHTML);
}
}
假如不運用事宜代辦,要獵取li
內里的文本應當怎麼弄呢?老要領是獵取到一切子元素li
,遍歷它就能夠了
var colors = color-list.children
for(var i=0;i<colors.length;i++){
colors[i].addEventListener('click',showColor,false);
};
function showColor(e){
var x = e.target;
console.log("The color is " + x.innerHTML);
};
阻撓事宜不再流傳,能夠運用事宜對象的stopPropagation()
要領,但不會徹底消除事宜,假如說綁定多個事宜的話。
用stopImmediatePropagation()
要領,綁定的其他事宜也將不會實行。