3

Мы используем шаблон раскрывающего модуля для организации материала в «пространства имен». Некоторая часть кода инициализации (для плагина проверки jQuery) должна вызываться только после загрузки документа.Как получить код показанного модуля только для запуска после DOM?

Namespace.Foo.Bar = (function($) { 

    var init = function() { 

    $(function() {    // <--- within DOM ready wrapper it never runs 
     $.validator.setDefaults({ 
     // ... 
     }); 
    }); 

    (function(){     // <--- but within an IIFE it will run 
     $.validator.setDefaults({ 
     // ... 
     }); 
    })(); 

    }; 

    init(); 

    // public functions/variables 
    return { 
    }; 

}(jQuery)); 

$.validator.setDefaults Когда бит в готовом обертке DOM, он никогда не вызывается, но когда он находится в пределах IIFE то она дозвонилась.

Почему? Что такое «лучший» способ отметить код модуля для запуска после DOM?

правок из образца кода нагляднее проблемы

+0

Как вы знаете, что он никогда не работает? Он должен работать, когда вы отправляете сообщения. Могли бы вы сделать демо? – Bergi

ответ

3

Это не работает из-за того, как вы определяете свои функции (т.е. init). См. var functionName = function() {} vs function functionName() {}

При выполнении init() функция init еще не определена, и вы получите сообщение об ошибке.

Namespace.Foo.Bar = (function($) { 
    // init this module 
    console.log(typeof init); // this prints `undefined` 
    init();      // this throws an error 

    // module initialisation 
    var init = function() { 
    ... 
    } 
    ... 
}(jQuery)); 

Вы должны либо переместить init() вызов к концу тела вашей функции, или определить функцию с помощью:

function init() { ... } 
+0

Отредактировано Q, чтобы показать init-вызов после объявления (как это было в кодовой базе btw), но проблема остается прежней. –

0

Я считаю, что вы ищете что-то вроде этого:

заметить разницу между этими двумя примерами:

//working 
var myNamespace = (function($) { 
    $(function(){ 
     var init = (function(){ 
      var text = document.createTextNode("Everything's ready!"); 
      document.body.appendChild(text); 
     })(); 
    }); 

}(jQuery)); 

//Error: Cannot call method 'appendChild' of null 
var myNamespace = (function($) { 

     var init = (function(){ 
      var text = document.createTextNode("Everything's ready!"); 
      document.body.appendChild(text); 
     })(); 


}(jQuery)); 

Хотя, здесь происходит то, что init() фактически недоступен ничем другим в пространстве имен, потому что это происходит после загрузки DOM.

Тем не менее, это близко к тому, что у вас возникли проблемы с, я думаю ...

Я предполагаю, что вы хотите, DOM готовой оболочки внутри модуля для организационных целей.

Также обратите внимание, что у вас есть доступ к модулю, как обычно снаружи модуля:

//appends to the body: "Everything's ready!undefined 
var myNamespace = (function($) { 
    var private = " Hello world"; 
     $(function(){ 
      var hello =(function(){ 
       var text = document.createTextNode("Everything's ready!" +myNamespace.private); 
       document.body.appendChild(text); 
      }()); 
     }); 

    return{ 
     public: " Hello World" 
    } 

}(jQuery)); 



//works as expected 
    var myNamespace = (function($) {  
    var private = " Hello world"; 
    $(function(){ 
     var hello =(function(){ 
     var text = document.createTextNode("Everything's ready!" +myNamespace.public); 
     document.body.appendChild(text); 
     }()); 
    }); 

    return{ 
     public: " Hello World" 
    } }(jQuery));