jQuery / Method / .fadeOut() - 選択した要素を徐々に隠すメソッド

jQueryの .fadeOut() は不透明度を下げ、最後にdisplayをnoneにして要素を隠します。画面とレイアウトから消えてもDOMの要素自体は削除しないため、再表示できます。実際に削除するなら効果終了後の完了コールバックで.remove()を呼びます。

非表示・削除・実行時間の違い

.fadeOut() の公式文書では、完了時にdisplay: noneとなり、レイアウト上の領域もなくなると説明しています。途中は不透明度が下がる効果で、高さが徐々に折り畳まれる効果ではありません。DOM(Document Object Model、文書オブジェクトモデル)からの削除は別の操作です。

操作 完了後の要素 例の結果 Restoreの意味
.fadeOut()のみ DOMに残り非表示 hidden / nodes=1 既存要素を表示し、編集値を保持
完了後.remove() DOMから削除 removed / nodes=0 初期HTMLと初期値で新規作成

.fadeOut(duration, easing, complete) は任意の引数を省略できます。既定時間は400ミリ秒、"fast"は200、"slow"は600です。.fadeOut(800)は800ミリ秒かけて消す指定で、開始前に待つ指定ではありません。easingの既定はswingで、一定の進行には時間の後で"linear"を指定します。

入力値で違いを調べる完全な例

全コードをUTF-8の fadeout-demo.html に保存し、ブラウザーで開きます。インストールは不要ですが、CDN(Content Delivery Network、コンテンツ配信ネットワーク)から公式jQueryの完全版を読む接続が必要です。slimにはeffectsがないので完全版を使います。

コードは4.0.0を使い、非表示・削除・入力値・復元・途中リセットは3.7.1と4.0.0で実行確認しました。操作ボタンを通知の外に置き、消えた後もRestoreとResetを使えるようにしています。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Fade out versus remove</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    #notice { padding: 20px; background: #e5f2f0; margin: 16px 0; }
    button, select, input { padding: 8px; margin: 4px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Fade out versus remove</h1>
  <label for="duration">Duration:</label>
  <select id="duration"><option value="800">800 ms</option><option value="0">0 ms</option></select>
  <button type="button" id="fade">Fade only</button>
  <button type="button" id="remove">Fade then remove</button>
  <button type="button" id="restore">Restore</button>
  <button type="button" id="reset">Reset</button>
  <div id="host">
    <div id="notice">
      <p>A temporary notice</p>
      <label>Note: <input id="note" value="Keep me"></label>
    </div>
  </div>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      const initialHtml = $("#host").html();
      function enable() {
        $("#fade, #remove").prop("disabled", false);
      }
      function report(state) {
        $("#result").text(`state=${state} | nodes=${$("#notice").length}`);
      }
      function fade(removeAfter) {
        const $notice = $("#notice");
        if (!$notice.length) {
          report("missing");
          return;
        }
        const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
        const duration = reduce ? 0 : Number($("#duration").val());
        $notice.stop(true, false);
        $("#fade, #remove").prop("disabled", true);
        report("fading");
        $notice.fadeOut(duration, function () {
          if (removeAfter) $(this).remove();
          enable();
          report(removeAfter ? "removed" : "hidden");
        });
      }
      $("#fade").on("click", () => fade(false));
      $("#remove").on("click", () => fade(true));
      $("#restore").on("click", function () {
        if (!$("#notice").length) $("#host").html(initialHtml);
        $("#notice").stop(true, false).css("opacity", "").show();
        enable();
        report("visible");
      });
      $("#reset").on("click", function () {
        $("#notice").stop(true, false);
        $("#host").html(initialHtml);
        enable();
        report("visible");
      });
      report("visible");
    });
  </script>
</body>
</html>

初期通知にはKeep meが入力され、次の結果が出ます。

state=visible | nodes=1
  1. Noteを edited に変えて Fade only を押すと、800ミリ秒後に state=hidden | nodes=1 です。
  2. Restore は同じ通知を再表示し、editedを保持します。元の要素が残っていたためです。
  3. Fade then remove は効果終了後に削除し、state=removed | nodes=0 です。削除を完了後にするので消える過程が見えます。
  4. 削除後の Restore は初期HTMLで新しい通知を作ります。入力もKeep meに戻り、editedは自動復元されません。
  5. 途中の Restore は効果を止めて既存通知を表示します。Reset は止めてから初期HTMLを作り直すので編集値も初期化します。
  6. 0 ms は段階的な変化なしで同じ完了処理を行います。動きを減らす設定を検出した場合も0です。

実際の編集画面で削除後に編集値も戻すには、データを別に保管して新要素へ反映する必要があります。この例のRestoreは既存要素の表示か固定の初期内容の再作成であり、削除した入力の復元ではありません。

完了後に削除し、対象なしも扱う

.remove()は要素と内容に加え、関連するjQueryデータとイベントも削除します。非表示と同じ保管方法ではありません。例は完了コールバックでremoveAfterが真のときだけthisを削除します。通常の関数のthisは効果が終わったDOM要素です。

.fadeOut()は後続JavaScriptを完了まで止めません。呼び出し直後に.remove()すると効果終了前に要素がなくなり、遷移を見られません。複数要素なら完了は要素ごとですが、ここでは一意のIDで1個だけを対象にします。

削除済みで空の選択なら要素ごとのコールバックもありません。例は開始前に.lengthを確認して state=missing | nodes=0 として戻り、存在しない対象を待ってボタンが無効のままになるのを防ぎます。

途中復元と繰り返し実行の確認

.stop(true, false)は待機中の効果を消し、現在の効果を完了せず止めます。完了コールバックが動かないのでRestoreやReset後に古い処理が通知を削除しません。Restoreは途中のopacityを除いて.show()、Resetは停止後に初期HTMLを入れます。

実行中はFadeボタンを無効化し、RestoreとResetは使えるままにします。正常完了とキャンセルを区別すると、回数と画面状態のずれを避けられます。

動かなければ完全版の読み込み、Consoleの.fadeOut is not a function、選択範囲を確認します。瞬時に消えるなら0 msや動きの削減を確認します。すでに非表示の要素は消える過程を繰り返せないのでRestore後に比較します。