2013-07-14 3 views
0

Я строю небольшое веб-приложение с несколькими другими людьми. Я хочу, чтобы другие разработчики определили пару функций, которые всегда вызываются, когда документ готов.Функции глобального глобального вызова JavaScript не называются?

Наше приложение вставляет следующий скрипт в тело 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/

ответ

3

jsFiddle в (очень удивительно) по умолчанию поставить свой код в windowload обработчика. (Вы можете видеть это слева вверху, второй раскрывающийся список говорит «onload».) Это происходит очень в конце процесса загрузки, вскоре после того, как ready уволил. Таким образом, функции не добавляются до тех пор, пока вы не попытаетесь запустить их.

Если другие разработчики поставили свои функции в Utils.funcs в script элементов после вашего элемента, определяющего Utils, но не дожидаясь load случае, это хорошо: Updated Fiddle


Для чего это стоит, хотя, я бы опереться к использованию решения pub/sub, а не к одной функции. Если вы хотите иметь более одной функции start, например, ваша текущая структура не позволяет этого.

В настоящее время jQuery имеет Deferred и Promise, которые могут быть использованы для этого. Вот простой пример: Live Copy | Live Source

<!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> 
0

Настройка Utils в отдельном сценарии должны быть загружены в качестве самого первого. Кроме того, сделать это безусловно (не в какой-либо обратного вызова и т.д.):

/* load as first script, sets up a global container-object for later use */ 
var Utils = { 
    funcs: {} 
} 

Обратите внимание, что это нормально, чтобы определить глобальную переменную в глобальном масштабе.

/* other script */ 
(function(){ 
    function myFunc() { /*...*/ }; 

    // now store a reference in Utils 
    Utils.funcs.start = myFunc; 
})(); 

Как уже упоминался в другом ответе: Будь в курсе загрузки и вызывая порядок различных скриптов/кода:

$ (документ) .ready, по существу, «DOMContentLoaded» -Event с большинством браузеров (но более ранние версии IE). «DOMContentLoaded» срабатывает, когда все встроенные ресурсы, первоначально найденные в головном разделе, загружены и присутствует DOM-структура тела. Так как это не включает какой-либо инъецируемый контент, вероятно, предоставляется, что событие запускается до того, как всякая модульная библиотека (которая загружает модули путем инъекции тегов скриптов) полностью загружена и присутствует. (Учитывая, что эти сценарии загружаются одновременно с изображениями и другими встроенными файлами, используя только несколько сетевых слотов/сокетов, предоставляемых браузером, они, вероятно, являются одной из последних вещей, которые нужно будет готовить во время всего процесса загрузки.)

0

Вместо того, чтобы просто используя

startFunc() and 
finishFunc() 

попробуйте использовать этот

startFunc.apply(this, null) and 
finishFunc.apply(this, null) 

это будет вызывать функции.

также убедитесь, что

Utils.funcs['start'] 
Utils.funcs['finish'] 

становится инициализирован, прежде чем они называются.

Смежные вопросы