localで構築したシステムのデータベースでクリックしたら「コピーできる機能があれば便利だねー」との意見をもらって実装。

localでSSLを使う方法もあるのだけど、今回はSSL無しのため、navigator.clipboard.writeText() が使えません。

現在は非推奨ですが document.execCommand('copy'); を使っていきます。

まずはわかりやすくコードを書きます。

<div class="input_box"><input type="text" value="test1" readonly></div>
<div class="input_box"><input type="text" value="test2" readonly></div>
function copyToClipboardFallback(textfield) {
      textfield.select();
      try {
          document.execCommand("copy");
          console.log("クリップボードにコピーされました: " + textfield);
          let span = document.createElement('span');
          span.setAttribute("class","copied");
          span.innerText = "コピーしました";
          textfield.before(span);
      } catch (err) {
          console.error("クリップボードへのコピーに失敗しました: ", err);
      }
 }

let cp_inputs = document.querySelectorAll('input[type="text"]');

    for (let i = 0; i < cp_inputs.length; i++) {
      cp_inputs[i].addEventListener('click',function(){
        copyToClipboardFallback(cp_inputs[i]);
      },false);
    }

CSSはコピーした際にコピーしましたとミニポップアップします。

@keyframes copied_anime{
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
    }
}
div.input_box{
    position:relative;
}
div.input_box .copied{
    position: absolute;
    top:-1em;
    background: rgba(0, 0, 0, 0.5);
    color:white;
    font-size: 0.8em;
    padding:1px 3px;
    border-radius: 3px;
    animation: copied_anime 1s ease-out forwards;
    animation-delay: 400ms;
}
div.input_box input[type="text"]{
    border:none;
    padding:2px 2px;
}

こんな感じ。

JavaScript最適化

JavaScript最適化します。
非推奨されている書き方でしたので最適化。

async function copyToClipboardFallback(textfield) {
  textfield.select();
  try {
    // navigator.clipboardを優先的に使用
    if (navigator.clipboard) {
      await navigator.clipboard.writeText(textfield.value);
    } else {
      document.execCommand("copy"); // 互換性のためのフォールバック
    }
    console.log("クリップボードにコピーされました: " + textfield.value);

    // 「コピーしました」メッセージの表示処理
    let span = textfield.previousElementSibling;
    if (!span || !n_span.classList.contains("copied")) {
      span = document.createElement("span");
      span.className = "copied";
      span.innerText = "コピーしました";
      textfield.before(span);

      // 数秒後にメッセージを削除
      setTimeout(() => span.remove(), 1500);
    }
  } catch (err) {
    console.error("クリップボードへのコピーに失敗しました: ", err);
  }
}

document.querySelectorAll('input[type="text"]').forEach(input => {
  input.addEventListener("click", () => copyToClipboardFallback(input));
});

\ 最新情報をチェック /

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA