前端JavaScript-嵌套事件

點擊

如果在多層嵌套中,對每層都設置事件監視器,試試看

<!DOCTYPE html>
<html lang="cn">
<body><div id="container"><button>點我!</button></div><pre id="output"></pre><script src="button.js"></script>"
</body>
</html>
const output = document.querySelector("#output");
const container = document.querySelector("#container");
const button = document.querySelector("button");function handleClick(e) {output.textContent += `你在 ${e.currentTarget.tagName} 元素上進行了點擊\n`;
}document.body.addEventListener("click", handleClick);
container.addEventListener("click", handleClick);
button.addEventListener("click", handleClick);

在 JS 腳本中先用 querySelector (querySelector是JS原生提供的DOM元素查找函數,是DOM API中的一部分,它的作用是通過 CSS選擇器 定位匹配的第一個元素)來確定了 output 和 container 位置并賦值給變量

(CSS選擇器通過特定語法匹配HTML元素并應用樣式,通過 .class 、 #id ,將其應用到JS里面來提取元素的好處就是不用更改語法)

接著設置了自定義函數 handleClick(e) ,參數e是一個事件對象(Event object),這是瀏覽器自動傳遞給事件處理函數的一個參數,比如?button.addEventListener("click", handleClick); 這告訴了如果點擊了button那么就調用 handleClick,這時會自動生成一個事件對象,其中 e.currentTarget 就是監聽對象 button ,而 e.currentTarget.tagName 就是 事件監聽器對象元素的標簽名

這個事件并不是通過 alert 實現輸出,而是直接更改 DOM元素output 的值,這會在點擊后直接顯示

你在 BUTTON 元素上進行了點擊
你在 DIV 元素上進行了點擊
你在 BODY 元素上進行了點擊

可以看到三層元素都觸發了單擊事件

可以觀察到

? ? ? ? 最先觸發的是按鈕的

? ? ? ? 然后是其父元素...

可以理解為:事件從點擊的最里層的元素冒泡而出

.target 和 .currentTarget 有什么區別

event.target 和 event.currentTarget 都指向DOM元素,但是

? ? ? ? event.target 指向的是觸發事件的元素,在冒泡過程中是保持不變的

? ? ? ? event.currentTarget 指向的是事件處理程序當前附加到的元素,也就是當前處理層的元素

注冊而非輪詢

也許你會好奇,為什么我都沒有加 while ,我一旦觸發事件還是會有相應的結果呢?

其實事件監視器是被動的、稱為“事件驅動程序”的模式

在瀏覽器內部有一個事件循環機制,它會不斷地持續檢查隊列中是否有事件要處理

異步處理:當用戶觸發事件時,瀏覽器會將這個事件放入事件隊列,事件循環一旦檢測到隊列中有事件就會用相應的事件處理(異步處理是一種編程和系統設計模式,其核心在于非阻塞執行,在發起耗時操作,如IO、網絡請求等后,程序不會等待操作完成,而是繼續執行后續任務,等操作完成再回調

(不阻塞:不會阻塞主線程或消耗CPU資源來主動檢查事件是否發生,只有事件觸發時相關代碼才會執行)

在線程、線程池、異步-CSDN博客有更詳細說明

隱藏

我們想要實現隱藏視頻,只有在點擊按鈕的時候才顯現,這時候點擊視頻會開始播放,點擊除視頻外的地方會隱藏視頻

<button>顯示視頻</button><div class="hidden"><video><source src="/shared-assets/videos/flower.webm" type="video/webm" /><p>你的瀏覽器不支持 HTML 視頻,這里有視頻的<a href="rabbit320.mp4">替代鏈接</a>。</p></video>
</div>
const btn = document.querySelector("button");
const box = document.querySelector("div");
const video = document.querySelector("video");btn.addEventListener("click", () => box.classList.remove("hidden"));
video.addEventListener("click", () => video.play());
box.addEventListener("click", () => box.classList.add("hidden"));

在 JS 里面添加了三個 'click' 事件處理器

classList 是 DOM 元素對象的一個屬性,提供了一個便捷的方式來操作元素的類(class屬性),它是 DOMTokenList 類型的對象,用于添加、刪除、檢查和切換 CSS 類

button 的點擊處理器會通過?box 的 classList 移除 div 的 "hidden" 類

在運行的時候會發現點擊按鈕的時候會顯示視頻,但是點擊視頻的時候盒子又被隱藏了,這是因為 video 在 div 里面,所以點擊視頻會觸發 video 的事件,也會觸發 div 的事件

這時候我們就想要阻止 video 向外界的感染,需要通過 stopPropagation( ) 方法

const btn = document.querySelector("button");
const box = document.querySelector("div");
const video = document.querySelector("video");btn.addEventListener("click", () => box.classList.remove("hidden"));video.addEventListener("click", (event) => {event.stopPropagation();video.play();
});box.addEventListener("click", () => box.classList.add("hidden"));

可以看到我們在 video 的事件里面添加了 event.stopPropagation();

事件捕捉

跟冒泡順序相反,從最外層到最里面,想實現這樣的操作只需要將 capture 參數設置為 true

比如剛開始的按鈕例子

document.body.addEventListener("click", handleClick, { capture: true });
container.addEventListener("click", handleClick, { capture: true });
button.addEventListener("click", handleClick);

順序就發生了顛倒

你在 BODY 元素上進行了點擊
你在 DIV 元素上進行了點擊
你在 BUTTON 元素上進行了點擊

事件委托

默認冒泡的話,我們可以通過子元素感染父元素,而不用一個個設置了,不直接在子元素上設置監聽器,而是將監聽器設置在父元素上,通過冒泡讓父元素監聽來自子元素的事件,

<!DOCTYPE html>
<html lang="en"></html>
<body><link href="button.css" rel="stylesheet" type="text/css"><div id="container"><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div><div class="tile"></div></div><script src="button.js"></script>"
</body>
</html>
.tile {height: 100px;width: 25%;float: left;
}
function random(number) {return Math.floor(Math.random() * number);
}function bgChange() {const rndCol = `rgb(${random(255)}, ${random(255)}, ${random(255)})`;return rndCol;
}const container = document.querySelector("#container");container.addEventListener("click", (event) => {event.target.style.backgroundColor = bgChange();
});

在這個例子中有很多 .title 元素在 #container 內

但是沒有對每個元素添加事件監聽器

而是在父元素 #container 上加了監聽器,通過 event.target 來確定是哪個子元素觸發了事件,并更改其 style.backgroundColor?為 bgChange

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906462.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906462.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906462.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網感驅動下開源AI大模型AI智能名片S2B2C商城小程序源碼的實踐路徑研究

摘要&#xff1a;在數字化浪潮中&#xff0c;網感已成為內容創作者與商業運營者必備的核心能力。本文以開源AI大模型、AI智能名片及S2B2C商城小程序源碼為技術載體&#xff0c;通過解析網感培養與用戶需求洞察的內在關聯&#xff0c;提出"數據驅動-場景適配-價值重構"…

AG-UI:重構AI代理與前端交互的下一代協議標準

目錄 技術演進背景與核心價值協議架構與技術原理深度解析核心功能與標準化事件體系典型應用場景與實戰案例開發者生態與集成指南行業影響與未來展望1. 技術演進背景與核心價值 1.1 AI交互的三大痛點 當前AI應用生態面臨三大核心挑戰: 交互碎片化:LangGraph、CrewAI等框架各…

游戲引擎學習第301天:使用精靈邊界進行排序

回顧并為今天的內容做準備 昨天&#xff0c;我們解決了一些關于排序的問題&#xff0c;這對我們清理長期存在的Z軸排序問題很有幫助。這個問題我們一直想在開始常規游戲代碼之前解決。雖然不確定是否完全解決了問題&#xff0c;但我們提出了一個看起來合理的排序標準。 有兩點…

Ajax快速入門教程

輸入java時&#xff0c;頁面并沒有刷新但是下面自動聯想出了跟java有關的東西&#xff0c;像這種就叫異步交互 它不會妨礙你的輸入&#xff0c;同時還能夠同步進行對于java相關聯想詞的推送 發送異步請求需要借助工具axios 引入axios&#xff0c;可以直接在scripts中引入 get和…

Anti Spy安卓版:智能防護,守護手機安全

Anti Spy安卓版是一款專為安卓設備設計的智能防護應用&#xff0c;旨在幫助用戶實時防護手機安全&#xff0c;抵御間諜軟件、惡意軟件和其他潛在威脅。它基于人工智能和啟發式搜索方法的引擎&#xff0c;能夠檢測并阻止已知和未知的間諜軟件、后門程序、賬單欺詐、短信欺詐、電…

超低延遲音視頻直播技術的未來發展與創新

引言 音視頻直播技術正在深刻改變著我們的生活和工作方式&#xff0c;尤其是在教育、醫療、安防、娛樂等行業。無論是全球性的體育賽事、遠程醫療、在線教育&#xff0c;還是智慧安防、智能家居等應用場景&#xff0c;都離不開音視頻技術的支持。為了應對越來越高的需求&#x…

系統架構設計(十二):統一過程模型(RUP)

簡介 RUP 是由 IBM Rational 公司提出的一種 面向對象的軟件工程過程模型&#xff0c;以 UML 為建模語言&#xff0c;是一種 以用例為驅動、以架構為中心、迭代式、增量開發的過程模型。 三大特征 特征說明以用例為驅動&#xff08;Use Case Driven&#xff09;需求分析和測…

海康相機連接測試-極簡版

文章目錄 1、下載客戶端 1、下載客戶端 海康機器人官網下載軟件 軟件下載地址 先下載客戶端測試連接 按照你的相機的類型選擇客戶端 安裝完畢后&#xff0c;確保USB線插的是3.0的端口 軟件會自動識別相機型號 在上方有播放按鈕&#xff0c;可以采集圖像信息顯示

Linux 磁盤擴容實戰案例:從問題發現到完美解決

Linux 磁盤擴容實戰案例&#xff1a;從問題發現到完美解決 案例背景 某企業服務器根目錄 (/) 空間不足&#xff0c;運維人員通過 df -h 發現 /dev/vda1 分區已 100% 占滿&#xff08;99G 已用&#xff09;。檢查發現物理磁盤 /dev/vda 已擴展至 200G&#xff0c;但分區和文件…

深入解析FramePack:高效視頻幀打包技術原理與實踐

摘要 本文深入探討FramePack技術在視頻處理領域的核心原理&#xff0c;解析其在不同場景下的應用優勢&#xff0c;并通過OpenCV代碼示例演示具體實現方法&#xff0c;為開發者提供可落地的技術解決方案。 目錄 1. FramePack技術背景 2. 核心工作原理剖析 3. 典型應用場景 …

RVTools 官網遭入侵,被用于分發攜帶 Bumblebee 惡意軟件的篡改安裝包

VMware 環境報告工具 RVTools 的官方網站遭黑客入侵&#xff0c;其安裝程序被植入惡意代碼。安全研究人員 Aidan Leon 發現&#xff0c;從該網站下載的受感染安裝程序會側加載一個惡意 DLL 文件&#xff0c;經確認是已知的 Bumblebee 惡意軟件加載器。 官方回應與風險提示 RV…

mysql故障排查與環境優化

一、mysql運行原理 mysql的運行分為三層 客戶端和連接服務 核心服務功能&#xff08;sql接口、緩存的查詢、sql的分析和優化以及部分內置函數的執行等。&#xff09; 存儲引擎層&#xff08;負責mysql中數據的存儲和提取。&#xff09; 二、示例 1、實驗環…

Codex與LangChain結合的智能代理架構:重塑軟件開發的未來

??「炎碼工坊」技術彈藥已裝填! 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 引言:當代碼生成遇見智能決策 想象以下場景: 凌晨三點:你需要緊急修復一個遺留系統的內存泄漏漏洞,但代碼注釋缺失且邏輯復雜; 產品經理需求變更:要求在24小時內將現有…

【開源Agent框架】CAMEL:角色扮演+任務分解

一、項目概覽:重新定義智能體協作范式 CAMEL(Communicative Agents for “Mind” Exploration of Large Language Model Society)是由camel-ai社區開發的開源多智能體框架,致力于探索智能體的規模法則(Scaling Laws)。該項目通過構建包含百萬級智能體的復雜社會系統,研…

第32節:基于ImageNet預訓練模型的遷移學習與微調

1. 引言 在深度學習領域,遷移學習(Transfer Learning)已經成為解決計算機視覺任務的重要方法,特別是在數據量有限的情況下。其中,基于ImageNet數據集預訓練的模型因其強大的特征提取能力而被廣泛應用于各種視覺任務。本文將詳細介紹遷移學習的概念、ImageNet預訓練模型的特…

celery獨立部署接入數據庫配置

目錄結構&#xff1a; config下配置&#xff1a; __init__: import os import sys sys.path.append(os.getcwd()) from celery import CeleryappCelery(celeryTester) # 創建一個Celery實例&#xff0c;名字自定義 app.config_from_object(config.celery_config) # 從celery_…

攻防世界-題目名稱-文件包含

進入環境 看到 include()&#xff0c;想到文件包含&#xff0c;用php偽協議 /?filenamephp://filter/readconvert.base64-encode/resourceflag.php do not hack!猜測可能是黑名單檢測的敏感字符 輸入單個字符串/?filenamebase64 還是顯示do not hack&#xff01; 構造payl…

MySQL高頻面試八連問(附場景化解析)

文章目錄 "為什么訂單查詢突然變慢了&#xff1f;"——從這個問題開始說起一、索引的生死時速&#xff08;必考題&#xff01;&#xff09;二、事務的"套娃"藝術三、鎖機制的相愛相殺四、存儲引擎的抉擇五、慢查詢的破案技巧六、分頁的深度優化七、高可用架…

Android 中 自定義生成的 APK/AAR 文件名稱

在 Kotlin DSL 中&#xff0c;可以通過配置 build.gradle.kts 文件來自定義生成的 APK 或 AAR 文件名稱。 1、自定義 APK 名稱 在模塊的 build.gradle.kts 中通過修改 applicationVariants.all 配置來實現。 android {......applicationVariants.all {outputs.all {val df …

《從零開始:Spring Cloud Eureka 配置與服務注冊全流程》?

關于Eureka的學習&#xff0c;主要學習如何搭建Eureka&#xff0c;將order-service和product-service都注冊到Eureka。 1.為什么使用Eureka? 我在實現一個查詢訂單功能時&#xff0c;希望可以根據訂單中productId去獲取對應商品的詳細信息&#xff0c;但是產品服務和訂單服…