国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
直觀的做法
減少重複代碼
利用Event 對象
使用事件冒泡
點擊事件呢?
更多示例
列表
表單
結(jié)論
首頁 web前端 css教學 簡化事件處理程序背後的思考

簡化事件處理程序背後的思考

Apr 21, 2025 am 10:31 AM

The Thinking Behind Simplifying Event Handlers

事件用於響應用戶點擊、鍵盤聚焦鏈接以及更改表單文本等操作。剛開始學習JavaScript 時,我編寫了複雜的事件監(jiān)聽器。最近,我學習瞭如何減少代碼量和監(jiān)聽器數(shù)量。

讓我們從一個簡單的例子開始:幾個可拖動的方塊。我們想向用戶顯示他們拖動的彩色方塊。

<div draggable="true">
    R
  </div>
  <div draggable="true">
    Y
  </div>
  <div draggable="true">
    G
  </div>
<p>拖動一個方塊</p>

直觀的做法

剛開始學習JavaScript 事件時,我為每個元素編寫了單獨的事件監(jiān)聽器函數(shù)。這是一個常見的模式,因為它是最簡單的入門方法。我們希望每個元素都有特定的行為,因此可以使用每個元素的特定代碼。

 document.querySelector('#red').addEventListener('dragstart', evt => {
  document.querySelector('#dragged').textContent = 'Dragged red';
});

document.querySelector('#yellow').addEventListener('dragstart', evt => {
  document.querySelector('#dragged').textContent = 'Dragged yellow';
});

document.querySelector('#green').addEventListener('dragstart', evt => {
  document.querySelector('#dragged').textContent = 'Dragged green';
});

減少重複代碼

該示例中的事件監(jiān)聽器非常相似:每個函數(shù)都顯示一些文本。此重複代碼可以折疊到一個輔助函數(shù)中。

 function preview(color) {
  document.querySelector('#dragged').textContent = `Dragged ${color}`;
}

document
  .querySelector('#red')
  .addEventListener('dragstart', evt => preview('red'));
document
  .querySelector('#yellow')
  .addEventListener('dragstart', evt => preview('yellow'));
document
  .querySelector('#green')
  .addEventListener('dragstart', evt => preview('green'));

這樣更簡潔,但仍然需要多個函數(shù)和事件監(jiān)聽器。

利用Event 對象

Event 對像是簡化監(jiān)聽器的關(guān)鍵。調(diào)用事件監(jiān)聽器時,它還會將Event 對像作為第一個參數(shù)發(fā)送。此對象包含一些數(shù)據(jù)來描述發(fā)生的事件,例如事件發(fā)生的時間。為了簡化我們的代碼,我們可以使用evt.currentTarget屬性,其中currentTarget指的是附加事件監(jiān)聽器的元素。在我們的示例中,它將是三個彩色方塊之一。

 const preview = evt => {
  const color = evt.currentTarget.id;
  document.querySelector('#dragged').textContent = `Dragged ${color}`;
};

document.querySelector('#red').addEventListener('dragstart', preview);
document.querySelector('#yellow').addEventListener('dragstart', preview);
document.querySelector('#green').addEventListener('dragstart', preview);

現(xiàn)在只有一個函數(shù)而不是四個函數(shù)了。我們可以將完全相同的函數(shù)作為事件監(jiān)聽器重用,而evt.currentTarget.id將根據(jù)觸發(fā)事件的元素具有不同的值。

使用事件冒泡

最後一個更改是減少代碼中的行數(shù)。與其將事件監(jiān)聽器附加到每個方塊,不如將單個事件監(jiān)聽器附加到包含所有彩色方塊的元素。

事件在觸發(fā)時從事件起源的元素(其中一個方塊)開始。但是,它不會就此停止。瀏覽器會轉(zhuǎn)到該元素的每個父元素,並調(diào)用其上的任何事件監(jiān)聽器。這將持續(xù)到文檔的根元素(HTML 中的標籤)。此過程稱為“冒泡”,因為事件像氣泡一樣上升到文檔樹中。將事件監(jiān)聽器附加到section 元素將導致焦點事件從被拖動的彩色方塊冒泡到父元素。我們還可以利用evt.target屬性,該屬性包含觸發(fā)事件的元素(其中一個方塊),而不是附加事件監(jiān)聽器的元素( section元素)。

 const preview = evt => {
  const color = evt.target.id;
  document.querySelector('#dragged').textContent = `Dragged ${color}`;
};

document.querySelector('section').addEventListener('dragstart', preview);

現(xiàn)在我們已經(jīng)將許多事件監(jiān)聽器減少到只有一個了!對於更複雜的代碼,效果會更好。通過利用Event 對象和冒泡,我們可以控制JavaScript 事件並簡化事件處理程序的代碼。

點擊事件呢?

evt.targetdragstartchange等事件非常有效,在這些事件中,只有少量元素可以接收焦點或更改輸入。

但是,我們通常希望監(jiān)聽點擊事件,以便我們可以響應用戶點擊應用程序中的按鈕。點擊事件會針對文檔中的任何元素觸發(fā),從大型div 到小型span。

