iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

JavaScript 從 50% 開始,打造函式庫不是問題!系列 第 20

JS 20 - HTML 字串算什麼,教你用 CSS 選擇器建立網頁元素!

  • 分享至 

  • twitterImage
  •  

大家好!

昨天我們建立了 insert 方法,今天我們就要延伸它的用法。
我們進入今天的主題吧!


前言

$('<button>Submit</button>');
$('<button id="submit" type="submit" disabled>Submit</button>');

如果要使用 jQuery 來建立元素時,我們會使用第一行的方法。
但是,如果元素有很多屬性的話,不就會像第二行的方法一樣很冗長嗎?
沒錯,接下來我們就要實作既省時又不冗長的靜態方法。


實作

Felix.create = function (str, content) {
    /* 拆解 CSS 選擇器 */
    var blank = str.split(/(?=[#.][\w-:]+)|(?=\[[a-z][\w-:]+(?:=".+")?\])/);
    /* 根據標籤名或預設值建立元素 */
    var el = document.createElement(/^[\w-:]+$/.test(blank[0]) ? blank.shift() : 'div');
    blank.forEach((v) => {
        /* 解析拆解後的選擇器 */
        var model = v.match(/#([\w-:]+)|\.([\w-:]+)|\[([a-z][\w-:]+)(?:="(.+)")?\]/);
        /* 識別解析後的選擇器 */
        if (model[1]) el.id = model[1];
        else if (model[2]) el.classList.add(model[2]);
        else if (model[3]) el.setAttribute(model[3], model[4] || '');
    });
    if (content) {
        var type = content instanceof HTMLElement ? 'Element' : 'HTML';
        el['insertAdjacent' + type]('beforeend', content);
    }
    return el;
};

最後,再將昨天的 insert 改良一下:

Felix.prototype.insert = function (el, content, pos) {
    el = typeof el === 'string' ? Felix.create(el, content) : el;
    pos = /^(before|after)(begin|end)$/.test(pos) ? pos : 'beforeend';
    Felix.forEach(this, function () {
        this.insertAdjacentElement(pos, el);
    });
    return el;
};

使用方法請見下方的樣本。


實測

我們來比較 jQuery 和 Felix 建立物件的效率吧!
先附上樣本:

/* jQuery */
$('body').append('<button id="submit" type="submit" disabled>Submit</button>');

/* Felix */
Felix('body').insert('button#submit[type="submit"][disabled]', 'Submit');

| # | jQuery | Felix | Winner |
| --- | --- | --- |
| 01 | 0.48511 ms | 0.53809 ms | jQuery |
| 02 | 0.33594 ms | 0.34668 ms | jQuery |
| 03 | 0.46191 ms | 0.25488 ms | Felix |
| 04 | 0.43604 ms | 0.16406 ms | Felix |
| 05 | 0.51001 ms | 0.24072 ms | Felix |
| 06 | 0.34180 ms | 0.15820 ms | Felix |
| 07 | 0.37964 ms | 0.20410 ms | Felix |
| 08 | 0.37598 ms | 0.17725 ms | Felix |
| 09 | 0.42871 ms | 0.37402 ms | Felix |
| 10 | 0.45386 ms | 0.24194 ms | Felix |
| Total | 4.20900 ms | 2.69994 ms | Felix |

結果是 Felix 成功勝出!


解析 HTML 字串需要一定時間(Element.innerHTMLElement.insertAdjacentHTML),因此執行時間就會比較長;然而,使用 CSS 選擇器只要操作正規表示式,耗費的時間自然也會較少。

差不多也到尾聲了,接下來我們要介紹的是函式庫的靜態方法。
如果對文章有任何疑問,也歡迎在下方提問和建議!
我是 Felix,我們明天再見!


上一篇
JS 19 - 我要一份能控制網頁內容的三人全家桶!
下一篇
JS 21 - 資料太多看得心很累?用 9 行程式碼將資料轉換為表格吧!
系列文
JavaScript 從 50% 開始,打造函式庫不是問題!46
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言