Редактировать:
function ready(callback){
// in case the document is already rendered
if (document.readyState!='loading') callback();
// modern browsers
else if (document.addEventListener) document.addEventListener('DOMContentLoaded', callback);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
if (document.readyState=='complete') callback();
});
}
ready(function(){
// do something
});
Взято из https://plainjs.com/javascript/events/running-code -when-the-document-is-ready-15 /
Поскольку принятый ответ был очень далек от завершения, я сшил вместе «готовую» функцию, такую как jQuery.ready()
на jQuery 1.6.2 source:
var ready = (function(){
var readyList,
DOMContentLoaded,
class2type = {};
class2type["[object Boolean]"] = "boolean";
class2type["[object Number]"] = "number";
class2type["[object String]"] = "string";
class2type["[object Function]"] = "function";
class2type["[object Array]"] = "array";
class2type["[object Date]"] = "date";
class2type["[object RegExp]"] = "regexp";
class2type["[object Object]"] = "object";
var ReadyObj = {
// Is the DOM ready to be used? Set to true once it occurs.
isReady: false,
// A counter to track how many items to wait for before
// the ready event fires. See #6781
readyWait: 1,
// Hold (or release) the ready event
holdReady: function( hold ) {
if ( hold ) {
ReadyObj.readyWait++;
} else {
ReadyObj.ready( true );
}
},
// Handle when the DOM is ready
ready: function( wait ) {
// Either a released hold or an DOMready/load event and not yet ready
if ( (wait === true && !--ReadyObj.readyWait) || (wait !== true && !ReadyObj.isReady) ) {
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
if ( !document.body ) {
return setTimeout( ReadyObj.ready, 1 );
}
// Remember that the DOM is ready
ReadyObj.isReady = true;
// If a normal DOM Ready event fired, decrement, and wait if need be
if ( wait !== true && --ReadyObj.readyWait > 0 ) {
return;
}
// If there are functions bound, to execute
readyList.resolveWith( document, [ ReadyObj ] );
// Trigger any bound ready events
//if ( ReadyObj.fn.trigger ) {
// ReadyObj( document ).trigger( "ready" ).unbind( "ready" );
//}
}
},
bindReady: function() {
if ( readyList ) {
return;
}
readyList = ReadyObj._Deferred();
// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
return setTimeout( ReadyObj.ready, 1 );
}
// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
window.addEventListener( "load", ReadyObj.ready, 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", DOMContentLoaded );
// A fallback to window.onload, that will always work
window.attachEvent( "onload", ReadyObj.ready );
// 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 ) {
doScrollCheck();
}
}
},
_Deferred: function() {
var // callbacks list
callbacks = [],
// stored [ context , args ]
fired,
// to avoid firing when already doing so
firing,
// flag to know if the deferred has been cancelled
cancelled,
// the deferred itself
deferred = {
// done( f1, f2, ...)
done: function() {
if ( !cancelled ) {
var args = arguments,
i,
length,
elem,
type,
_fired;
if ( fired ) {
_fired = fired;
fired = 0;
}
for ( i = 0, length = args.length; i < length; i++ ) {
elem = args[ i ];
type = ReadyObj.type( elem );
if ( type === "array" ) {
deferred.done.apply( deferred, elem );
} else if ( type === "function" ) {
callbacks.push( elem );
}
}
if ( _fired ) {
deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
}
}
return this;
},
// resolve with given context and args
resolveWith: function( context, args ) {
if ( !cancelled && !fired && !firing ) {
// make sure args are available (#8421)
args = args || [];
firing = 1;
try {
while( callbacks[ 0 ] ) {
callbacks.shift().apply( context, args );//shifts a callback, and applies it to document
}
}
finally {
fired = [ context, args ];
firing = 0;
}
}
return this;
},
// resolve with this as context and given arguments
resolve: function() {
deferred.resolveWith( this, arguments );
return this;
},
// Has this deferred been resolved?
isResolved: function() {
return !!( firing || fired );
},
// Cancel
cancel: function() {
cancelled = 1;
callbacks = [];
return this;
}
};
return deferred;
},
type: function( obj ) {
return obj == null ?
String( obj ) :
class2type[ Object.prototype.toString.call(obj) ] || "object";
}
}
// The DOM ready check for Internet Explorer
function doScrollCheck() {
if ( ReadyObj.isReady ) {
return;
}
try {
// If IE is used, use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
document.documentElement.doScroll("left");
} catch(e) {
setTimeout( doScrollCheck, 1 );
return;
}
// and execute any waiting functions
ReadyObj.ready();
}
// Cleanup functions for the document ready method
if ( document.addEventListener ) {
DOMContentLoaded = function() {
document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
ReadyObj.ready();
};
} else if ( document.attachEvent ) {
DOMContentLoaded = function() {
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", DOMContentLoaded );
ReadyObj.ready();
}
};
}
function ready( fn ) {
// Attach the listeners
ReadyObj.bindReady();
var type = ReadyObj.type( fn );
// Add the callback
readyList.done( fn );//readyList is result of _Deferred()
}
return ready;
})();
Как использовать:
Я не уверен, насколько функциональен этот код, но он отлично работал с моими поверхностными тестами. Это потребовалось довольно долгое время, поэтому я надеюсь, что вы и другие могут извлечь из этого выгоду.
PS: Я предлагаю компилировать его.
Или вы можете использовать http://dustindiaz.com/smallest-domready-ever :
function r(f){/in/.test(document.readyState)?setTimeout(r,9,f):f()}
r(function(){/*code to run*/});
или встроенная функция, если вам нужно только поддерживать новые браузеры (в отличие от jQuery ready, это не будет работать, если вы добавите это после загрузки страницы)
document.addEventListener('DOMContentLoaded',function(){/*fun code to run*/})
Это не вопрос «да» или «нет». Это вопрос переговоров между вами и вашим клиентом (теми, кто платит вам за создание сайта). Обычно переговоры проходят так: ваш веб-сайт обойдется вам в x долларов и поддерживает браузер a, b, c. Если вам нужна поддержка IE6, это будет $ x + $ y и т. Д. Тогда ваши клиенты позвонят, чтобы решить, стоит ли тратить $ y, чтобы иметь возможность обслуживать тех из своих клиентов, которые настаивают на использовании IE6.
Если вы являетесь собственным клиентом, вы можете вырезать средний бит и позвонить самостоятельно; -)
(то же самое для IE7)
Я бы не стал беспокоиться о поддержке IE6. Он постепенно выводится из употребления (и должен быть обновлен каждым, кто все еще использует его).
Я бы все равно попытался поддерживать IE7, поскольку я думаю, что он все еще в некоторой степени популярен. На сайте всегда может быть что-то с надписью «Этот сайт работает намного лучше в: Firefox / Chrome / Safari / IE8»
Я должен согласиться с теми, кто говорит «это зависит от обстоятельств».
Самая важная часть - это то, что использует аудитория сайта, если они используют IE6, разрабатывая вашу страницу для поддержки IE6.
По моему опыту, вы можете ожидать такую аудиторию:
частный : IE7 + или FF
частный и технический || геймер : IE8, FF, Chrome
Многие до сих пор используют XP с IE6 / 7, если только они не являются техническими специалистами или не используют ПК очень часто.
искусство и дизайн : Safari, FF (часто для Mac)
Маки по-прежнему широко используются в графической среде, и почти у каждого художника и дизайнера есть такой, даже если он просто вписывается в толпу.
пожилые люди : IE6, редко IE7
Windows 95/98 не поддерживает IE7. Вам также следует избегать использования javascript для этой аудитории, поскольку у них обычно дрянные компьютеры.
корпоративный : IE6 / IE7
Многие компании обновляются очень медленно, так как это требует большого количества документов, организации и бюджета. В зависимости от того, кто в корпорации может использовать вашу страницу и какой это тип компании, вы можете ожидать худшего (секретари, низко оплачиваемые рабы и т. Д.) Или лучше (генеральный директор, технический директор и т. Д.).
Обратите внимание, что это не основано на какой-либо статистике, только на моем личном опыте.
Отказаться от IE6 и IE7 было бы неплохо, но коммерческие сайты не могут позволить себе потерять пользователей. Вы, как создатель веб-сайта, не имеете права вообще заставлять пользователей переключать браузеры. В некоторых случаях (например, в корпоративных средах) даже пользователи не имеют полномочий, они могут просто использовать то, что разрешено администраторами. В других случаях они понятия не имеют, как установить что-либо (пожилые люди, дети, ...).
Я использую IE6 до следующего года в крупной глобальной корпоративной среде.
Я хочу потратить несколько миллионов на какое-нибудь новое отличное программное обеспечение. Должен поддерживать IE6 ...
Черт возьми. По крайней мере, с IE6. IE7 не так уж и плох в поддержке. Я занимаюсь веб-разработкой уже довольно давно, и я показываю предупреждение: «Вы используете устаревший браузер. Некоторые части этой веб-страницы могут работать некорректно. Обновите или выберите Firefox», потому что вы можете » Чтобы просто игнорировать этих пользователей, вы должны предоставить им возможность.