2009-08-15 10 views
3

で別のスクリプトの関数を取得します。このコードは、2回目の動作です。ブックマークレットをクリックします(この機能は警告()の後まで読み込まれません)。奇妙なことに私はこのブックマークレットからのコードをロードJS JS

私は、コードを変更した場合、:

if (in_array(domain, supported)) 
{ 
    include_dom('http://localhost/bklts/parse/'+domain+'.js'); 
    alert('hello there'); 
    alert(getName()); 
} 

私は、最初のクリックで、アラート、およびスクリプト関数の残りの部分の両方を取得します。ブックマークレットの最初のクリックで、偽のアラートなしでスクリプトを動作させるにはどうすればよいですか?

ありがとうございます! -Mala

+1

新しいアラートが実行を変更するだろう唯一の方法はタイミングであるので、おそらく問題は十分に速く、余分なJavaScriptをロードしていないブラウザである私には思えます。 –

答えて

2

<スクリプト>タグをDHTMLで追加すると、スクリプトが非同期に読み込まれるため、ブラウザは読み込みを開始しますが、残りのスクリプトを実行するまで待機しません。

タグオブジェクトのイベントを処理して、スクリプトがロードされた時刻を知ることができます。ここでは、すべてのブラウザで正常に動作するように見えるサンプルコードを示しますが、これを実現するにはより良い方法がありますが、これが正しい方向に向けることを願っています:

忘れないでください<スクリプト>要素を保持するオブジェクトにタグを変更するには、fnLoaderにスクリプトがロードされたときに呼び出す関数を、fnErrorにはスクリプトのロードに失敗した場合に呼び出す関数を指定します。

これらの関数は後で呼び出されるので、(タグのような)関数が利用可能でなければならないことに留意してください(クロージャが通常通りに処理します)。

 tag.onload = fnLoader; 
    tag.onerror = fnError; 
    tag.onreadystatechange = function() { 
     if (!window.opera && typeof tag.readyState == "string"){ 
      /* Disgusting IE fix */ 
      if (tag.readyState == "complete" || tag.readyState == "loaded") { 
       fnLoader(); 
      } else if (tag.readyState != "loading") { 
       fnError(); 
      }; 
     } else if (tag.readyState == 4) { 
      if (tag.status != 200) { 
       fnLoader(); 
      } 
      else { 
       fnError(); 
      }; 
     }; 
    }); 
+0

ありがとう、これは私が欲しかった正確に動作するようです! – Mala

0

外部スクリプト(http://localhost/bklts/parse/www.amazon.com/js)の読み込みがロードされるまで実行をブロックしていないようです。シンプルなタイムアウトは、ブラウザにDOMを更新する機会を与えるに十分で、その後すぐに、論理のあなたの次のブロックの実行をキューにあります。私の経験で

//... 
if (in_array(domain, supported)) 
{ 
    include_dom('http://localhost/bklts/parse/'+domain+'.js'); 
    setTimeout(function() { 
     alert(getName()); 
    }, 0); 
} 
//... 

、ゼロがタイムアウトのために動作しない場合あなたは本当の競争条件を持っています。タイムアウトを長くすると(たとえば10〜100)、状況によってはそれを修正することができますが、これが常に必要な場合は危険な状況に陥ります。ゼロがあなたのために働くならば、それはかなりしっかりしているはずです。そうでない場合は、実行する残りのコードのうち、さらに多く(すべて?)を外部スクリプトにプッシュする必要があります。

+0

私はjavascriptの専門家ではありませんが、 'include_dom(...)'の前に 'loaded = false'を設定してから、外部セット' loaded = true'の終わりに 'while'の後に待ちますそれのための? –

+0

100のタイムアウトは、スクリプトが現在ローカルにホストされているにもかかわらず、動作しません。そのため、一度それがオンラインになると、どちらか適切な時間がかかりません。読み込まれた=偽のアイデアを使用して今すぐ試してみてください... – Mala

+0

オースティン - あなたのアイデアを試しましたが、Firefoxが実行を止めるまでブラウザをハングアップさせる無限ループに私をスローします...残りのすべてのコードを外部関数にプッシュしてみてください: - \ Gh! – Mala

0

私が働く最良の方法:しないでください。

とにかく小さなローダーのブックマークレットからJSを呼び出していたので(これはあなたが見ているページにスクリプトを貼り付けるだけです)、私はJSコードを出力するPHPスクリプトにsrcを指すようにブックマークレットを修正しました。 document.domainをパラメータとして取得します。そのように、私はちょうど外部コードを含めるためにPHPを使用しました。

誰かを助ける希望。それは本当に私の質問への答えではないので、私はこれを受け入れられた答えとしてマークしません。誰かがより良い方法を持っている場合、私はそれを知ってみたい、しかしであるように私は私のコードを残すことでしょう:

ブックマークレット:

javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://localhost/bklts/div.php?d='+escape(document.domain);})(); 

はlocalhost/bklts/div.php:

<?php 

print(" 
// JS code 
"); 

$supported = array("www.amazon.com", "www.amazon.co.uk"); 
$domain = @$_GET['d'] 
if (in_array($domain, $supported)) 
    include("parse/$domain.js"); 

print(" 
// more JS code 
"); 

?> 
関連する問題