📝

動的に出力される文字列をspanタグで囲む

2023/07/10に公開

動的に出力される文字列をspanタグで囲むロジックを書きました
CSSはspanで囲われたかどうか分かりやすくするために書いています
spanで囲われた場合は文字の背景がオレンジになります

index.html
<p class="str js-str">シナカフェ名古屋</p>
<p class="str js-str02">アラブ石油王</p>
style.css
.str {
  padding: 10px;
  background-color: beige;
}
.str + .str {
  margin-top: 10px;
}
.str__span {
  padding: 3px;
  background-color: rgb(255, 168, 17)
}
.str__span + .str__span {
  margin-left: 3px;
}

最初の状態

script.js
/**
 * 動的に出力されるテキストをspanタグで囲む
 * @param {*} obj 
 * @returns 
 * @example
 *  テキストだけ指定
    insertSpan({
      strings: ["アラブ", "石油王"],
    });

    obj.elms(DOMのクラス名)とobj.spanClassName(spanのクラス名)を指定する場合
    insertSpan({
      elms: ".js-hoge",
      spanClassName: "fuga",
      strings: ["アラブ", "石油王"],
    });
 */
const insertSpan = obj => {
  //DOM
  obj.DOM = {};
  obj.DOM.elms = obj.elms ? document.querySelectorAll(obj.elms) : document.querySelectorAll(".js-str");
      
  if(!obj.DOM.elms) return;
    
  //spanのクラス名
  obj.spanClassName = obj.spanClassName ? obj.spanClassName : "str__span";
    
  //指定テキスト(検索対象文字)
  const searchTarget = obj.strings.reduce((pre, cur) => pre + cur);
    
  //それぞれのDOMの処理
  obj.DOM.elms.forEach(item => {
    //動的に出力されているテキストの整形
    const text = item.textContent.replace(/\r?\n/g, '').trim(); //改行削除・空白削除
    
    //指定テキスト(検索対象文字)と動的に出力されているテキストが一致しない場合は処理中断
    if(text !== searchTarget) return;
    
    //いったん動的に出力されているテキストを削除
    item.textContent = "";
    
    //指定テキストをspanで囲んだ後、DOMに挿入
    for(let i = 0; i < obj.strings.length; i++) {
      const spans = document.createElement("span");
      spans.textContent = obj.strings[i]; //spanタグにテキスト挿入
      spans.classList.add(obj.spanClassName); //クラス付与
      item.appendChild(spans); //作成したspanタグを追加
    }
  });
}

記述の順番を気にしたくなかったので引数をオブジェクトにしています

jsを実行すると以下のようにspanが挿入されます

insertSpan({
  strings: ["シナカフェ", "名古屋"],
});

insertSpan({
  elms: ".js-str02",
  strings: ["アラブ", "石油王"],
});

オブジェクト使わない場合

const insertSpan02 = (strings, elms = ".js-str", spanClassName = "str__span") => {
  let DOM = {};
  DOM.elms = document.querySelectorAll(elms);
  if (!DOM.elms) return;

  //検索対象文字列
  const searchTarget = strings.reduce((pre, cur) => pre + cur);

  DOM.elms.forEach(item => {
    //動的に出力されているテキストの整形
    const text = item.textContent.replace(/\r?\n/g, '').trim(); //改行削除・空白削除

    //指定テキスト(検索対象文字)と動的に出力されているテキストが一致しない場合は処理中断
    if (text !== searchTarget) return;

    //いったん動的に出力されているテキストを削除
    item.textContent = "";

    //指定テキストをspanで囲んだ後、DOMに挿入
    for (let i = 0; i < strings.length; i++) {
      const spans = document.createElement("span");
      spans.textContent = strings[i]; //spanタグにテキスト挿入
      spans.classList.add(spanClassName); //クラス付与
      item.appendChild(spans); //作成したspanタグを追加
    }
  });
}
insertSpan02(["シナカフェ", "名古屋"]);
insertSpan02(["アラブ", "石油王"], ".js-str02");

Discussion