宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見(jiàn)問(wèn)題
產(chǎn)品動(dòng)態(tài)
精選推薦

使用事件代理提升 Web 應(yīng)用性能

管理 管理 編輯 刪除

前言

在構(gòu)建現(xiàn)代 Web 應(yīng)用時(shí),我們經(jīng)常需要處理大量數(shù)據(jù),并將其渲染為列表或表格,對(duì)每個(gè)數(shù)據(jù)項(xiàng)綁定一個(gè)事件處理程序是常見(jiàn)的做法。但隨著數(shù)據(jù)量的增長(zhǎng),這種做法將會(huì)導(dǎo)致嚴(yán)重的性能問(wèn)題;本文旨在介紹事件代理這一解決方案,幫助開(kāi)發(fā)者優(yōu)化 Web 應(yīng)用性能,提升用戶體驗(yàn)。

常見(jiàn)場(chǎng)景

在構(gòu)建現(xiàn)代 Web 應(yīng)用時(shí),我們會(huì)使用各種現(xiàn)代 Web 框架來(lái)簡(jiǎn)化我們的工作。以 Vue 為例,渲染一個(gè)列表的代碼大致如下:

<template>
    <ul>
        <li v-for="item of someList" :key="item.id" @click="handleItemClick">{{ item.name }}</li>
    </ul>
</template>

<script setup lang="ts">
const someList = [
    ...
];

const handleItemClick = (e: Event) => {
    ...
}

</script>   

someList 中存在多少條數(shù)據(jù),頁(yè)面中便會(huì)存在多少個(gè)事件監(jiān)聽(tīng)處理程序。當(dāng) someList 數(shù)據(jù)量巨大時(shí),大量的事件監(jiān)聽(tīng)器會(huì)占用大量?jī)?nèi)存,并導(dǎo)致嚴(yán)重的性能問(wèn)題。此時(shí)我們可以通過(guò)事件代理,將事件處理代理給父元素。事件代理利用了事件冒泡的機(jī)制,使得只需在父元素上綁定一個(gè)事件監(jiān)聽(tīng)器,即可處理所有子元素的事件,從而大大減少事件監(jiān)聽(tīng)器的數(shù)量,代碼如下:

<template>
    <ul @click="handleListClick">
        <li v-for="item of someList" :key="item.id" :data-id="item.id">{{ item.name }}</li>
    </ul>
</template>

<script setup lang="ts">
const someList = [
    ...
];

const handleListClick= (e: Event) => {
    const { id } = e.target.dataset;
    if (id !== undefined) {
        ...
    }
}

</script>   


通過(guò)將子元素需要的數(shù)據(jù)綁定在 dataset 屬性中,我們可以方便的在事件代理中獲取這些數(shù)據(jù),解決了參數(shù)傳遞的問(wèn)題。然而實(shí)際開(kāi)發(fā)中,列表項(xiàng)遠(yuǎn)比示例中要復(fù)雜得多,可能會(huì)包含多個(gè)圖標(biāo)、按鈕或其他子元素。

此時(shí)我們就需要一種方法來(lái)區(qū)分不同的按鈕;同樣我們可以使用 dataset 屬性,為不同的按鈕設(shè)置不同的 dataset 屬性值,然后在事件處理程序中通過(guò) event.target.dataset 來(lái)判斷哪個(gè)按鈕觸發(fā)了事件,代碼如下;

b7d52202501221038236709.png

<template>
    <ul @click="handleListClick">
        <li v-for="item of someList" :key="item.id">
            <p>文案</p>
            <button :data-id="item.id" data-event="event1">button1</button>
            <button :data-id="item.id" data-event="event2">button2</button>
        </li>
    </ul>
</template>

<script setup lang="ts">

const someList = [
    ...
];

const handleListClick= (e: Event) => {
    const { id, event } = e.target.dataset;
    if (id === undefined || event === undefined) return;
    if (event === "event1") {
        ...
    } else if (event === "event2") {
        ...
    }
}

</script>   


有時(shí),列表子項(xiàng)內(nèi)包含多個(gè)無(wú)需任何事件處理程序的子元素,而數(shù)據(jù)綁定在列表子項(xiàng)的 dataset 屬性上。此時(shí),如果點(diǎn)擊子元素, e.target 指向的是子元素,而非列表元素,無(wú)法直接獲取 dataset。 e.target.closest(selector) 方法可以向上查找匹配選擇器的最近祖先元素,從而解決這個(gè)問(wèn)題,代碼如下:

<template>
    <ul @click="handleListClick">
        <li v-for="item of someList" :key="item.id" :data-uid="item.uid">
            <p>文案</p>
            <img src="../avatar.png" />
        </li>
    </ul>
</template>

<script setup lang="ts">

const someList = [
    ...
];

const handleListClick= (e: Event) => {
    let { uid } = e.target.dataset;
    if (uid === undefined) {
        const listItem = e.target.closest("li")
        if (!listItem) return;
        uid = listItem.dataset.uid;
    }
    
    ....
}

</script>  

結(jié)語(yǔ)

需要注意的是,事件代理并非適用于所有場(chǎng)景,開(kāi)發(fā)者需要針對(duì)具體情況進(jìn)行實(shí)際權(quán)衡。在需要處理大量相似元素的事件時(shí),事件代理無(wú)疑是一種優(yōu)秀的解決方案。本文的代碼示例中以 Vue 框架為示例,但核心思想應(yīng)用在 React 或其他框架上也同樣使用,希望本文能夠幫助開(kāi)發(fā)者更好的使用事件代理,在實(shí)際開(kāi)發(fā)中做出更穩(wěn)妥的選擇。

請(qǐng)登錄后查看

plz 最后編輯于2025-01-22 11:11:24

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點(diǎn)贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無(wú)簡(jiǎn)介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
3623
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見(jiàn)問(wèn)題 產(chǎn)品動(dòng)態(tài) 精選推薦 首頁(yè)頭條 首頁(yè)動(dòng)態(tài) 首頁(yè)推薦
取 消 確 定
回復(fù)
回復(fù)
問(wèn)題:
問(wèn)題自動(dòng)獲取的帖子內(nèi)容,不準(zhǔn)確時(shí)需要手動(dòng)修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請(qǐng)輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊(cè)

切換手機(jī)號(hào)登錄

{{ bind_phone ? '綁定手機(jī)' : '手機(jī)登錄'}}

{{codeText}}
切換微信登錄/注冊(cè)
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開(kāi)源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服