Порядок очереди jQuery для нескольких документов

Я знаю, что вызовы $(function(){ }) в jQuery выполняются в том порядке, в котором они определены, но мне интересно, можете ли вы управлять порядком очереди?

Например, можно ли вызвать "Hello World 2" перед "Hello World 1":

$(function(){ alert('Hello World 1') });
$(function(){ alert('Hello World 2') });

Вопрос в том, возможно ли это... Я уже знаю, что это противоречит лучшей практике;)

4 ответа

Решение

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

http://github.com/jquery/jquery/blob/master/src/core.js#L47

Вот как вы будете делать это:

// lower priority value means function should be called first
var method_queue = new Array();

method_queue.push({
  method : function()
  { 
    alert('Hello World 1');
  },
  priority : 2
});

method_queue.push({
  method : function()
  { 
    alert('Hello World 2');
  },
  priority : 1
});


function sort_queue(a, b)
{
  if( a.priority < b.priority ) return -1;
  else if( a.priority == b.priority ) return 0;
  else return 1;  
}

function execute_queue()
{
  method_queue.sort( sort_queue );

  for( var i in method_queue ) method_queue[i].call( null );
}

// now all you have to do is 
execute_queue();

Вы можете прочитать больше об этом здесь

Вы можете использовать обещание jQuery для достижения чего-то подобного.

Ниже приведен пример, в котором jQuery.ready.promise помогает управлять порядком выполнения блоков DOM Ready:

  1. В следующем примере первый блок DOM Ready пытается получить доступ к высоте тестового элемента div, которая добавляется к телу в последующем блоке DOM Ready. Как и в скрипке, он не может его получить.

    jQuery(function () {
        var testDivHeight = jQuery("#test-div").outerHeight();
        if(testDivHeight) {
            alert("Height of test div is: "+testDivHeight);
        } else {
            alert("Sorry I cannot get the height of test div!");
        }
    });
    jQuery(function () {
        jQuery('body').append('<div style="background: #C00; height: 100px;" id="test-div"></div>');
    });
    

    Скрипка: http://jsfiddle.net/geektantra/qSHec/

  2. В следующем примере это делается точно так же, как в примере перед использованием jQuery.ready.promise. Как и в Fiddle, он работает как требуется.

    jQuery(function () {
        jQuery.ready.promise().done(function () {
            var testDivHeight = jQuery("#test-div").outerHeight();
            if(testDivHeight) {
                alert("Height of test div is: "+testDivHeight);
            } else {
                alert("Sorry I cannot get the height of test div!");
            }
        });
    });
    jQuery(function () {
        jQuery('body').append('<div style="background: #C00; height: 100px;" id="test-div"></div>');
    });
    

    Скрипка: http://jsfiddle.net/geektantra/48bRT/

Это можно сделать, но не легко. Вам, вероятно, придется взломать сам jQuery. Прежде чем jQuery начнет вызывать эти функции внутри while цикл, вам нужно было бы добавить код для проверки readyList массив и изменить порядок элементов в соответствии с вашими предпочтениями.

Другие вопросы по тегам