Обработка ошибок в jQuery (document).ready

Я разрабатываю JS, который используется в веб-фреймворке, и часто смешивается с другим кодом jQuery других разработчиков (часто с ошибкой). К сожалению, ошибки в их блоках jQuery (document).ready не позволяют моему исполнению. Возьмем следующий простой пример:

<script type="text/javascript">
    jQuery(document).ready(function() {
        nosuchobject.fakemethod();       //intentionally cause major error
    });
</script>
<script type="text/javascript">
    jQuery(document).ready(function() {
        alert("Hello!");                 //never executed
    });
</script>

Не должен ли второй готовый блок выполняться независимо от того, что произошло в предыдущем? Есть ли "безопасный" способ запуска jQuery (document).ready, который будет работать даже в случае предыдущих ошибок?

EDIT: у меня нет контроля/видимости над блоками, подверженными ошибкам, поскольку они написаны другими авторами и смешаны произвольно.

Ответы

Ответ 1

Я не пробовал этот код, но он должен работать (по крайней мере, идея должна в любом случае). Удостоверьтесь, что вы включили его после jquery, но перед любыми потенциально глючными сценариями. (Не обязательно, см. комментарии.)

var oldReady = jQuery.ready;
jQuery.ready = function(){
  try{
    return oldReady.apply(this, arguments);
  }catch(e){
    // handle e ....
  }
};

Ответ 2

Чтобы ответить на ваш вопрос, оба блока ready по существу объединены в один способ работы jQuery:

<script type="text/javascript">
  jQuery(document).ready(function() {
      nosuchobject.fakemethod();       //intentionally cause major error
      alert("Hello!");                 //never executed
  });
</script>

Итак, почему он не предупреждает об ошибке выше. Я не верю, что есть способ исправить это, чтобы каждая функция ready выполнялась независимо от прежних отказов.

Ответ 3

Вы пытались обернуть команды, подверженные ошибкам, в try... catch brackets?

$(function(){
    try {
        noObject.noMethod();
    } catch (error) {
        // handle error
    }
});

$(function(){
    try {
        alert("Hello World");
    } catch (error) {
        // handle error
    }
});

Чтобы избежать потенциальной путаницы, $(function(){ ... }); функционально совпадает с $(document).ready(function(){ ... });

Ответ 4

Вот решение, оно перенесет любую функцию, отправленную в готовый блок try-catch:

(function($){
    $.fn.oldReady = $.fn.ready;
    $.fn.ready = function(fn){
        return $.fn.oldReady( function(){ try{ if(fn) fn.apply($,arguments); } catch(e){}} );
    }
})(jQuery);

Ответ 5

Вы можете повторно ссылаться на jQuery перед каждым из ваших блоков кода. Затем ваш код будет использовать новый экземпляр библиотеки, и он будет выполнен. Я тестировал это в Safari 4.0.3 на OSX.

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
    <script type="text/javascript">
        jQuery(document).ready(function() {
            nosuchobject.fakemethod();       //intentionally cause major error
        });
    </script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>    
    <script type="text/javascript">
        jQuery(document).ready(function() {
            alert("Hello!");                 //executed!
        });
    </script>   

</head>
<body>

<p>hello world</p>

</body>
</html>