[解決済み] jQueryやgetElementByIdのようなDOMメソッドが、要素を見つけられないのはなぜですか?
質問
の理由として考えられることは何ですか?
document.getElementById
,
$("#id")
または他のDOMメソッド/ jQueryセレクタが要素を見つけることができませんか?
問題例としては、以下のようなものがあります。
- jQueryがイベントハンドラのバインドに無言で失敗する。
-
jQuery の "getter" メソッド (
.val()
,.html()
,.text()
) を返します。undefined
-
を返す標準的な DOM メソッドです。
null
が発生し、いくつかのエラーが発生します。
Uncaught TypeError: null のプロパティ '...' を設定できません。
Uncaught TypeError: nullのプロパティを設定できない('...'を設定)。
Uncaught TypeError: null のプロパティ '...' を読み取れない
Uncaught TypeError: nullのプロパティを読み取れない('...'を読み取る)。
最も一般的な形は
Uncaught TypeError: プロパティ 'onclick' に null を設定できない。
Uncaught TypeError: nullのプロパティ'addEventListener'を読み取れませんでした。
Uncaught TypeError: nullのプロパティ'style'を読み取れませんでした。
解決方法は?
探そうとしていた要素は DOM スクリプトを実行したときに
DOMに依存するスクリプトの位置は、その動作に大きな影響を与えることがあります。ブラウザはHTMLドキュメントを上から下へと解析します。要素は DOM に追加され、スクリプトは(一般に)遭遇したときに実行されます。 つまり、順番が重要なのです。 一般に、マークアップの後半に登場する要素は、まだDOMに追加されていないため、スクリプトは見つけることができません。
次のようなマークアップを考えてみましょう。
<div>
が、スクリプト#2 は成功する。
<script>
console.log("script #1:", document.getElementById("test")); // null
</script>
<div id="test">test div</div>
<script>
console.log("script #2:", document.getElementById("test")); // <div id="test" ...
</script>
では、どうすればいいのでしょうか?いくつかの選択肢があります。
オプション1:スクリプトを移動する
上の例で見たように、直感的な解決策は、スクリプトをマークアップの下に移動して、アクセスしたい要素を通過させることかもしれません。実際、長い間、ページの一番下にスクリプトを配置するのは ベストプラクティス というのも、さまざまな理由からです。このように整理することで、スクリプトを実行する前にドキュメントの残りの部分をパースすることができます。
<body>
<button id="test">click me</button>
<script>
document.getElementById("test").addEventListener("click", function() {
console.log("clicked:", this);
});
</script>
</body><!-- closing body tag -->
これは理にかなっており、レガシーブラウザのための堅実な選択肢ですが、限界があり、より柔軟で現代的なアプローチが存在します。
オプション2
defer
属性
スクリプトはと言いながら
(一般的に)遭遇したときに実行されます。
最近のブラウザでは、別の動作を指定することができます。外部のスクリプトをリンクする場合は
defer
属性で指定します。
[
defer
は、ドキュメントが解析された後、スクリプトが実行されることを意味し、ブラウザに示すために設定されます。DOMContentLoaded
.
というタグが付けられたスクリプトを配置することができるということです。
defer
はどこでも、たとえ
<head>
そして、完全に実現された DOM にアクセスできるようにする必要があります。
<script src="https://gh-canon.github.io/misc-demos/log-test-click.js" defer></script>
<button id="test">click me</button>
覚えておいてください...
-
defer
は、外部スクリプトにのみ使用できます。src
属性を使用します。 - 気をつける ブラウザサポート すなわち、IE < 10ではバギーな実装となります。
オプション3:モジュール
お客様のご要望に応じて JavaScriptモジュール . 標準的なスクリプトとの重要な違いとして ( ここに記す )、モジュールは自動的に遅延され、外部ソースに制限されない。
スクリプトの
type
から
module
, 例:
<script type="module">
document.getElementById("test").addEventListener("click", function(e) {
console.log("clicked: ", this);
});
</script>
<button id="test">click me</button>
オプション4:イベント処理で延期する
ドキュメントがパースされた後に発生するイベントのリスナーを追加します。
DOMContentLoadedイベント
DOMContentLoaded
は、スタイルシートや画像などの読み込みを待たずに、最初のパースから DOM が完全に構築された後に起動します。
<script>
document.addEventListener("DOMContentLoaded", function(e){
document.getElementById("test").addEventListener("click", function(e) {
console.log("clicked:", this);
});
});
</script>
<button id="test">click me</button>
ウィンドウ:ロードイベント
は
load
の後に発生します。
DOMContentLoaded
と、スタイルシートや画像などの追加リソースが読み込まれました。そのため、私たちの目的よりも遅れて実行されます。それでも、IE8 のような古いブラウザを考慮するならば、ほぼ万能にサポートされています。尤も
のポリフィル
addEventListener()
.
<script>
window.addEventListener("load", function(e){
document.getElementById("test").addEventListener("click", function(e) {
console.log("clicked:", this);
});
});
</script>
<button id="test">click me</button>
jQueryの
ready()
DOMContentLoaded
と
window:load
にはそれぞれ注意点があります。
ready()
を使用したハイブリッドソリューションを提供します。
DOMContentLoaded
にフェイルオーバーします。
window:load
DOM が既に完成している場合は、即座にコールバックを実行します。
ready ハンドラを直接 jQuery に渡すには、以下のようにします。
$(handler)
, 例:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function() {
$("#test").click(function() {
console.log("clicked:", this);
});
});
</script>
<button id="test">click me</button>
オプション5:イベントの委譲
イベント処理を対象要素の祖先に委譲する。
ある要素がイベントを発生させたとき、(それが
バブリング
イベントの伝播を止めるものは何もありません)、その要素の先祖にあるそれぞれの親から
window
は、同様にイベントを受信します。このため、既存の要素にハンドラを付けて、その子孫からバブルアップしてくるイベントをサンプリングすることができる。あとは、そのイベントが目的の要素から発生したかどうかを確認し、発生した場合はコードを実行するだけです。
一般に、このパターンはロード時に存在しない要素や、大量の重複したハンドラを添付することを避けるために予約されています。効率化のために、対象要素の最も近い信頼できる先祖を選択し、その代わりに
document
.
ネイティブJavaScript
<div id="ancestor"><!-- nearest ancestor available to our script -->
<script>
document.getElementById("ancestor").addEventListener("click", function(e) {
if (e.target.id === "descendant") {
console.log("clicked:", e.target);
}
});
</script>
<button id="descendant">click me</button>
</div>
jQueryの
on()
jQueryは、この機能を
on()
. イベント名、希望する子孫のセレクタ、イベントハンドラを指定すると、委譲されたイベント処理を解決して
this
コンテキストを使用します。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ancestor"><!-- nearest ancestor available to our script -->
<script>
$("#ancestor").on("click", "#descendant", function(e) {
console.log("clicked:", this);
});
</script>
<button id="descendant">click me</button>
</div>
関連
-
[解決済み] Web API エラー - このリクエストはブロックされました; コンテンツは HTTPS で提供されなければなりません
-
[解決済み】 `string.split is not a function` というエラーの原因は何ですか?
-
[解決済み】ある要素が可視DOMに存在するかどうかを確認するにはどうすればいいですか?
-
[解決済み] jQueryを使って要素のIDを取得するにはどうすればよいですか?
-
[解決済み] 私のJavaScriptコードは "No 'Access-Control-Allow-Origin' header is present on requested resource "というエラーを受け取りますが、Postmanはそうならないのはなぜですか?
-
[解決済み] なぜ ++[[]][+[] +[+[]] は "10" という文字列を返すのでしょうか?
-
[解決済み] どのDOM要素にフォーカスがあるかを調べるには?
-
[解決済み] JavaScriptには、与えられた範囲内の範囲を生成する "range() "のようなメソッドがありますか?
-
[解決済み] DOM要素が現在のビューポートで表示されているかどうかを確認するにはどうすればよいですか?
-
[解決済み] jQuery データ属性の値に基づいて要素を検索する方法は?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
vueネットワークリクエストソリューション ネイティブネットワークリクエストとjsネットワークリクエストライブラリ
-
WeChatアプレット用ユニアプリによるグローバルシェアリング
-
vueにおけるv-forループオブジェクトのプロパティ
-
[解決済み】ローカルファイルを開くことができません - Chrome: ローカルリソースの読み込みが許可されていない
-
[解決済み] 配列の結合時に未定義のプロパティ 'push' を読み込むことができない
-
[解決済み】Uncaught TypeError。プロパティ 'onclick' を null に設定できない [重複]。
-
[解決済み】エラー。Ionic使用中にモジュール '../lib/utils/unsupported.js' が見つかりませんでした。
-
[解決済み】document.getElementbyId()がnullを返す件【重複あり
-
nodejs unhandledPromiseRejectionWarning メッセージ
-
[解決済み] JavaScriptのgetElementByID()が動作しない [重複] [重複