12

スクリプトが配置されている場所で、DOM要素をページに追加する必要があるスクリプトを作成しています(ウィジェットのようなアプローチ)。これを行うための最良の方法は何ですか?

これが私が検討しているテクニックです:

  1. スクリプトのすぐ上にid="Locator"を持つ要素を含めます。問題:
    • 余分なマークアップは好きではありません
    • ページでウィジェットを再利用すると、複数の要素が同じ「ロケーター」IDを持ちます。スクリプトに行を追加して、一度使用したIDを削除することを考えていましたが、それでも...
  2. スクリプトにIDを追加します。問題:
    • 動作しているように見えますが、id属性はscript要素に対して無効です
    • 上記と同じ問題ですが、ページでスクリプトを再利用すると、いくつかの要素が同じIDになります。
  3. getElementsByTagName( "script")を使用して、最後の要素を選択します。これはこれまでのところうまくいきましたが、少し重いようで、信頼できるかどうかはわかりません(遅延スクリプトについて考えてみてください)
  4. document.write:エレガントではありませんが、仕事をしているようです。

  5. [編集]idealmachineからの返信に基づいて、もう1つのオプションについて考えています。

    • スクリプトタグに属性を含めます(例:goal = "tabify")。
    • getElementsByTagName( "script")を使用して、すべてのスクリプトを取得します。
    • スクリプトをループし、goal="tabify"属性をチェックしてスクリプトを見つけます。
    • ページに別のウィジェットがある場合は、goal属性を削除してください。
  6. [編集]これまでの返信からもインスピレーションを得た別のアイデア:

    • getElementsByTagName( "script")を使用して、すべてのスクリプトを取得します。
    • スクリプトをループし、innerHTMLをチェックしてスクリプトを見つけます。
    • スクリプトの最後で、ページに別のウィジェットがある場合に備えて、スクリプトタグを削除します。
4

9 に答える 9

6

箱から出して:document.currentScript (IEではサポートされていません)

于 2015-09-23T12:40:18.630 に答える
4

私は、メインサービスとしてサイトに配置するウィジェットを提供するOnlyWireで働いてきました。

私たちはvar scripts = document.getElementsByTagName("script"); var thisScript = scripts[scripts.length - 1];トリックを使用し、それはかなりうまくいくようです。次にthisScript.parentNode.insertBefore(ga, thisScript);、DOMツリーでその前に必要なものを挿入するために使用します。

なぜこれを「重い」ソリューションと見なすのかわかりません...反復を伴わず、完全に統合された純粋なクロスブラウザソリューションです。

于 2010-11-13T11:13:20.023 に答える
4

これは、ページ上の同じコードの複数のコピー、および動的に挿入されたコードで機能します。

<script type="text/javascript" class="to-run">
(function(self){
    if (self == window) {
        var script = document.querySelector('script.to-run');
        script.className = '';
        Function(script.innerHTML).call(script);
    } else {
        // Do real stuff here. self refers to current script element.
        console.log(1, self);
    }
})(this);
</script>
于 2011-06-10T11:18:42.377 に答える
1

<script>タグをドロップするか、ドロップするかにかかわらず<div class="mywidget">、マークアップに何かを追加します。個人的には、スクリプト自体は1回しか追加されないため、後者の方が好きです。ページ本文のスクリプトが多すぎると、ページの読み込み時間が遅くなる可能性があります。

document.write()ただし、ウィジェットを配置する場所にスクリプトタグを追加する必要がある場合は、divを配置するために使用することの何が問題になっているのかわかりません。

于 2010-11-13T11:26:23.517 に答える
1

またはdocument.write最後のスクリプト要素を選択すると、ほとんどのWebページで同期的にロードされるスクリプトに対して機能します。ただし、非同期ロードを許可することを考慮していなかったと思われるオプションがいくつかあります。

  • スクリプトの前にdivwithを追加します。HTMLクラスには、重複が無効にならないclass="Locator"という利点があります。もちろん、複数のウィジェットの場合を処理するには、HTML要素の追加が完了したときに要素のクラス名を変更して、2回追加しないようにする必要があります。(要素が複数のクラスのメンバーになることも可能であることに注意してください。これはスペースで区切られたリストです。)

  • src各スクリプト要素のをチェックすることで、トラッキングコード(Googleアナリティクスのレガシートラッキングコードなど)やページの最後に読み込まれる他のスクリプトが、非同期読み込みを使用したときにスクリプトが正しく機能するのを妨げないことを確認できます。繰り返しになりますが、複数のウィジェットの場合を処理するには、スクリプト要素を使い終わったとき(つまり、目的のコードがページに追加されたとき)にスクリプト要素を削除する必要がある場合があります。


私が行う最後のコメントの1つは(すでにこれを知っているかもしれませんが)、ウィジェットをコーディングするときは、すべての変数を使用して宣言し、すべてのコードを次のように囲む必要があるvarということです(JSLintはこれをチェックするのに役立ちます)

(function(){
    ...
})();

これは「自己実行関数」と呼ばれ、スクリプトで使用される変数がWebページの他の部分に干渉しないようにします。

于 2010-11-13T12:53:53.967 に答える
0

私はちょうど私の質問に答えるように見える別の方法を見つけました:

javascriptから親Iframeにアクセスする方法

スクリプトは常に独自のウィンドウへの参照を保持するため、スクリプトをiframeに埋め込むと、いつでもスクリプトを見つけることができます。

スクリプトをページに何度追加しても常に機能するため、これが最善のアプローチであると投票します(ウィジェットを考えてください)。コメントを歓迎します。

そもそもiframeを検討するようになったのは、Googleガジェットを作成するために行った実験でした。

于 2011-05-06T06:21:14.627 に答える
0

多くの場合、これはうまく機能します(hud.jsはsciptの名前です):

var jsscript = document.getElementsByTagName("script"); 
for (var i = 0; i < jsscript.length; i++) { 
      var pattern = /hud.js/i; 
      if ( pattern.test( jsscript[i].getAttribute("src") ) )
      {
         var parser = document.createElement('a');
         parser.href = jsscript[i].getAttribute("src");
         host = parser.host; 
      }

 }
于 2017-05-10T15:29:32.913 に答える
0

また、それらの中に個々のスクリプトの名前を追加することもできます。

  • いくつかのjsスクリプト内のいずれか

     dataset['my_prefix_name'] = 'someScriptName'
    
  • またはHTML内-<script>タグ内

     data-my_prefix_name='someScriptName'
    

次に、 document.scripts配列をループして、適切なものを検索します。

 ... function(){
    for (var i = 0, n = document.scripts.length; i < n; i++) {
        var prefix = document.scripts[i].dataset['my_prefix_name']
        if (prefix == 'whatYouNeed') 
           return prefix
    }
 }
于 2017-08-10T17:40:08.627 に答える
0

私はずっとインターネットエクスプローラーにアクセスできませんでしたが、これはほとんどどこでも機能するはずです:

<script src="script.js"
    data-count="30"
    data-headline="My headline"
    onload="uniqueFunctionName(this)"
    defer
    ></script>

およびscript.js内:

window.uniqueFunctionName = function (currentScript) {
   var dataset = currentScript.dataset
   console.log(dataset['count'])
   console.log(dataset['headline'])
}
于 2020-03-11T17:17:34.507 に答える