LoginSignup
0
0

More than 3 years have passed since last update.

【javascript】appendChildを多用するコードをスッキリと

Last updated at Posted at 2021-03-04

目的

自分用

HTML
<div class="e1">
    <div class="e1-1">
        <div class="e1-1-1"></div>
        <div class="e1-1-2">
            <div class="e1-1-2-1">
        </div>
        <div class="e1-1-3"></div>
    </div>
</div>

javascriptで上記のような要素の生成と追加を繰り返すコードをスッキリさせたかった。
下記のように書くと上記HTMLを出力するようにしたい。


const c = 'className';
const elmement =
    childAppender(el('div',{[c]:'e1'}),
        siblingAppender(el('div',{[c]:'e1-1'}),
            el('div',{[c]:'e1-1-1'}),
            childAppender(el('div',{[c]:'e1-1-2'}),
                el('div',{[c]:'e1-1-2-1'})
            ),
            el('div',{[c]:'e1-1-3'})
        )
    );
console.log(elmement);  //上記HTMLのような構造を出力

第一引数は親要素となる為、慣れないと少しややこしい。

関数

以下の関数を用いる

//要素の生成
const el = (tag, attr) => {
    if (!tag) return null;
    const elm = document.createElement(tag);
    if (!attr) return elm;
    const map = Object.entries(attr);
    for (const [k,v] of map) elm[k] = v;
    return elm;
};
//nodeTypeの確認
const isElementNode = n => n ? n.nodeType===1 : false;
//子孫要素の追加
const childAppender = (...elms) => {
    const idx = elms.findIndex(x => !isElementNode(x));
    switch (idx) {
        case -1:    break;
        case 0:     return null;
        case 1:     return elms[0];
        default:    elms.slice(0, idx); break;
    }
    for (let i=0,len=elms.length-1; i<len; i++) {
        elms[i].appendChild(elms[i + 1]);
    }
    return elms[0];
};
//兄弟要素の追加
const siblingAppender = (parent, ...elms) => {
    if (!isElementNode(parent)) return null;

    const available = elms.filter(isElementNode);
    for (const child of available) parent.appendChild(child);
    return parent;

};

関数の説明

  • el( tagName[, {attribute: value,...}] )
    要素を生成し返す。
    引数1:tagName => HTMLのタグ名
    引数2:属性名をKEY、値をVALUEで組んだオブジェクト形式
        elm.className = 'classname'のようなイコールで指定出来るもののみ
        elm.classList.add('classname')のような指定方法のものは不可

  • childAppender( element1, element2, ... )
    第一引数を親要素として残りの引数を順次、直列的に子孫に追加し、親要素を返す。
    nodeTypeが1でない要素が存在すると以降の要素は追加されない。

  • siblingAppender( parentNode, element1, element2, ... )
    第一引数を親要素として残りの引数を順次、兄弟要素として親要素の直下に追加し、親要素を返す。
    nodeTypeが1でない要素は追加されないが、childAppenderと違い最後の引数まで追加される。

感想

少し重い気がする。

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0