æä»¬ä¸ä» å¯ä»¥åé äºä»¶å¤çç¨åºï¼è¿å¯ä»¥ä» JavaScript çæäºä»¶ã
èªå®ä¹äºä»¶å¯ç¨äºå建âå¾å½¢ç»ä»¶âãä¾å¦ï¼æä»¬èªå·±çåºäº JavaScript çèåçæ ¹å
ç´ å¯è½ä¼è§¦å openï¼æå¼èåï¼ï¼selectï¼æä¸é¡¹è¢«éä¸ï¼çäºä»¶æ¥åè¯èååçäºä»ä¹ãå¦ä¸ä¸ªä»£ç å¯è½ä¼çå¬äºä»¶ï¼å¹¶è§å¯èååçäºä»ä¹ã
æä»¬ä¸ä»
å¯ä»¥çæåºäºèªèº«ç®çèå建çå
¨æ°äºä»¶ï¼è¿å¯ä»¥çæä¾å¦ click å mousedown çå
建äºä»¶ãè¿å¯è½ä¼æå©äºèªå¨åæµè¯ã
äºä»¶æé å¨
å 建äºä»¶ç±»å½¢æä¸ä¸ªå±æ¬¡ç»æï¼hierarchyï¼ï¼ç±»ä¼¼äº DOM å ç´ ç±»ãæ ¹æ¯å 建ç Event ç±»ã
æä»¬å¯ä»¥åè¿æ ·å建 Event 对象ï¼
let event = new Event(type[, options]);
åæ°ï¼
-
type ââ äºä»¶ç±»åï¼å¯ä»¥æ¯åè¿æ ·
"click"çåç¬¦ä¸²ï¼æè æä»¬èªå·±çåè¿æ ·"my-event"çåæ°ã -
options ââ å ·æä¸¤ä¸ªå¯é屿§ç对象ï¼
bubbles: true/falseââ å¦æä¸ºtrueï¼é£ä¹äºä»¶ä¼å泡ãcancelable: true/falseââ å¦æä¸ºtrueï¼é£ä¹âé»è®¤è¡ä¸ºâå°±ä¼è¢«é»æ¢ãç¨åæä»¬ä¼çå°å¯¹äºèªå®ä¹äºä»¶ï¼å®æå³çä»ä¹ã
é»è®¤æ åµä¸ï¼ä»¥ä¸ä¸¤è é½ä¸º falseï¼
{bubbles: false, cancelable: false}ã
dispatchEvent
äºä»¶å¯¹è±¡è¢«å建åï¼æä»¬åºè¯¥ä½¿ç¨ elem.dispatchEvent(event) è°ç¨å¨å
ç´ ä¸âè¿è¡âå®ã
ç¶åï¼å¤çç¨åºä¼å¯¹å®ååºååºï¼å°±å¥½å宿¯ä¸ä¸ªå¸¸è§çæµè§å¨äºä»¶ä¸æ ·ã妿äºä»¶æ¯ç¨ bubbles æ å¿å建çï¼é£ä¹å®ä¼å泡ã
å¨ä¸é¢è¿ä¸ªç¤ºä¾ä¸ï¼click äºä»¶æ¯ç¨ JavaScript åå§åå建çãå¤çç¨åºå·¥ä½æ¹å¼åç¹å»æé®çæ¹å¼ç¸åï¼
<button id="elem" onclick="alert('Click!');">Autoclick</button>
<script>
let event = new Event("click");
elem.dispatchEvent(event);
</script>
æä¸ç§æ¹æ³å¯ä»¥åºåâçå®âç¨æ·äºä»¶åéè¿èæ¬çæçäºä»¶ã
å¯¹äºæ¥èªçå®ç¨æ·æä½çäºä»¶ï¼event.isTrusted 屿§ä¸º trueï¼å¯¹äºèæ¬çæçäºä»¶ï¼event.isTrusted 屿§ä¸º falseã
åæ³¡ç¤ºä¾
æä»¬å¯ä»¥å建ä¸ä¸ªå为 "hello" çåæ³¡äºä»¶ï¼å¹¶å¨ document 䏿è·å®ã
æä»¬éè¦åçå°±æ¯å° bubbles 设置为 trueï¼
<h1 id="elem">Hello from the script!</h1>
<script>
// å¨ document 䏿è·...
document.addEventListener("hello", function(event) { // (1)
alert("Hello from " + event.target.tagName); // Hello from H1
});
// ...å¨ elem ä¸ dispatchï¼
let event = new Event("hello", {bubbles: true}); // (2)
elem.dispatchEvent(event);
// å¨ document ä¸çå¤çç¨åºå°è¢«æ¿æ´»ï¼å¹¶æ¾ç¤ºæ¶æ¯ã
</script>
注æï¼
- æä»¬åºè¯¥å¯¹æä»¬çèªå®ä¹äºä»¶ä½¿ç¨
addEventListenerï¼å 为on<event>ä» åå¨äºå 建äºä»¶ä¸ï¼document.onhelloåæ æ³è¿è¡ã - å¿
须设置
bubbles:trueï¼å¦åäºä»¶ä¸ä¼åä¸å泡ã
å
建äºä»¶ï¼clickï¼åèªå®ä¹äºä»¶ï¼helloï¼çåæ³¡æºå¶ç¸åãèªå®ä¹äºä»¶ä¹ææè·é¶æ®µååæ³¡é¶æ®µã
MouseEventï¼KeyboardEvent åå ¶ä»
è¿æ¯ä¸ä¸ªæèªäº UI äºä»¶è§è çä¸ä¸ªç®çç UI äºä»¶ç±»å表ï¼
UIEventFocusEventMouseEventWheelEventKeyboardEvent- â¦
妿æä»¬æ³è¦åå»ºè¿æ ·çäºä»¶ï¼æä»¬åºè¯¥ä½¿ç¨å®ä»¬è䏿¯ new Eventãä¾å¦ï¼new MouseEvent("click")ã
æ£ç¡®çæé å¨å 许为该类åçäºä»¶æå®æ å屿§ã
å°±åé¼ æ äºä»¶ç clientX/clientY 䏿 ·ï¼
let event = new MouseEvent("click", {
bubbles: true,
cancelable: true,
clientX: 100,
clientY: 100
});
alert(event.clientX); // 100
请注æï¼éç¨ç Event æé å¨ä¸å
è®¸è¿æ ·åã
让æä»¬è¯è¯ï¼
let event = new Event("click", {
bubbles: true, // æé å¨ Event ä¸åªæ bubbles å cancelable å¯ä»¥å·¥ä½
cancelable: true,
clientX: 100,
clientY: 100
});
alert(event.clientX); // undefinedï¼æªç¥ç屿§è¢«å¿½ç¥äºï¼
仿æ¯ä¸è®²ï¼æä»¬å¯ä»¥éè¿å¨å建åç´æ¥åé
event.clientX=100 æ¥è§£å³è¿ä¸ªé®é¢ãæä»¥ï¼è¿æ¯ä¸ä¸ªæ¹ä¾¿åéµå®è§åçé®é¢ãæµè§å¨çæçäºä»¶å§ç»å
·ææ£ç¡®çç±»åã
è§è䏿ä¾äºä¸å UI äºä»¶ç屿§ç宿´å表ï¼ä¾å¦ MouseEventã
èªå®ä¹äºä»¶
å¯¹äºæä»¬èªå·±çå
¨æ°äºä»¶ç±»åï¼ä¾å¦ "hello"ï¼æä»¬åºè¯¥ä½¿ç¨ new CustomEventã仿æ¯ä¸è®²ï¼CustomEvent å Event 䏿 ·ãé¤äºä¸ç¹ä¸åã
å¨ç¬¬äºä¸ªåæ°ï¼å¯¹è±¡ï¼ä¸ï¼æä»¬å¯ä»¥ä¸ºæä»¬æ³è¦ä¸äºä»¶ä¸èµ·ä¼ éçä»»ä½èªå®ä¹ä¿¡æ¯æ·»å ä¸ä¸ªéå ç屿§ detailã
ä¾å¦ï¼
<h1 id="elem">Hello for John!</h1>
<script>
// äºä»¶é带ç»å¤çç¨åºçå
¶ä»è¯¦ç»ä¿¡æ¯
elem.addEventListener("hello", function(event) {
alert(event.detail.name);
});
elem.dispatchEvent(new CustomEvent("hello", {
detail: { name: "John" }
}));
</script>
detail 屿§å¯ä»¥æä»»ä½æ°æ®ã仿æ¯ä¸è®²ï¼æä»¬å¯ä»¥ä¸ç¨ï¼å 为æä»¬å¯ä»¥å¨å建åå°ä»»ä½å±æ§åé
ç»å¸¸è§ç new Event 对象ä¸ã使¯ CustomEvent æä¾äºç¹æ®ç detail åæ®µï¼ä»¥é¿å
ä¸å
¶ä»äºä»¶å±æ§çå²çªã
æ¤å¤ï¼äºä»¶ç±»æè¿°äºå®æ¯âä»ä¹ç±»åçäºä»¶âï¼å¦æäºä»¶æ¯èªå®ä¹çï¼é£ä¹æä»¬åºè¯¥ä½¿ç¨ CustomEvent æ¥æç¡®å®æ¯ä»ä¹ã
event.preventDefault()
è®¸å¤æµè§å¨äºä»¶é½æâé»è®¤è¡ä¸ºâï¼ä¾å¦ï¼å¯¼èªå°é¾æ¥ï¼å¼å§ä¸ä¸ªéæ©ï¼çã
å¯¹äºæ°çï¼èªå®ä¹çäºä»¶ï¼ç»å¯¹æ²¡æé»è®¤çæµè§å¨è¡ä¸ºï¼ä½æ¯åæ´¾ï¼dispatchï¼æ¤ç±»äºä»¶ç代ç å¯è½æèªå·±ç计åï¼è§¦å该äºä»¶ä¹ååºè¯¥åä»ä¹ã
éè¿è°ç¨ event.preventDefault()ï¼äºä»¶å¤çç¨åºå¯ä»¥ååºä¸ä¸ªä¿¡å·ï¼æåºè¿äºè¡ä¸ºåºè¯¥è¢«åæ¶ã
å¨è¿ç§æ
åµä¸ï¼elem.dispatchEvent(event) çè°ç¨ä¼è¿å falseãé£ä¹åæ´¾ï¼dispatchï¼è¯¥äºä»¶ç代ç å°±ä¼ç¥éä¸åºè¯¥åç»§ç»ã
让æä»¬çä¸ä¸ªå®é çä¾å ââ ä¸åªéèçå åï¼å¯ä»¥æ¯å ³éèåæè å ¶ä»ï¼ã
å¨ä¸é¢ï¼ä½ å¯ä»¥çå°ä¸ä¸ªå¨å
¶ä¸åæ´¾äº "hide" äºä»¶ç #rabbit å hide() 彿°ï¼ä»¥ä½¿æææå
´è¶£çåæ¹é¢é½ç¥éè¿åªå
åè¦éèèµ·æ¥ã
ä»»ä½å¤çç¨åºé½å¯ä»¥ä½¿ç¨ rabbit.addEventListener('hide',...) æ¥çå¬è¯¥äºä»¶ï¼å¹¶å¨éè¦æ¶ä½¿ç¨ event.preventDefault() æ¥åæ¶è¯¥è¡ä¸ºãç¶åå
åå°±ä¸ä¼èèµ·æ¥äºï¼
<pre id="rabbit">
|\ /|
\|_|/
/. .\
=\_Y_/=
{>o<}
</pre>
<button onclick="hide()">Hide()</button>
<script>
function hide() {
let event = new CustomEvent("hide", {
cancelable: true // 没æè¿ä¸ªæ å¿ï¼preventDefault å°ä¸èµ·ä½ç¨
});
if (!rabbit.dispatchEvent(event)) {
alert('The action was prevented by a handler');
} else {
rabbit.hidden = true;
}
}
rabbit.addEventListener('hide', function(event) {
if (confirm("Call preventDefault?")) {
event.preventDefault();
}
});
</script>
请注æï¼è¯¥äºä»¶å¿
é¡»å
·æ cancelable: true æ å¿ï¼å¦å event.preventDefault() è°ç¨å°ä¼è¢«å¿½ç¥ã
äºä»¶ä¸çäºä»¶æ¯åæ¥ç
é常äºä»¶æ¯å¨éåä¸å¤ççãä¹å°±æ¯è¯´ï¼å¦ææµè§å¨æ£å¨å¤ç onclickï¼è¿æ¶åçäºä¸ä¸ªæ°çäºä»¶ï¼ä¾å¦é¼ æ ç§»å¨äºï¼é£ä¹å®çå¤çç¨åºä¼è¢«æå
¥éåï¼ç¸åºç mousemove å¤çç¨åºå°å¨ onclick äºä»¶å¤ç宿å被è°ç¨ã
å¼å¾æ³¨æçä¾å¤æ
åµå°±æ¯ï¼ä¸ä¸ªäºä»¶æ¯å¨å¦ä¸ä¸ªäºä»¶ä¸åèµ·çãä¾å¦ä½¿ç¨ dispatchEventãè¿ç±»äºä»¶å°ä¼è¢«ç«å³å¤çï¼å³å¨æ°çäºä»¶å¤çç¨åºè¢«è°ç¨ä¹åï¼æ¢å¤å°å½åçäºä»¶å¤çç¨åºã
ä¾å¦ï¼å¨ä¸é¢ç代ç ä¸ï¼menu-open äºä»¶æ¯å¨ onclick äºä»¶æ§è¡è¿ç¨ä¸è¢«è°ç¨çã
å®ä¼è¢«ç«å³æ§è¡ï¼èä¸å¿
çå¾
onclick å¤çç¨åºç»æï¼
<button id="menu">Menu (click me)</button>
<script>
menu.onclick = function() {
alert(1);
menu.dispatchEvent(new CustomEvent("menu-open", {
bubbles: true
}));
alert(2);
};
// å¨ 1 å 2 ä¹é´è§¦å
document.addEventListener('menu-open', () => alert('nested'));
</script>
è¾åºé¡ºåºä¸ºï¼1 â nested â 2ã
请注æï¼åµå¥äºä»¶ menu-open ä¼å¨ document ä¸è¢«æè·ãåµå¥äºä»¶çä¼ æï¼propagationï¼åå¤çå
è¢«å®æï¼ç¶åå¤çè¿ç¨æä¼è¿åå°å¤é¨ä»£ç ï¼onclickï¼ã
è¿ä¸åªæ¯ä¸ dispatchEvent æå
³ï¼è¿æå
¶ä»æ
åµã妿ä¸ä¸ªäºä»¶å¤çç¨åºè°ç¨äºè§¦åå
¶ä»äºä»¶çæ¹æ³ ââ å®ä»¬åæ ·ä¹ä¼è¢«ä»¥åµå¥çæ¹å¼åæ¥å¤çã
ä¸è¿ææ¶åï¼è¿å¹¶ä¸æ¯æä»¬ææçç»æãæä»¬æ³è®© onclick ä¸å menu-open æè
å
¶å®åµå¥äºä»¶çå½±åï¼ä¼å
被å¤ç宿¯ã
é£ä¹ï¼æä»¬å°±å¯ä»¥å° dispatchEventï¼æå¦ä¸ä¸ªè§¦åäºä»¶çè°ç¨ï¼æ¾å¨ onclick æ«å°¾ï¼æè
æå¥½å°å
¶å
è£
å°é¶å»¶è¿ç setTimeout ä¸ï¼
<button id="menu">Menu (click me)</button>
<script>
menu.onclick = function() {
alert(1);
setTimeout(() => menu.dispatchEvent(new CustomEvent("menu-open", {
bubbles: true
})));
alert(2);
};
document.addEventListener('menu-open', () => alert('nested'));
</script>
ç°å¨ï¼dispatchEvent å¨å½åä»£ç æ§è¡å®æä¹å弿¥è¿è¡ï¼å
æ¬ menu.onclickï¼å æ¤ï¼äºä»¶å¤çç¨åºæ¯å®å
¨ç¬ç«çã
è¾åºé¡ºåºåæï¼1 â 2 â nestedã
æ»ç»
è¦ä»ä»£ç çæä¸ä¸ªäºä»¶ï¼æä»¬é¦å éè¦å建ä¸ä¸ªäºä»¶å¯¹è±¡ã
éç¨ç Event(name, options) æé 卿¥åä»»æäºä»¶åç§°åå
·æä¸¤ä¸ªå±æ§ç options 对象ï¼
- 妿äºä»¶åºè¯¥å泡ï¼å
bubbles: trueã - 妿
event.preventDefault()åºè¯¥ææï¼åcancelable: trueã
å
¶ä»å MouseEvent å KeyboardEvent è¿æ ·çåçäºä»¶çæé å¨ï¼é½æ¥åç¹å®äºè¯¥äºä»¶ç±»åç屿§ãä¾å¦ï¼é¼ æ äºä»¶ç clientXã
对äºèªå®ä¹äºä»¶ï¼æä»¬åºè¯¥ä½¿ç¨ CustomEvent æé å¨ã宿ä¸ä¸ªå为 detail çéå éé¡¹ï¼æä»¬åºè¯¥å°äºä»¶ç¹å®çæ°æ®åé
ç»å®ãç¶åï¼ææå¤çç¨åºå¯ä»¥ä»¥ event.detail ç形弿¥è®¿é®å®ã
å°½ç®¡ææ¯ä¸å¯ä»¥çæå click æ keydown è¿æ ·çæµè§å¨äºä»¶ï¼ä½æä»¬è¿æ¯åºè°¨æ
使ç¨å®ä»¬ã
æä»¬ä¸åºè¯¥çææµè§å¨äºä»¶ï¼å ä¸ºè¿æ¯è¿è¡å¤çç¨åºçä¸ç§æªå¼ï¼hackyï¼æ¹å¼ã大夿°æ¶åï¼è¿é½æ¯ç³ç³çæ¶æã
å¯ä»¥çæåçäºä»¶ï¼
- å¦æç¬¬ä¸æ¹ç¨åºåºä¸æä¾å ¶ä»äº¤äºæ¹å¼ï¼é£ä¹è¿æ¯ä½¿ç¬¬ä¸æ¹ç¨åºåºå·¥ä½æéçä¸ç§è®èææ®µã
- 对äºèªå¨åæµè¯ï¼è¦å¨èæ¬ä¸âç¹å»æé®âå¹¶æ¥çæ¥å£æ¯å¦æ£ç¡®ååºã
ä½¿ç¨æä»¬èªå·±çåç§°çèªå®ä¹äºä»¶é常æ¯åºäºæ¶æçç®çèå建çï¼ä»¥æç¤ºåçå¨èåï¼menuï¼ï¼æ»åï¼sliderï¼ï¼è½®æï¼carouselï¼çå é¨åçäºä»ä¹ã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