JS FAQ: クリックするとポップアップ表示される i が常に最後のものになるのはなぜですか_JavaScript ヒント
フロントエンドグループでこの質問をしている人がたくさんいたのですが、今夜も同じ質問をする人がいたので、それを整理するために記事を書きました。まず、コードを見てください。li をクリックすると、現在の li に対応するインデックス値がポップアップ表示されます。非常に多くの人が次のコードを書きました。
var aLi = document.getElementsByTagName('li'); for(var i = 0; i < aLi.length; i++){ aLi[i].onclick = function(){ alert(i); } }
しかし、結果は満足のいくものではありません。簡単にするために、ページ内に 2 li があることに同意します。 li をクリックすると、すべてのポップアップが 2 になります。
まず、結果が 1 になる理由を分析しましょう。ループは単純に 2 つの部分に分割できます。
i = 0时,aLi[0].onclick = function(){alert(i)} i = 1时,aLi[1].onclick = function(){alert(i)} i = 2时,不满足条件跳出循环.
クリック関数を実行すると、スコープ チェーンが作成されます。このスコープ チェーンは、コード スコープ内の変数を定義するオブジェクトのリストです。 (変数オブジェクトの内容を詳しく知りたい場合は、変数オブジェクトを表示できます。)alert(i) を実行すると、変数 i を内側から外側に向かって探します。この時点で、この関数のスコープチェーンには 2 つのオブジェクトがあり、ループは終了しており、このときの i の値は 2 です。したがって、任意の li をクリックすると、ポップアップが表示されます。 2、必要なインデックス値ではありません。重要なのは、ポップアップされるのは変数 i、変数 i、変数 i であるということです。大事なことは3回言いましょう。
そこで、この問題をどのように解決するかという問題が生じます。必要なのは、イベントを aLi[i] にバインドするたびに、内部スコープに i の値を保存することです。解決策は次のとおりです。
var aLi = document.getElementsByTagName('li'); for (var i = 0; i < aLi.length; i++) { (function(i){ aLi[i].onclick = function () { alert(i); }; })(i) }
これには、ブロックレベルのスコープの概念が含まれます。 ES6 が登場する前は、関数がブロックレベルのスコープを作成する主な手段でした。ここでは、i をパラメーターとして使用して、aLi[i].onclick の外側に関数のレイヤーを配置し、結果を再分析してみましょう。
i = 0时, (function(i){ aLi[0].onclick = function(){ alert(i); } })(0) i = 1时, (function(i){ aLi[1].onclick = function(){ alert(i); } })(1) i = 2时,不满足条件跳出循环.
自己実行関数のラッピング層が追加されたため、li をクリックすると、内側から外側に向かって 3 つのレベルのスコープが存在します: クリック関数内の変数オブジェクト、クリック関数の変数オブジェクト。自己実行関数とレイヤーの最も外側のスコープ。 2 番目のレベルを検索すると、自己実行関数の i が渡されたパラメータ値と同じであることがわかり、そのときの i の値が対応して保存されるため、対応するインデックス値がポップアップ表示されます。
よくある js の問題を共有しましょう。li をクリックすると、現在の li インデックスと innerHTML 関数がポップアップします。
いずれかをクリックすると、次のアラートが表示されます:
通常の考え方によれば、コードは次のように記述する必要があります:
var myul = document.getElementsByTagName("ul")[0]; var list = myul.getElementsByTagName("li"); function foo(){ for(var i = 0, len = list.length; i < len; i++){ list[i].onclick = function(){ alert(i + "----" + this.innerHTML); } } } foo();
しかし、残念なことに、結果は次のようになります:
インデックスが常に 4 なのはなぜですか? これは、js にブロックレベルのスコープがないことが原因です。解決策は 3 つあります
1. クロージャを使用する
<script type="text/javascript"> var myul = document.getElementsByTagName("ul")[0]; var list = myul.getElementsByTagName("li"); function foo(){ for(var i = 0, len = list.length; i < len; i++){ var that = list[i]; list[i].onclick = (function(k){ var info = that.innerHTML; return function(){ alert(k + "----" + info); }; })(i); } } foo(); </script>
2. ES6 の新機能 let を使用して変数を宣言します
let で宣言された変数はブロックレベルのスコープを持ち、明らかに要件を満たしていますが、有効にするには 'use strict' (厳密モードを使用) を追加する必要があることに注意してください。
<script type="text/javascript"> var myul = document.getElementsByTagName("ul")[0]; var list = myul.getElementsByTagName("li"); function foo(){'use strict' for(let i = 0, len = list.length; i < len; i++){ list[i].onclick = function(){ alert(i + "----" + this.innerHTML); } } } foo(); </script>
3. jquery を導入し、イベント バインディングに on または delegate を使用します (これらはすべてイベント プロキシの特性を備えています)
<script type="text/javascript" src="jquery-1.8.2.min.js"></script> <script type="text/javascript"> $("ul").delegate("li", "click", function(){ var index = $(this).index(); var info = $(this).html(); alert(index + "----" + info); }); </script> <script type="text/javascript"> $("ul").on("click", "li", function(){ var index = $(this).index(); var info = $(this).html(); alert(index + "----" + info); }); </script>

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









記事では、JavaScriptライブラリの作成、公開、および維持について説明し、計画、開発、テスト、ドキュメント、およびプロモーション戦略に焦点を当てています。

この記事では、ブラウザでJavaScriptのパフォーマンスを最適化するための戦略について説明し、実行時間の短縮、ページの負荷速度への影響を最小限に抑えることに焦点を当てています。

フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

この記事では、ブラウザ開発者ツールを使用した効果的なJavaScriptデバッグについて説明し、ブレークポイントの設定、コンソールの使用、パフォーマンスの分析に焦点を当てています。

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

この記事では、ソースマップを使用して、元のコードにマッピングすることにより、Minified JavaScriptをデバッグする方法について説明します。ソースマップの有効化、ブレークポイントの設定、Chrome DevtoolsやWebpackなどのツールの使用について説明します。

このチュートリアルでは、chart.jsを使用してパイ、リング、およびバブルチャートを作成する方法について説明します。以前は、4つのチャートタイプのchart.js:ラインチャートとバーチャート(チュートリアル2)、およびレーダーチャートと極地域チャート(チュートリアル3)を学びました。 パイとリングチャートを作成します パイチャートとリングチャートは、さまざまな部分に分かれている全体の割合を示すのに理想的です。たとえば、パイチャートを使用して、サファリの男性ライオン、女性ライオン、若いライオンの割合、または異なる候補者が選挙で受け取る票の割合を示すことができます。 パイチャートは、単一のパラメーターまたはデータセットの比較にのみ適しています。パイチャートのファンの角度はデータポイントの数値サイズに依存するため、パイチャートは値のあるエンティティをゼロ値で描画できないことに注意してください。これは、割合がゼロのエンティティを意味します

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...
