ホームページ ウェブフロントエンド jsチュートリアル innerHTML_javascript スキルに挿入されたスクリプトを実行するコード

innerHTML_javascript スキルに挿入されたスクリプトを実行するコード

May 16, 2016 pm 07:07 PM

ajax プログラミングを行う場合、xmlhttp で取得したページのコンテンツを innerHTML を介してコンテナ (p、span、td など) に割り当てる必要があることがよくあります。 innerHTML に代入 ページコンテンツに外部スクリプト、内部スクリプトを問わずスクリプトが含まれている場合、(1)は実行されない場合があります。場合によっては、この問題は些細で無視できることもありますが、場合によってはこの問題が非常に深刻であり、プログラムが期待した結果を得られない可能性があります。したがって、この問題を解決する必要があります。

MSDN を読むと、innerHTML に挿入されたすべてのスクリプトが実行できないわけではないことがわかります。このスクリプトの script タグに defer 属性が含まれている場合、IE はこれらのスクリプトを正しく実行します。しかし残念ながら、Moziila/Firefox と Opera ではこれが行われません。script タグに defer 属性が設定されているかどうかに関係なく、これらのブラウザは IE のように innerHTML に挿入されたスクリプトを実行しません。

しかし、スクリプトが実行されるかどうかに関係なく、確実に言えることは、これらのスクリプトが実際に innerHTML に挿入されているということです。信じられない場合は、警告して確認してください。しかし、実際に注意してみると、例外があることもわかります。つまり、スクリプトが innerHTML コンテンツの先頭にある場合、IE ブラウザはこのスクリプトを無視しますが、Moziila/Firefox および Opera は無視しません。

さて、問題分析はほぼ完了しました。解決方法を見てみましょう。

解決策は実際には非常に簡単です。つまり、innerHTML に挿入されたすべてのスクリプトを取り出し、それらを 1 つずつ実行します。しかし、最初に上記の 2 つの問題を解決する必要があります。

まず最初の質問、IE の innerHTML で defer 属性を使用したスクリプトの繰り返し実行を回避する方法を見てみましょう。これは簡単で、ブラウザが IE かどうかを判断し、次に実行するスクリプトに defer 属性があるかどうかを確認するだけです。 IE ブラウザを判断する際には、Opera のブラウザ認識に騙されないように注意する必要があります。以下のコードでこれがどのように行われるかを見ていきます。

次に、IE が innerHTML の先頭にあるスクリプトを無視する問題を見てみましょう。これも簡単に解決できます。 innerHTML に挿入したいコンテンツの先頭に、スクリプトではないコンテンツを追加するだけで完了です。ただし、空の内容、スペース、キャリッジ リターン、ライン フィードなどを含むタグを追加しないでください。追加しても機能せず、先頭のスクリプトは無視されます。を追加しないでください。追加すると、最初のスクリプトが無視されるのを防ぐことができますが、それでも元のコンテンツの表示に影響しますが、うるさいユーザーにとっては耐えられないかもしれません。したがって、追加コンテンツが悪影響を及ぼさずに開始スクリプトが無視されるのを防ぐために、次のコンテンツを追加します:

上記のコンテンツはある程度の長さがありますが、表示されません。また、挿入されたタグには ID や名前がないため、元のコンテンツの一部のタグとは異なります。衝突。ただし、ここで注意すべき点が 1 つあります。他のブラウザではこの表示がサポートされていない可能性があるため、IE であるかどうかを判断してから、このコンテンツを追加するかどうかを決定する必要があります。CSS の変更はありません (Opera Mini など)。これを追加 このコードは最終的な表示効果に影響します。

スクリプトを取り出して実行する方法を見てみましょう。

スクリプトの削除は簡単です。innerHTML が配置されているオブジェクトの getElementsByTagName メソッドを使用するだけです。このメソッドは、ほとんどすべてのコンテナ タグで機能します。スクリプトを取り出したら、それが外部スクリプトなのか内部スクリプトなのかを一つ一つ判断する必要があります。

