2010-08-07 3 views
10

Мне нужно дождаться готовности документа в моем JavaScript, чтобы вставить div в нижней части тела.

Я хочу:

  • делают этот JavaScript файл как можно (компилировать его до < 1KB, если это возможно)
  • инлайн код, который обеспечивает документ readyness в затворе (без его экспорта)

Вложение всего источника jQuery в мой файл будет слишком большим, поэтому я ищу другие методы. window.onload будет работать, но я специально хочу готовность к документу, а не ждать события window.onload.

Кто-нибудь знает фрагмент JS, который может это сделать? Или мне нужно просто скопировать часть источника jQuery?

EDIT:

мне удалось подползти источник JQuery и положить вместе со следующим фрагментом:

var ready = (function() { 
    var ready_event_fired = false; 
    var ready_event_listener = function (fn) { 

     // Create an idempotent version of the 'fn' function 
     var idempotent_fn = function() { 
      if (ready_event_fired) { 
       return; 
      } 
      ready_event_fired = true; 
      return fn(); 
     } 

     // The DOM ready check for Internet Explorer 
     var do_scroll_check = function() { 
      if (ready_event_fired) { 
       return; 
      } 

      // If IE is used, use the trick by Diego Perini 
      // http://javascript.nwbox.com/IEContentLoaded/ 
      try { 
       document.documentElement.doScroll('left'); 
      } catch(e) { 
       setTimeout(do_scroll_check, 1); 
       return; 
      } 

      // Execute any waiting functions 
      return idempotent_fn(); 
     } 

     // If the browser ready event has already occured 
     if (document.readyState === "complete") { 
      return idempotent_fn() 
     } 

     // Mozilla, Opera and webkit nightlies currently support this event 
     if (document.addEventListener) { 

      // Use the handy event callback 
      document.addEventListener("DOMContentLoaded", idempotent_fn, false); 

      // A fallback to window.onload, that will always work 
      window.addEventListener("load", idempotent_fn, false); 

     // If IE event model is used 
     } else if (document.attachEvent) { 

      // ensure firing before onload; maybe late but safe also for iframes 
      document.attachEvent("onreadystatechange", idempotent_fn); 

      // A fallback to window.onload, that will always work 
      window.attachEvent("onload", idempotent_fn); 

      // If IE and not a frame: continually check to see if the document is ready 
      var toplevel = false; 

      try { 
       toplevel = window.frameElement == null; 
      } catch (e) {} 

      if (document.documentElement.doScroll && toplevel) { 
       return do_scroll_check(); 
      } 
     } 
    }; 
    return ready_event_listener; 
})(); 

// TEST 
var ready_1 = function() { 
    alert("ready 1"); 
}; 
var ready_2 = function() { 
    alert("ready 2"); 
}; 
ready(function() { 
    ready_1(); 
    ready_2(); 
}); 

Большое спасибо за помощь мне найти это в источнике JQuery. Теперь я могу положить все это в закрытие и выполнять свою работу, не экспортируя никаких функций и не загрязняя глобальную сферу.

+2

Вы можете скачать исходники JQuery с сервера Google, которая даст вам хорошее изменение это время cachedd уже. – Pointy

ответ

7

Один из вариантов - просто получить файл jQuery из github.

Возможно, вы могли бы немного похудеть для кода, который вам не нужен. Затем запустите его через компрессор YUI, и он должен быть довольно маленьким.

Я попробовал, и этот код работал правильно:

$(function() { 
    var newDiv = document.createElement('div'); 
    document.getElementsByTagName('body')[0].appendChild(newDiv); 
}); 

Обновление: Это было так мало, как я понял. Это полностью от jQuery и составляет около 1,278 байт (сжато). Должно быть меньше, когда вы gzip.

Только разница в том, что вам нужно позвонить нравится:

$.fn.ready(function() { 
    // your code 
}); 

YUI Сжатый:

(function(){var e=function(i,j){},c=window.jQuery,h=window.$,d,g=false,f=[],b;e.fn={ready:function(i){e.bindReady();if(e.isReady){i.call(document,e)}else{if(f){f.push(i)}}return this}};e.isReady=false;e.ready=function(){if(!e.isReady){if(!document.body){return setTimeout(e.ready,13)}e.isReady=true;if(f){var k,j=0;while((k=f[j++])){k.call(document,e)}f=null}if(e.fn.triggerHandler){e(document).triggerHandler("ready")}}};e.bindReady=function(){if(g){return}g=true;if(document.readyState==="complete"){return e.ready()}if(document.addEventListener){document.addEventListener("DOMContentLoaded",b,false);window.addEventListener("load",e.ready,false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",b);window.attachEvent("onload",e.ready);var i=false;try{i=window.frameElement==null}catch(j){}if(document.documentElement.doScroll&&i){a()}}}};d=e(document);if(document.addEventListener){b=function(){document.removeEventListener("DOMContentLoaded",b,false);e.ready()}}else{if(document.attachEvent){b=function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",b);e.ready()}}}}function a(){if(e.isReady){return}try{document.documentElement.doScroll("left")}catch(i){setTimeout(a,1);return}e.ready()}window.jQuery=window.$=e})(); 