讓我們將我們的可拖動彩色方塊改為可點擊的。

<div draggable="true">
    R
  </div>
  <div draggable="true">
    Y
  </div>
  <div draggable="true">
    G
  </div>
<p>點擊一個方塊</p>
const preview = evt => {
  const color = evt.target.id;
  document.querySelector('#clicked').textContent = `Clicked ${color}`;
};

document.querySelector('section').addEventListener('click', preview);

在測試此代碼時,請注意,有時不會附加到“Clicked”,而不是點擊方塊時。它不起作用的原因是每個方塊都包含一個可以點擊的<span></span>元素,而不是可拖動的<div>元素。由於span 沒有設置ID,因此<code>evt.target.id屬性為空字符串。我們只關(guān)心代碼中的彩色方塊。如果我們在方塊內(nèi)某處點擊,我們需要找到父方塊元素。我們可以使用element.closest()來查找最接近被點擊元素的父元素。

 const preview = evt => {
  const element = evt.target.closest('div[draggable]');
  if (element != null) {
    const color = element.id;
    document.querySelector('#clicked').textContent = `Clicked ${color}`;
  }
};

現(xiàn)在我們可以對點擊事件使用單個監(jiān)聽器了!如果element.closest()返回null,則表示用戶在彩色方塊之外的某處點擊,我們應該忽略該事件。

更多示例

以下是一些其他示例,用於演示如何利用單個事件監(jiān)聽器。

列表

一個常見的模式是擁有一個可以交互的項目列表,其中新的項目是使用JavaScript 動態(tài)插入的。如果我們?yōu)槊總€項目附加事件監(jiān)聽器,那麼每次生成新元素時,代碼都必須處理事件監(jiān)聽器。

<div id="buttons-container"></div>
<button id="add">添加新按鈕</button>
let buttonCounter = 0;
document.querySelector('#add').addEventListener('click', evt => {
  const newButton = document.createElement('button');
  newButton.textContent = buttonCounter;

  // 每次點擊“添加新按鈕”時創(chuàng)建一個新的事件監(jiān)聽器newButton.addEventListener('click', evt => {

    // 點擊時,記錄被點擊按鈕的編號。
    document.querySelector('#clicked').textContent = `Clicked button #${newButton.textContent}`;
  });

  buttonCounter ;

  const container = document.querySelector('#buttons-container');
  container.appendChild(newButton);
});

通過利用冒泡,我們可以在容器上使用單個事件監(jiān)聽器。如果我們在應用程序中創(chuàng)建許多元素,這會將監(jiān)聽器的數(shù)量從n 減少到兩個。

 let buttonCounter = 0;
const container = document.querySelector('#buttons-container');
document.querySelector('#add').addEventListener('click', evt => {
  const newButton = document.createElement('button');
  newButton.dataset.number = buttonCounter;
  buttonCounter ;

  container.appendChild(newButton);
});
container.addEventListener('click', evt => {
  const clickedButton = evt.target.closest('button');
  if (clickedButton != null) {
    // 點擊時,記錄被點擊按鈕的編號。
    document.querySelector('#clicked').textContent = `Clicked button #${clickedButton.dataset.number}`;
  }
});

表單

也許有一個包含許多輸入的表單,我們想將所有用戶響應收集到單個對像中。





let responses = {
  name: '',
  email: '',
  password: ''
};

document
  .querySelector('input[name="name"]')
  .addEventListener('change', evt => {
    const inputElement = document.querySelector('input[name="name"]');
    responses.name = inputElement.value;
    document.querySelector('#preview').textContent = JSON.stringify(responses);
  });
document
  .querySelector('input[name="email"]')
  .addEventListener('change', evt => {
    const inputElement = document.querySelector('input[name="email"]');
    responses.email = inputElement.value;
    document.querySelector('#preview').textContent = JSON.stringify(responses);
  });
document
  .querySelector('input[name="password"]')
  .addEventListener('change', evt => {
    const inputElement = document.querySelector('input[name="password"]');
    responses.password = inputElement.value;
    document.querySelector('#preview').textContent = JSON.stringify(responses);
  });

讓我們改用父<form></form>元素上的單個監(jiān)聽器。

 let responses = {
  name: '',
  email: '',
  password: ''
};

document.querySelector('form').addEventListener('change', evt => {
  responses[evt.target.name] = evt.target.value;
  document.querySelector('#preview').textContent = JSON.stringify(responses);
});

結(jié)論

現(xiàn)在我們知道如何利用事件冒泡和事件對象將復雜的事件處理程序混亂簡化為幾個……有時甚至減少到一個!希望本文能幫助您從新的角度思考事件處理程序。我知道在我早期的開發(fā)生涯中花費大量時間編寫重複的代碼來完成同樣的事情之後,這對我來說是一個啟示。

以上是簡化事件處理程序背後的思考的詳細內(nèi)容。更多資訊請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願投稿,版權(quán)歸原作者所有。本站不承擔相應的法律責任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請聯(lián)絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

