DOM APIを使いません?

DOM APIを使いません?:

reactやvueなどフレームワークでのdom構築が主なこの頃ですが、小規模のプロジェクトの場合、標準仕様を活用することで簡素に仕上げることが可能です。


再帰的なcreateElementを考える

domは入れ子になることがほとんどです。標準で入れ子の表現をしようとすると、大変なので、ラッパーを作ります。

const mergeAttr = (target, attr) => { 
  for (const k of Object.keys(attr)) { 
    if(attr[k] instanceof HTMLElement) target.appendChild(attr[k]); 
    else if(k === 'innerHTML' && attr[k] instanceof Array) mergeAttr(target, attr[k]); 
    else target[k] = attr[k]; 
  } 
} 
const createElement = (tagName, attr) => { 
  const target = document.createElement(tagName); 
  attr && mergeAttr(target, attr); 
  return target; 
} 


サンプル

後は、標準仕様で書けばおk

サンプルとして、イベントなども加えたリストを作ります。

const listElement = async() => { 
  const ul = createElement('ul', { 
    className: 'list', 
    innerHTML: [ 
      createElement('li', { 
        innerHTML: 'default item' 
      }), 
      createElement('li', { 
        innerHTML: 'default item' 
      }) 
    ], 
    onclick: e => console.log('click event'), 
    add: text => { 
      ul.appendChild(createElement('li', { 
        innerHTML: text 
      })); 
    } 
  }); 
  return ul; 
} 
//実行 
(async() => { 
  const list = await listElement(); 
  list.add('add item'); 
  console.log(list.outerHTML); 
})() 
上記の出力は下記です。

//<ul class="list"><li>default item</li><li>default item</li><li>add item</li></ul> 


documentへの挿入

const outElement = (element) => { 
  const currentScript = document.currentScript; 
  (async() => { 
    currentScript.parentNode.insertBefore(await element(), currentScript); 
  })() 
} 
<script>outElement(listElement)</script> 
非同期にしなくても良いかも。。。


チャットもどきを作ってみる

const formElement = async(listElement) => { 
  let input; 
  return createElement('form', { 
    onsubmit: () => { 
      listElement.add(input.value); 
      input.value = ''; 
      return false; 
    }, 
    innerHTML: [ 
      input = createElement('input'), 
      createElement('input', { 
        type: 'submit', 
        value: 'send' 
      }) 
    ] 
  }); 
} 
const chatElement = async() => { 
  const list = await listElement(); 
  const form = await formElement(list); 
  return createElement('div', { 
      innerHTML: [list, form] 
  }) 
} 
<script>outElement(chatElement)</script> 

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)