Полный источник (опять же, это jQuery код):

(function() { 
var jQuery = function(selector, context) { 
    }, 
    _jQuery = window.jQuery, 
    _$ = window.$, 

    rootjQuery, 
    readyBound = false, 
    readyList = [], 
    DOMContentLoaded; 

jQuery.fn = { 
    ready: function(fn) { 
     jQuery.bindReady(); 
     if (jQuery.isReady) { 
      fn.call(document, jQuery); 
     } else if (readyList) { 
      readyList.push(fn); 
     } 
     return this; 
    } 
}; 
jQuery.isReady = false; 
jQuery.ready = function() { 
     if (!jQuery.isReady) { 
      if (!document.body) { 
       return setTimeout(jQuery.ready, 13); 
      } 
      jQuery.isReady = true; 
      if (readyList) { 
       var fn, i = 0; 
       while ((fn = readyList[ i++ ])) { 
        fn.call(document, jQuery); 
       } 
       readyList = null; 
      } 
      if (jQuery.fn.triggerHandler) { 
       jQuery(document).triggerHandler("ready"); 
      } 
     } 
    }; 
jQuery.bindReady = function() { 
     if (readyBound) { 
      return; 
     } 
     readyBound = true; 

     if (document.readyState === "complete") { 
      return jQuery.ready(); 
     } 
     if (document.addEventListener) { 
      document.addEventListener("DOMContentLoaded", DOMContentLoaded, false); 
      window.addEventListener("load", jQuery.ready, false); 
     } else if (document.attachEvent) { 

      document.attachEvent("onreadystatechange", DOMContentLoaded); 
      window.attachEvent("onload", jQuery.ready); 

      var toplevel = false; 
      try { 
       toplevel = window.frameElement == null; 
      } catch(e) {} 
      if (document.documentElement.doScroll && toplevel) { 
       doScrollCheck(); 
      } 
     } 
    }; 
rootjQuery = jQuery(document); 
if (document.addEventListener) { 
    DOMContentLoaded = function() { 
     document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false); 
     jQuery.ready(); 
    }; 
} else if (document.attachEvent) { 
    DOMContentLoaded = function() { 
     if (document.readyState === "complete") { 
      document.detachEvent("onreadystatechange", DOMContentLoaded); 
      jQuery.ready(); 
     } 
    }; 
} 
function doScrollCheck() { 
    if (jQuery.isReady) { 
     return; 
    } 
    try { 

     document.documentElement.doScroll("left"); 
    } catch(e) { 
     setTimeout(doScrollCheck, 1); 
     return; 
    } 
    jQuery.ready(); 
} 
window.jQuery = window.$ = jQuery; 
})(); 

Я уверен, что есть еще несколько байтов, которые можно удалить.

Не забывайте:

/*! 
* jQuery JavaScript Library v1.4.2 
* http://jquery.com/ 
* 
* Copyright 2010, John Resig 
* Dual licensed under the MIT or GPL Version 2 licenses. 
* http://jquery.org/license 
*/ 
+0

Спасибо, что указали этот хитрый кусок кода! Я изменил код, чтобы он не экспортировал никаких глобальных переменных, но функциональность такая же. –

+0

@Attila - Добро пожаловать. Единственными глобальными значениями должны быть '$' и 'jQuery'. Конечно, хорошая идея избавиться от '$'. Кроме того, следует включить соответствующую информацию об авторских правах. – user113716

+0

Ahm, спасибо, что напомнил мне включить соответствующую информацию об авторских правах. Я не беру на себя ответственность за это, так как весь фактический код изначально поступает из jQuery, я только переименовал некоторые функции в соответствии со своим вкусом :) –

2

Есть функции several implementations for "DOMReady", но большинство из того, что я могу найти, немного устарели, поэтому я не знаю, как они будут себя вести с IE8 и т. Д.

Я бы порекомендовал использовать jQuery ready(), поскольку я думаю, что он обещает самую кросс-браузерную совместимость. Я не эксперт в исходном коде jQuery, но this кажется правильным местом (строки 812-845 или поиск function bindReady).

0

Вы можете начать с скрипта: http://snipplr.com/view/6029/domreadyjs/, но не оптимизирован (но работает) для последнего Safari, хотя (например, используйте таймер вместо поддерживаемого DOMContentLoaded).