問題は、誰もが「メモリ リーク」について知っていることです。一般的なシナリオはいくつかあります。
ポイント 3 は私の注意を引きました。その意味はよくわかります。たとえば、「DOM ノードを手動で削除し、DOM ノードが占有していたメモリを解放する必要があるが、不注意により、一部のコードに削除されたノードへの参照が残っているため、最終的にノードが占有していたメモリが解放されない」とします。 <div id="ルート"> <div class="child">私は子要素です</div> <button>削除</button> </div> <スクリプト> btn = document.querySelector('button') とします。 child = document.querySelector('.child') とします。 root = document.querySelector('#root') とします。 btn.addEventListener('クリック', 関数() { root.removeChild(子) }) </スクリプト> このコードは、ボタンをクリックした後に .child ノードを削除します。クリック後にノードは確かに DOM から削除されますが、グローバル変数 child にはまだノードへの参照があるため、ノードのメモリを解放できません。 解決策: .child ノードへの参照をクリック イベントのコールバック関数に移動できます。その後、ノードが削除され、コールバック関数が終了すると、ノードへの参照は自動的にクリアされ、当然メモリ リークは発生しません。 (これは実際にはイベント内にノードが存在するかどうかをリアルタイムで検出するものです。存在しない場合、ブラウザは削除関数の実行をトリガーしません。) <div id="ルート"> <div class="child">私は子要素です</div> <button>削除</button> </div> <スクリプト> btn = document.querySelector('button') とします。 btn.addEventListener('クリック', 関数() { child = document.querySelector('.child') とします。 root = document.querySelector('#root') とします。 root.removeChild(子) }) </スクリプト> このコードは完璧ですか?いいえ。各イベントがトリガーされた後に、子ノードとルートノードへの参照が作成されるためです。メモリ消費量(気が狂いそうな人もいるだろう ボタンのクリック…)。 実際には、別の方法があります。クリック時に、現在のルート ノードに子ノードがまだ存在するかどうかを判断します。存在する場合は、削除関数を実行し、存在しない場合は何もしません。 これにより、タイトルに記載されている動作が発生します。 どう判断する? トラバース?いや、面倒すぎるよ! どういうわけか、プロトタイプ チェーンに基づいてオブジェクトを走査できる 当時のシーンを復元してみましょう。GitHub を開き、親ノードをランダムに探して取得します。 図の赤い枠は取得したい親要素、オレンジ色の枠は存在するかどうかを判定したい子要素です。 親を document.querySelector('.position-relative') とします。 子を document.querySelector('.progress-pjax-loader') にします。 ここで、取得するのは DOM ノード (配列のようなオブジェクト) であるため、操作の前に処理する必要があることに注意してください。 p_child=[...parent.children]とします。 それから console.log(p_child 内の子); ! ! ! なぜ? (この時点では、筆者はまだ事の重大さに気づいていない) 何か問題があったのではないかと思い、es6 の include API を使用して確認しました。 console.log(p_child.includes(child)); それは正しい! 通常の配列で検証してみましょう。 ? ? ? この時点で、MDN を確認することを思い出しました。 その後、次のことがわかりました。in 演算子を単独で使用すると、左側の値 (インデックスとして) に対応する値が右側のオブジェクト (プロパティとプロトタイプ) 内にあるかどうかが検出されます。 上記のコードに戻ると、次のことがわかります。 これは私たちの結論を裏付けています。 明らかに、「子要素」は「プロトタイプ チェーン上に存在する」ことと同じではありません。これは、属性とプロパティの違いという別の知識ポイントにつながります。 したがって、いくつかの「トラブル」の後、ソース コードは次のように直接記述する必要があります。 <div id="ルート"> <div class="child">私は子要素です</div> <button>削除</button> </div> <スクリプト> btn = document.querySelector('button') とします。 child = document.querySelector('.child') とします。 root = document.querySelector('#root') とします。 r_child = [...root.children] とします。 btn.addEventListener('クリック', 関数() { if(r_child.includes(child)){ // または、child が null かどうかを確認することもできます... root.removeChild(child) } }) </スクリプト> やや急ぎの結末 だから、読書や勉強は「徹底的に理解しようとしない」というわけにはいかないのです~ また、「面倒なことをする」勇気と、「書類を確認する」方法を学ぶ勇気も必要です [/ 面白い顔]。 要約する 問題の JS 演算子に関するこの記事はこれで終わりです。問題の JS 演算子に関する詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Alibaba Cloud で MySQL リモート接続を構成するための詳細な手順
>>: ウェブサイトがhttpsを有効にした後のSSLのセキュリティ構成と検出
必要な効果: 確認コードを送信するためにクリックした後、ボタンは無効になり、5 秒後に無効解除されま...
1. 計算プロパティとリスナー1.1 計算プロパティ <!DOCTYPE html> &...
デスクトップ プラットフォームの Web レイアウトのメタ タグは誰もがよく知っています。これは常に...
pymysqlをインストールするpip install pymysql 2|0pymysqlの使用2...
[LeetCode] 180. 連続した数字少なくとも 3 回連続して出現するすべての数字を検索す...
目次導入1. MySQL マスタースレーブレプリケーション1. MySQLレプリケーションタイプ2....
序文最近この問題に遭遇するまで、私は UTF-8 が文字セットの問題に対する普遍的な解決策だと考えて...
フロントエンド開発者の必須科目であるCSS3は、多くの基本的なアニメーション効果を実現するのに役立ち...
目次エフェクト表示コードリンクキーコード表形式データコンポーネントのネスト検証方法リセット方法完全な...
問題を見つける最近 Django を学習しているのですが、MySQL データと組み合わせてデータを挿...
この記事では、LinuxでのMySQL 5.6.27のインストールチュートリアルを参考までに紹介しま...
<br />私が住んでいる地域では、コミュニティに出入りする車両を管理するために、コミュ...
CSS 画面サイズの適応を実現するには、まず CSS3 @media メディア クエリを導入する必要...
MySQL パーティションテーブルの概要数億、あるいは数十億ものレコードを格納するテーブルに遭遇する...
目次インストールルーティングの基本構成Vue にルーターをインストールするルーターの設定Router...