☂️

UmbrellaJS で DOM 生成

2020/11/29に公開約4,400字2件のコメント

jQueryに強く影響を受けているというだけあってやっぱ楽

TL;DR

生成したいDOM例

<div id="thumbnail_list" class="grid grid-cols-4 gap-4 px-24 py-4">
  <div class="h-56">
    <div class="mb-2">
      <img class="w-full h-40" src="https://via.placeholder.com/150/92c952">
    </div>
    <div class="flex">
      <img class="flex-none w-10 h-10 rounded-full" src="https://via.placeholder.com/150/92c952">
      <div class="flex-grow ml-4">
        <div>foo title A</div>
        <div class="text-sm">foo</div>
        <div class="text-sm">2020/11/15</div>
        </div>
    </div>
  </div>
  <div class="h-56">
    <div class="mb-2">
      <img class="w-full h-40" src="https://via.placeholder.com/150/92c952">
    </div>
    <div class="flex">
      <img class="flex-none w-10 h-10 rounded-full" src="https://via.placeholder.com/150/92c952">
      <div class="flex-grow ml-4">
        <div>bar title B</div>
        <div class="text-sm">bar</div>
        <div class="text-sm">2020/11/20</div>
        </div>
    </div>
  </div>
...
</div>

Vanilla JavaScript で書いてみる

function createVideoThumbnails(videos) {
  const thumbnailList = document.getElementById("thumbnail_list");

  for (const video of videos) {
    const thumbnailImg = document.createElement("img");
    thumbnailImg.className = "w-full h-40";
    thumbnailImg.src = video.thumbnailUrl;
    const thumbnailImgDiv = document.createElement("div");
    thumbnailImgDiv.className = "mb-2";
    thumbnailImgDiv.appendChild(thumbnailImg);
  
    const titleDiv = document.createElement("div");
    titleDiv.innerText = video.title;
    const artistDiv = document.createElement("div");
    artistDiv.className = "text-sm";
    artistDiv.innerText = video.artist;
    const dateDiv = document.createElement("div");
    dateDiv.className = "text-sm";
    dateDiv.innerText = video.date;
    const infoDiv = document.createElement("div");
    infoDiv.className = "flex-grow ml-4";
    infoDiv.appendChild(titleDiv);
    infoDiv.appendChild(artistDiv);
    infoDiv.appendChild(dateDiv);
  
    const iconImg = document.createElement("img");
    iconImg.className = "flex-none w-10 h-10 rounded-full";
    iconImg.src = video.thumbnailUrl;

    const iconAndInfoDiv = document.createElement("div");
    iconAndInfoDiv.className = "flex";
    iconAndInfoDiv.appendChild(iconImg);
    iconAndInfoDiv.appendChild(infoDiv);
  
    const thumbnailDiv = document.createElement("div");
    thumbnailDiv.className = "h-56";
    thumbnailDiv.appendChild(thumbnailImgDiv);
    thumbnailDiv.appendChild(iconAndInfoDiv);

    thumbnailList?.appendChild(thumbnailDiv);
  }
}

コードが長い……。
もうちょっとスマートに書ける気がするが大差はなさそう。

UmbrellaJS (+TypeScript) で書いてみる

type Video = {
  id: string;
  title: string;
  artist: string;
  thumbnailUrl: string;
  sourceUrl: string;
  date: string;
}

function createVideoThumbnailsByU(videos:Array<Video>):void {
  const thumbnailList = u("#thumbnail_list");

  for (const video of videos) {
    const thumbnailImg = u('<img>').addClass("w-full h-40").attr("src", video.thumbnailUrl);
    const thumbnailImgDiv = u('<div>').addClass("mb-2");
    thumbnailImgDiv.append(thumbnailImg);

    const titleDiv = u('<div>').text(video.title);
    const artistDiv = u('<div>').addClass("text-sm").text(video.artist);
    const dateDiv = u('<div>').addClass("text-sm").text(video.date);
    const infoDiv = u('<div>').addClass("flex-grow ml-4");
    infoDiv.append(titleDiv).append(artistDiv).append(dateDiv);

    const iconImg = u('<img>').addClass("flex-none w-10 h-10 rounded-full").attr("src", video.thumbnailUrl);
    const iconAndInfoDiv = u('<div>').addClass("flex");
    iconAndInfoDiv.append(iconImg).append(infoDiv);

    const thumbnailDiv = u('<div>').addClass("h-56");
    thumbnailDiv.append(thumbnailImgDiv).append(iconAndInfoDiv);

    thumbnailList.append(thumbnailDiv);
  }
}

できた。
u('<div>')document.createElement("div") 相当のことができる。
u() は Umbrella JS インスタンスを返すので、
そのままメソッドチェーンで class や attribute を指定できて便利。
append() もチェーンできるのですっきりする気がする。
Vanilla JavaScript で各パターンと最終的に生成されるDOMは同じです。

こっちも、もっと完結に書ける気はする…… 色々試し中です。

参考サイト

Discussion

ほー、UmbrellaJSはじめて知りました。ちょっとしたDOM操作に良さそうですね。

@catnose さん

ちょっとしたDOM操作に良さそうですね。

そうですね、jQuery はいらないけど Vanilla でやるのはちょっと冗長なんだよな……
という時に結構便利だなと思いました

ログインするとコメントできます