iT邦幫忙

2024 iThome 鐵人賽

DAY 20
1

img

圖片來源:梗圖倉庫
已購買,老八愛吃。

本篇藉前篇之小桃元素產生之問題,紀錄有發泡現象之focusinfocusout事件之事件委任應用。

不可思議事件委任 Event delegation

委任一詞於法律之意,即謂當事人約定,一方委託他方處理事務,他方允為處理之契約。而用之於不可思議事件,即委託其他元素監聽事件之發生,並代為處理事件發生後之函式之術。而受委託之其他元素,通常為委託元素之父元素。

以下示例藉前篇之示例改造,以解決新生之小桃毫無反應之問題。
結構如下:

<div class="container">
  <a class="momo" href="##"></a>
  <a class="momo" href="##"></a>
  <a class="momo" href="##"></a>
</div>

操術法如下:

const container = document.querySelector(".container");

function becomeEvil() {
  this.style.backgroundImage = `url("./momo_ya.png")`;
}

function mitte() {
  this.style.backgroundImage = `url("./momo_mitte.png")`;
}

function addMomo() {
  const newMomo = document.createElement("a");
  newMomo.setAttribute("class", "momo");
  newMomo.setAttribute("href", "##");
  container.insertBefore(newMomo, container.lastChild);
}

window.addEventListener("scrollend", addMomo);

container.addEventListener("focus", becomeEvil);
container.addEventListener("blur", mitte);

改造之處註釋如下:
僅選取小桃元素之父元素——容器元素。

const container = document.querySelector(".container");

對於容器元素設定二觀測器,觀測可發生發泡現象之focusinfocusout事件。

container.addEventListener("focusin", becomeEvil);
container.addEventListener("focusout", mitte);

利用focusinfocusout事件之發泡現象,可順利在小桃元素(子元素)受矚時向上至容器元素(父元素)觸發事件。
img

然而展露邪惡面向的元素並非小桃元素,而是容器元素,因此需要更改函式之術式內容:

function becomeEvil(event) {
  event.target.style.backgroundImage = `url("./momo_ya.png")`;
}

function mitte(event) {
  event.target.style.backgroundImage = `url("./momo_mitte.png")`;
}

this更改為事件之target屬性,即可取得真正觸發事件之元素(示例即為小桃元素)。

MDN:
The read-only target property of the Event interface is a reference to the object onto which the event was dispatched.

故將函式之術改為更改event.target之樣式,則可成功使新生之小桃元素顯露邪惡行為。
img

示例處

示例之術式

https://github.com/CReticulata/2024ithome/tree/main/Day20

翻譯

事件委任:event delegation
受矚:focus

相關連結


上一篇
Day 19 - 毫無反應就是個小桃
下一篇
Day 21 - 放冰箱的東西還是會壞掉
系列文
元素不可思議事件簿30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言