0

私は他の数人と小さなウェブアプリを構築しています。ドキュメントの準備ができたときに常に呼び出されるいくつかの関数を、他の開発者が定義できるようにしたいと考えています。

このアプリは、次のスクリプトをすべてのページの HTML 本文に挿入します。

<script type="text/javascript">
  (function(){
    window.Utils = {
      funcs: {}
    };

    $(document).ready(function(){
      alert('Calling funcs...');

      var startFunc = Utils.funcs['start'];
      if (startFunc != undefined){
        startFunc();
      }

      var finishFunc = Utils.funcs['finish'];
      if (finishFunc != undefined){
        finishFunc();
      }
    });
  })();
</script>

次に、別の .js ファイルで、開発者は次の操作を実行できる必要があります。

Utils.funcs['start'] = function(){
    alert('Starting...');
};

Utils.funcs['finish'] = function(){
    alert('Finishing...');
};

しかし、これはうまくいきません。関数は呼び出されませんか?

jsFiddle リンク: http://jsfiddle.net/XvQtF/

4

3 に答える 3

3

jsFiddle の(非常に驚くべき)window loadデフォルトは、コードをハンドラーに入れることです。(これは上部の左側に表示されます。2 番目のドロップダウン ボックスには "onload" と表示されています。) これは、ロード プロセスの非常にready遅い段階で発生し、が発火してからずっと後になります。そのため、実行しようとするまで関数は追加されません。

他の開発者が、要素を定義した後、イベントを待たずに関数Utils.funcsを要素に入れても問題ありません: Updated FiddlescriptUtilsload


ただし、それだけの価値があるため、単一の関数ではなく、pub/sub ソリューションを使用することに傾倒します。たとえば、複数のstart機能が必要な場合、現在の構造では許可されていません。

jQuery にはDeferredand Promisenow があり、これを使用できます。その簡単な例を次に示しますライブソース

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>Pub/Sub with Deferred and Promise</title>
</head>
<body>
  <script>
    (function($) {
      // Deferred objects for our app states
      var start = new $.Deferred(),
          finish = new $.Deferred();

      window.Utils = {
        start: start.promise(),   // Only expose the Promise of each
        finish: finish.promise()  // " " " " " "
      };

      $(function() {
        alert("Calling funcs...");

        // Start the app
        start.resolve();

        // Finish the app (or whatever)
        finish.resolve();
      });

    })(jQuery);
  </script>
  <script>
    // Module 1
    Utils.start.then(function() {
      alert("Module 1 Started!");
    });
    Utils.finish.then(function() {
      alert("Module 1 Finished!");
    });
  </script>
  <script>
    // Module 2
    Utils.start.then(function() {
      alert("Module 2 Started!");
    });
    Utils.finish.then(function() {
      alert("Module 2 Finished!");
    });
  </script>
</body>
</html>
于 2013-07-14T10:26:01.320 に答える