關于原生DOM事件綁定傳參的一些事

在如今無論是單向還是雙向綁定的各類V框架中, 我們大多數時候其實不需要用上以前字符串模板拼接的html, 甚至是對于html本身的編寫, 也大部分都是在.vue或是.jsx中了, 即便如此, 在維護一些比較久遠的代碼時, 還是會遇到一些問題, 而今天便是討論下關于傳參的方式

首先html結構為

<ul id="ul"></ul>

對應的有如下需要渲染到ul中的一個數據

let arr = [
  { num: 1, str: '行1', obj: { a: 1, b: 2 }, arr: [1, 2] },
  { num: 2, str: '行2', obj: { a: 2, b: 3 }, arr: [3, 4] },
]

那么如果需要將這個數據渲染出來并且傳入這個數據本身, 對于vue之類的框架而言, 只需要v-for@click直接綁定就可以, 不過對于原生而言, 這種方式其實并不理智, 也不對

原生如果需要直接實現@click(params)的話, 對應的自然也就是綁定在onclick(item)中, 那么實現的方式會是這樣

arr.forEach(item => {
  html += `<li onclick='handle(event, ${JSON.stringify(item)})' >${item.str}</li>`;
})

那么這種方式會有什么問題呢?他會暴露整個對象在html中, 也就是下圖

1.png

所以按我的經驗來說的話, 我會更加建議將參數傳入到data-xxx中, 不過當然也是半斤八兩, 畢竟前端代碼就是給別人看的, 不懂的沒必要偽裝, 懂的也沒辦法偽裝, 我這里的經驗更多的是應對于后續維護調試, 可以排除大量不需要的屬性, 定位問題更加容易, 就像是在vue中我更多的是直接用解構賦值來獲取參數, 比如

<a @click="handle(item)" v-for="(item, index) in list" :key="item.id"></a>
handle({ id,  name, department }) { } 

那么如果想要傳入整個對象, 但是又不愿意將其暴露在html中的話, 那該怎么綁定呢, 也是有方法的, 那便是利用閉包, 也就是以下的綁定方式

arr.forEach((item) => {
  let id = `li${item.num}`;
  let dom = document.createElement('li');
  dom.innerHTML = item.str + `一些比較復雜的html,比如<div><div><a href='javascript:;'>點擊鏈接</a></div></div>`;
  dom.addEventListener('click', function(event) { console.log(event, item) });
  ul.append(dom);
})

可以從代碼中看到, 這個li節點將是直接生成而非字符串拼接, 這樣的好處在于可以直接獲取這個li節點, 從而利用js的閉包將當前循環的item對象直接傳入到綁定方法中, 但是閉包有好處自然也有壞處, 這種方式如果綁定的多, 對于內存的消耗自然也不小, 所以使用這種方式的話, 需要稍微考慮性能的問題, 不過當然, 一般情況下應該采用其他方式來處理這種問題, 比如按視圖加載, 分頁處理, 都是用來解決這類大量點擊綁定的好方法。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。