まず外部スクリプトを見てみましょう。外部スクリプトの場合は、最初に外部スクリプトのコピー オブジェクトを作成し、その defer 属性を true に設定する方法を選択しました (これは、IE ブラウザが正しく実行できるようにするためです)。次に、appendChild メソッドを使用して、このコピー オブジェクトを head に挿入します。ここで、innerHTML が配置されているオブジェクトにそれを挿入すればよいのではないかと疑問に思うかもしれません。 innerHTMLがあるオブジェクトに挿入した方が良いのではないでしょうか?試してみるとわかりますが、innerHTML が配置されているオブジェクトに挿入すると、IE ブラウザでは問題ありませんが、Mozilla/Firefox および Opera ブラウザでは若干の問題が発生します。問題は、Firefox でこれを実行すると、ブラウザが応答を停止し (これは Firefox 1.5 でのテスト結果であり、他のバージョンでこの問題が発生するかどうかは不明です)、Opera ではスクリプトが不可解にも 2 回実行されることです (これは Opera 8.5 でのテスト結果です。Opera の他のバージョンでこの問題が発生するかどうかはまだ不明です。これらの問題を回避するために、ヘッドに挿入することにしました。

内部スクリプトを見てみましょう。内部スクリプトの内容は、スクリプト オブジェクトの text 属性を使用して直接取得できます。ここでは、innerHTML 属性の代わりに script オブジェクトの text 属性を使用します。 Opera ブラウザ、スクリプト オブジェクト innerHTML 属性は空であり、スクリプト コンテンツの取得に使用できるのは text 属性のみです。内部スクリプトを実行するには、eval を使用するだけです。ただし、HTML のコメントタグ内にスクリプトが含まれている場合があるため、コメントタグを削除しないと IE でエラーが発生します。

上記の分析は完璧に見えますが、実際にはまだ問題があります。1 つは document.write と document.writeln の問題です。この問題は Blueidea にあり、それを置き換えるというアイデアが得られます。デフォルトの document.write メソッドと document.writeln メソッドは文字列置換を使用するため、内部スクリプトに対してのみ有効であり、外部スクリプトに対しては無効です。そこで、document write を直接置き換える、より一般的な方法を考えました。 document.write と document.writeln が再定義されるため、内部スクリプトが実行されるか外部スクリプトが実行されるかに関係なく、document.write と document.writeln を自分たちで定義します。ただし、副作用もあります。つまり、これら 2 つの関数は以前のように現在のページで使用できなくなります。ただし、これら 2 つの関数は通常、ページが読み込まれた後は使用されなくなるため、次のような副作用が発生します。再定義しても影響は最小限です。しかし、もう 1 つの問題は、これにもかかわらず、 document.write または document.writeln によって出力されたコンテンツが、コンテンツを配置するコンテナーに単に追加されるだけであることを保証できないことです。

もう 1 つは eval によって引き起こされる問題です。1 つは Blueidea で Hutia が指摘したスコープの問題です。もう 1 つは、eval を使用して内部スクリプトを実行すると、外部スクリプトが読み込まれる前に内部スクリプトが読み込まれることです。ロードされました。実行が開始されました。これら 2 つの問題を解決するには、window.setTimeout 関数を使用して、各スクリプトを実行する前に一定期間遅延させることができます。外部スクリプトの遅延時間を長く設定して完全にロードできるようにする一方で、内部スクリプトの場合は遅延時間を長く設定できます。スクリプトの実行時間は通常非常に短いため、設定できる値は非常に短くなります。これにより、スコープが変更されないことが保証されるだけでなく、スクリプトの実行順序が変更されないことも基本的に保証されます (このメソッドはそうではありません)。実行順序を 100% 効率的に確保するのに優れています。ネットワークが非常に混雑している場合は、設定された時間内に外部スクリプトがロードされない可能性がありますが、少なくとも eval を直接使用するよりははるかに優れています。

——————————–
(1) 注: 以下ではスクリプトが実行される状況があるため、ここでは修飾子「may」を使用します。これが表示されます。


前述の方法に従って実装すると、ほとんどのスクリプトは正常に実行できます。ただし、スクリプトに defer 属性がある場合、IE はそのコードを単独で実行するため (前述)、実行順序が乱れます。また、document.writeやdocument.writelnで書いたコードはスクリプトのある場所ではなく最後に追加されるので、これも問題です。

これら 2 つの問題を解決するには、以前の解決策にいくつかの変更を加える必要があります。まず、コンテンツを innerHTML に割り当ててから、そこからスクリプトを取得することはできません。スクリプトを取得するには、コンテンツを直接分析する必要があります。また、スクリプト以外のHTML部分をinnerHTMLに直接代入することはできず、スクリプト実行後に元のHTMLの内容とdocument.writewritelnで記述した内容を順番にマージしてからinnerHTMLに代入する必要があります。ここで、タグのコンテンツの半分が存在する可能性があるため、このコンテンツの一部を innerHTML に部分的に接続することはできません。その場合、ブラウザーでエラーが発生しやすくなります。そして、ページが繰り返し更新されることがわかります。最初にバッファに入れて、最後に innerHTML に代入すると、この問題は発生しません。

さらに、スクリプトをバッファーに入れる利点は、スクリプトの実行後に、バッファーに新しいスクリプトがあるかどうかを確認し、存在する場合はそれを再帰的に実行できることです。 .write と document で記述したスクリプトも実行できます。

2006-6-4 更新:

innerHTML に挿入されたスクリプトが innerHTML に挿入されたオブジェクトを取得できない問題を修正しました。 (思い出させてくれたネチズン DE に感謝します)。

同じコンテナ内のコンテンツに設定される共有ロックを追加しました。これにより、同じコンテナ内のコンテンツを継続的に設定するときに競合が発生しなくなります。 (シンガポールのネチズン、Jason Li に思い出させてくれてありがとう)。

2006-5-29 更新:

同じ外部スクリプトの 2 回目の読み込み速度を向上させるために、外部スクリプト キャッシュ機能の使用を追加しました。

2006-5-23 更新:

熱心なユーザー johnZEN によって思い出されたように、複数のコンテナの内容を同時に設定するときに競合が発生しないように、共有ロックが追加されました。 。

netizen udbjatwfn が指摘したように、IE の内部スクリプト実行スコープ エラーが修正されました。

以下は私の最終的な実装コードです:

ダウンロード: innerhtml.js

コードをコピー コードは次のとおりです:


/* innerhtml.js
* Copyright Ma Bingyao  
* バージョン: 1.9
* 最終更新日: 2006-06-04
* このライブラリは無料です。  再配布したり、変更したりすることができます。 
* http://www.php.cn/
*/

var global_html_pool = []; 
var global_script_pool = []; 
var global_script_src_pool = []; 
var global_lock_pool = []; 
var innerhtml_lock = null; 
var document_buffer = ""; 

function set_innerHTML(obj_id, html, time) {
if (innerhtml_lock == null) {
innerhtml_lock = obj_id; 
}
else if (typeof(time) == "未定義") {
global_lock_pool[obj_id "_html"] = html; 
window.setTimeout("set_innerHTML('" obj_id "', global_lock_pool['" obj_id "_html']);", 10); 
戻る; 
}
else if (innerhtml_lock != obj_id) {
global_lock_pool[obj_id "_html"] = html; 
window.setTimeout("set_innerHTML('" obj_id "', global_lock_pool['" obj_id "_html'], " time ");", 10); 
戻る; 
}

function get_script_id() {
return "script_" (new Date()).getTime().toString(36)
Math.floor(Math.random() * 100000000).toString(36); 
}

document_buffer = ""; 

document.write = function (str) {
document_buffer = str; 
}
document.writeln = function (str) {
document_buffer = str "n"; 
}

global_html_pool = []; 

var scripts = []; 
html = html.split(//i); 
for (var i = 0; i < html.length; i ) {
global_html_pool[i] = html[i].replace(/ scripts[i] = {text: '', src: '' }; 
scripts[i].text = html[i].substr(global_html_pool[i].length); 
scripts[i].src = scripts[i].text.substr(0, scripts[i].text.indexOf('>') 1); 
scripts[i].src = scripts[i].src.match(/srcs*=s*("([^"]*)"|'([^']*)'|([^s ]*)[s>])/i);
if (scripts[i].src) {
if (scripts[i].src[2]) {
scripts[i].src = scripts[i].src[2];
}
else if (scripts[i].src[3]) {
                スクリプト[i].src = スクリプト[i].src[3]; 
}
else if (scripts[i].src[4]) {
scripts[i].src = scripts[i].src[4]; 
}
else {
scripts[i].src = ""; 
}
scripts[i].text = ""; 
}
else {
scripts[i].src = ""; 
scripts[i].text = scripts[i].text.substr(scripts[i].text.indexOf('>') 1); 
scripts[i].text = scripts[i].text.replace(/^s*

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

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

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

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

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

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

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 Dec 17, 2023 pm 02:54 PM

WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法 はじめに: 技術の継続的な発展により、音声認識技術は人工知能の分野の重要な部分になりました。 WebSocket と JavaScript をベースとしたオンライン音声認識システムは、低遅延、リアルタイム、クロスプラットフォームという特徴があり、広く使用されるソリューションとなっています。この記事では、WebSocket と JavaScript を使用してオンライン音声認識システムを実装する方法を紹介します。

WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー WebSocket と JavaScript: リアルタイム監視システムを実装するための主要テクノロジー Dec 17, 2023 pm 05:30 PM

WebSocketとJavaScript:リアルタイム監視システムを実現するためのキーテクノロジー はじめに: インターネット技術の急速な発展に伴い、リアルタイム監視システムは様々な分野で広く利用されています。リアルタイム監視を実現するための重要なテクノロジーの 1 つは、WebSocket と JavaScript の組み合わせです。この記事では、リアルタイム監視システムにおける WebSocket と JavaScript のアプリケーションを紹介し、コード例を示し、その実装原理を詳しく説明します。 1.WebSocketテクノロジー

WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 WebSocketとJavaScriptを使ったオンライン予約システムの実装方法 Dec 17, 2023 am 09:39 AM

WebSocket と JavaScript を使用してオンライン予約システムを実装する方法 今日のデジタル時代では、ますます多くの企業やサービスがオンライン予約機能を提供する必要があります。効率的かつリアルタイムのオンライン予約システムを実装することが重要です。この記事では、WebSocket と JavaScript を使用してオンライン予約システムを実装する方法と、具体的なコード例を紹介します。 1. WebSocket とは何ですか? WebSocket は、単一の TCP 接続における全二重方式です。

JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 JavaScript と WebSocket を使用してリアルタイムのオンライン注文システムを実装する方法 Dec 17, 2023 pm 12:09 PM

JavaScript と WebSocket を使用してリアルタイム オンライン注文システムを実装する方法の紹介: インターネットの普及とテクノロジーの進歩に伴い、ますます多くのレストランがオンライン注文サービスを提供し始めています。リアルタイムのオンライン注文システムを実装するには、JavaScript と WebSocket テクノロジを使用できます。 WebSocket は、TCP プロトコルをベースとした全二重通信プロトコルで、クライアントとサーバー間のリアルタイム双方向通信を実現します。リアルタイムオンラインオーダーシステムにおいて、ユーザーが料理を選択して注文するとき

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 Dec 17, 2023 pm 05:13 PM

JavaScript と WebSocket: 効率的なリアルタイム天気予報システムの構築 はじめに: 今日、天気予報の精度は日常生活と意思決定にとって非常に重要です。テクノロジーの発展に伴い、リアルタイムで気象データを取得することで、より正確で信頼性の高い天気予報を提供できるようになりました。この記事では、JavaScript と WebSocket テクノロジを使用して効率的なリアルタイム天気予報システムを構築する方法を学びます。この記事では、具体的なコード例を通じて実装プロセスを説明します。私たちは

簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 簡単な JavaScript チュートリアル: HTTP ステータス コードを取得する方法 Jan 05, 2024 pm 06:08 PM

JavaScript チュートリアル: HTTP ステータス コードを取得する方法、特定のコード例が必要です 序文: Web 開発では、サーバーとのデータ対話が頻繁に発生します。サーバーと通信するとき、多くの場合、返された HTTP ステータス コードを取得して操作が成功したかどうかを判断し、さまざまなステータス コードに基づいて対応する処理を実行する必要があります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法を説明し、いくつかの実用的なコード例を示します。 XMLHttpRequestの使用

JavaScript で HTTP ステータス コードを簡単に取得する方法 JavaScript で HTTP ステータス コードを簡単に取得する方法 Jan 05, 2024 pm 01:37 PM

JavaScript で HTTP ステータス コードを取得する方法の紹介: フロントエンド開発では、バックエンド インターフェイスとの対話を処理する必要があることが多く、HTTP ステータス コードはその非常に重要な部分です。 HTTP ステータス コードを理解して取得すると、インターフェイスから返されたデータをより適切に処理できるようになります。この記事では、JavaScript を使用して HTTP ステータス コードを取得する方法と、具体的なコード例を紹介します。 1. HTTP ステータス コードとは何ですか? HTTP ステータス コードとは、ブラウザがサーバーへのリクエストを開始したときに、サービスが

JavaScriptでinsertBeforeを使用する方法 JavaScriptでinsertBeforeを使用する方法 Nov 24, 2023 am 11:56 AM

使用法: JavaScript では、insertBefore() メソッドを使用して、DOM ツリーに新しいノードを挿入します。このメソッドには、挿入される新しいノードと参照ノード (つまり、新しいノードが挿入されるノード) の 2 つのパラメータが必要です。

See all articles