什麼是'渲染障礙CSS”? 什麼是'渲染障礙CSS”? Jun 24, 2025 am 12:42 AM

CSS會阻塞頁面渲染是因為瀏覽器默認將內(nèi)聯(lián)和外部CSS視為關(guān)鍵資源,尤其是使用引入的樣式表、頭部大量內(nèi)聯(lián)CSS以及未優(yōu)化的媒體查詢樣式。 1.提取關(guān)鍵CSS並內(nèi)嵌至HTML;2.延遲加載非關(guān)鍵CSS通過JavaScript;3.使用media屬性優(yōu)化加載如打印樣式;4.壓縮合併CSS減少請求。建議使用工具提取關(guān)鍵CSS,結(jié)合rel="preload"異步加載,合理使用media延遲加載,避免過度拆分與復雜腳本控制。

什麼是AutoPrefixer,它如何工作? 什麼是AutoPrefixer,它如何工作? Jul 02, 2025 am 01:15 AM

Autoprefixer是一個根據(jù)目標瀏覽器範圍自動為CSS屬性添加廠商前綴的工具。 1.它解決了手動維護前綴易出錯的問題;2.通過PostCSS插件形式工作,解析CSS、分析需加前綴的屬性、依配置生成代碼;3.使用步驟包括安裝插件、設置browserslist、在構(gòu)建流程中啟用;4.注意事項有不手動加前綴、保持配置更新、非所有屬性都加前綴、建議配合預處理器使用。

什麼是圓錐級函數(shù)? 什麼是圓錐級函數(shù)? Jul 01, 2025 am 01:16 AM

theconic-Gradient()functionIncsscreatesCircularGradientsThatRotateColorStopSaroundAcentralPoint.1.IsidealForPieCharts,ProgressIndicators,colordichers,colorwheels和decorativeBackgrounds.2.itworksbysbysbysbydefindefingincolordefingincolorstopsatspecificains off.

CSS教程,用於創(chuàng)建粘性標頭或頁腳 CSS教程,用於創(chuàng)建粘性標頭或頁腳 Jul 02, 2025 am 01:04 AM

TocreatestickyheadersandfooterswithCSS,useposition:stickyforheaderswithtopvalueandz-index,ensuringparentcontainersdon’trestrictit.1.Forstickyheaders:setposition:sticky,top:0,z-index,andbackgroundcolor.2.Forstickyfooters,betteruseposition:fixedwithbot

CSS自定義屬性的範圍是什麼? CSS自定義屬性的範圍是什麼? Jun 25, 2025 am 12:16 AM

CSS自定義屬性的作用域取決於其聲明的上下文,全局變量通常定義在:root中,而局部變量則定義在特定選擇器內(nèi),以便組件化和隔離樣式。例如,定義在.card類中的變量僅對匹配該類的元素及其子元素可用。最佳實踐包括:1.使用:root定義全局變量如主題色;2.在組件內(nèi)部定義局部變量以實現(xiàn)封裝;3.避免重複聲明同一變量;4.注意選擇器特異性可能引發(fā)的覆蓋問題。此外,CSS變量區(qū)分大小寫,且應在使用前定義以避免錯誤。若變量未定義或引用失敗,則會採用回退值或默認值initial。調(diào)試時可通過瀏覽器開發(fā)者工

CSS網(wǎng)格中的FR單元是什麼? CSS網(wǎng)格中的FR單元是什麼? Jun 22, 2025 am 12:46 AM

ThefrunitinCSSGriddistributesavailablespaceproportionally.1.Itworksbydividingspacebasedonthesumoffrvalues,e.g.,1fr2frgivesone-thirdandtwo-thirds.2.Itenablesflexiblelayouts,avoidsmanualcalculations,andsupportsresponsivedesign.3.Commonusesincludeequal-

CSS教程專注於移動優(yōu)先設計 CSS教程專注於移動優(yōu)先設計 Jul 02, 2025 am 12:52 AM

Mobile-firstCSSdesignrequiressettingtheviewportmetatag,usingrelativeunits,stylingfromsmallscreensup,optimizingtypographyandtouchtargets.First,addtocontrolscaling.Second,use%,em,orreminsteadofpixelsforflexiblelayouts.Third,writebasestylesformobile,the

您可以在CSS網(wǎng)格項目中嵌套Flexbox容器嗎? 您可以在CSS網(wǎng)格項目中嵌套Flexbox容器嗎? Jun 22, 2025 am 12:40 AM

是的,可以在CSSGrid項中使用Flexbox。具體做法是先用Grid劃分頁面結(jié)構(gòu),在某個Grid單元格內(nèi)設置子容器為Flex容器,以實現(xiàn)更精細的對齊和排列;例如,在HTML中嵌套一個帶有display:flex樣式的div;這樣做的好處包括分層佈局、響應式設計更容易、組件化開發(fā)更友好;需要注意display屬性僅影響直接子元素、避免過度嵌套、考慮舊版瀏覽器兼容性問題。

See all articles