non-jQuery เทียบเท่า$(document).ready()
คืออะไร?
$(document).ready()
- books.google.com/... นอกจากนี้ยังใช้การaddEvent
เชื่อมโยงเหตุการณ์ที่เป็นนามธรรมซึ่งเขียนโดย Dean Edwards ซึ่งเป็นรหัสที่อยู่ในหนังสือด้วยเช่นกัน :)
non-jQuery เทียบเท่า$(document).ready()
คืออะไร?
$(document).ready()
- books.google.com/... นอกจากนี้ยังใช้การaddEvent
เชื่อมโยงเหตุการณ์ที่เป็นนามธรรมซึ่งเขียนโดย Dean Edwards ซึ่งเป็นรหัสที่อยู่ในหนังสือด้วยเช่นกัน :)
คำตอบ:
สิ่งที่ดีเกี่ยวก็คือว่ามันยิงก่อน$(document).ready()
window.onload
ฟังก์ชั่นโหลดรอจนกระทั่งทุกอย่างถูกโหลดรวมถึงเนื้อหาภายนอกและรูปภาพ $(document).ready
อย่างไรก็ตามจะยิงเมื่อต้นไม้ DOM เสร็จสมบูรณ์และสามารถจัดการได้ หากคุณต้องการให้ DOM พร้อมใช้งานโดยไม่มี jQuery คุณอาจเช็คอินไลบรารีนี้ มีคนดึงready
ส่วนจาก jQuery มันเล็กและดีและคุณอาจพบว่ามันมีประโยชน์:
มันทำงานได้อย่างสมบูรณ์แบบจาก ECMA
document.addEventListener("DOMContentLoaded", function() {
// code...
});
window.onload
ไม่เท่ากับ JQuery $(document).ready
เพราะ$(document).ready
รอเพียงเพื่อ DOM ต้นไม้ในขณะที่การwindow.onload
ตรวจสอบองค์ประกอบทั้งหมดรวมถึงสินทรัพย์ภายนอกและภาพ
แก้ไข : เพิ่ม IE8 และเทียบเท่าที่เก่ากว่าขอบคุณการสังเกตของJan Derk คุณสามารถอ่านซอร์สของรหัสนี้บน MDN ที่ลิงค์นี้ :
// alternative to DOMContentLoaded
document.onreadystatechange = function () {
if (document.readyState == "interactive") {
// Initialize your application or run some code.
}
}
มีตัวเลือกอื่น ๆ "interactive"
ที่นอกเหนือจาก ดูลิงค์MDNสำหรับรายละเอียด
document.addEventListener("DOMContentLoaded",function(){console.log(123)})
ลองเลย
สิ่งเล็ก ๆ น้อย ๆ ที่ฉันรวบรวมเข้าด้วยกัน
domready.js
(function(exports, d) {
function domReady(fn, context) {
function onReady(event) {
d.removeEventListener("DOMContentLoaded", onReady);
fn.call(context || exports, event);
}
function onReadyIe(event) {
if (d.readyState === "complete") {
d.detachEvent("onreadystatechange", onReadyIe);
fn.call(context || exports, event);
}
}
d.addEventListener && d.addEventListener("DOMContentLoaded", onReady) ||
d.attachEvent && d.attachEvent("onreadystatechange", onReadyIe);
}
exports.domReady = domReady;
})(window, document);
วิธีใช้งาน
<script src="domready.js"></script>
<script>
domReady(function(event) {
alert("dom is ready!");
});
</script>
นอกจากนี้คุณยังสามารถเปลี่ยนบริบทที่การเรียกกลับทำงานได้โดยผ่านอาร์กิวเมนต์ที่สอง
function init(event) {
alert("check the console");
this.log(event);
}
domReady(init, console);
ตอนนี้เป็นปี 2018 นี่เป็นวิธีที่ง่ายและรวดเร็ว
สิ่งนี้จะเพิ่มผู้ฟังเหตุการณ์ แต่ถ้ามันถูกไล่ออกไปแล้วเราจะตรวจสอบว่าโดมอยู่ในสถานะพร้อมหรือเสร็จสมบูรณ์ สิ่งนี้สามารถดำเนินการก่อนหรือหลังทรัพยากรย่อยเสร็จสิ้นการโหลด (รูปภาพสไตล์ชีตเฟรม ฯลฯ )
function domReady(fn) {
// If we're early to the party
document.addEventListener("DOMContentLoaded", fn);
// If late; I mean on time.
if (document.readyState === "interactive" || document.readyState === "complete" ) {
fn();
}
}
domReady(() => console.log("DOM is ready, come and get it!"));
ต่อไปนี้เป็นผู้ช่วยด้านอรรถประโยชน์อย่างรวดเร็วที่ใช้การนำเข้าและส่งออกมาตรฐาน ES6 ฉันเขียนที่มี TypeScript ด้วย บางทีฉันอาจได้รับรอบในการทำให้ไลบรารีเหล่านี้อย่างรวดเร็วที่สามารถติดตั้งลงในโครงการเป็นการอ้างอิง
export const domReady = (callBack) => {
if (document.readyState === "loading") {
document.addEventListener('DOMContentLoaded', callBack);
}
else {
callBack();
}
}
export const windowReady = (callBack) => {
if (document.readyState === 'complete') {
callBack();
}
else {
window.addEventListener('load', callBack);
}
}
export const domReady = (callBack: () => void) => {
if (document.readyState === "loading") {
document.addEventListener('DOMContentLoaded', callBack);
}
else {
callBack();
}
}
export const windowReady = (callBack: () => void) => {
if (document.readyState === 'complete') {
callBack();
}
else {
window.addEventListener('load', callBack);
}
}
export const domReady = new Promise(resolve => {
if (document.readyState === "loading") {
document.addEventListener('DOMContentLoaded', resolve);
}
else {
resolve();
}
});
export const windowReady = new Promise(resolve => {
if (document.readyState === 'complete') {
resolve();
}
else {
window.addEventListener('load', resolve);
}
});
ตามhttp://youmightnotneedjquery.com/#readyทดแทนที่ดีที่ยังคงทำงานร่วมกับ IE8 คือ
function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', fn);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState != 'loading')
fn();
});
}
}
// test
window.ready(function() {
alert('it works');
});
การปรับปรุง : โดยส่วนตัวฉันจะตรวจสอบว่าประเภทของfn
ฟังก์ชั่น และเช่นเดียวกับ@elliottreganแนะนำให้ลบ listener เหตุการณ์หลังการใช้งาน
เหตุผลที่ฉันตอบคำถามนี้ล่าช้าเนื่องจากฉันค้นหาคำตอบนี้ แต่หาไม่พบที่นี่ และฉันคิดว่านี่เป็นทางออกที่ดีที่สุด
มีการแทนที่ตามมาตรฐานDOMContentLoaded ที่รองรับเบราว์เซอร์มากกว่า 90% + แต่ไม่ใช่ IE8 (ดังนั้นด้านล่างรหัสใช้โดย JQuery สำหรับการสนับสนุนเบราว์เซอร์) :
document.addEventListener("DOMContentLoaded", function(event) {
//do work
});
ฟังก์ชั่นพื้นฐานของ jQueryนั้นซับซ้อนกว่าเพียงแค่ window.onload ดังที่แสดงด้านล่าง
function bindReady(){
if ( readyBound ) return;
readyBound = true;
// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", function(){
document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
jQuery.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", function(){
if ( document.readyState === "complete" ) {
document.detachEvent( "onreadystatechange", arguments.callee );
jQuery.ready();
}
});
// If IE and not an iframe
// continually check to see if the document is ready
if ( document.documentElement.doScroll && window == window.top ) (function(){
if ( jQuery.isReady ) return;
try {
// If IE is used, use the trick by Diego Perini
// http://javascript.nwbox.com/IEContentLoaded/
document.documentElement.doScroll("left");
} catch( error ) {
setTimeout( arguments.callee, 0 );
return;
}
// and execute any waiting functions
jQuery.ready();
})();
}
// A fallback to window.onload, that will always work
jQuery.event.add( window, "load", jQuery.ready );
}
DOMContentLoaded
และload
ใช้งานอีเวนต์เท่านั้นaddEventListener
และก่อนอื่นนั้นไฟจะลบทั้งผู้ฟังดังนั้นจึงไม่ต้องเปิดสองครั้ง
ใน vanilla JavaScript ธรรมดาไม่มีไลบรารี่? มันเป็นข้อผิดพลาด$
เป็นเพียงตัวระบุและไม่ได้กำหนดเว้นแต่คุณจะกำหนดไว้
jQuery กำหนด$
ว่าเป็น "วัตถุทุกอย่าง" ของตัวเอง (หรือที่รู้จักกันในชื่อjQuery
เพื่อให้คุณสามารถใช้งานได้โดยไม่ขัดแย้งกับห้องสมุดอื่น) หากคุณไม่ได้ใช้ jQuery (หรือไลบรารีอื่นที่กำหนดไว้) $
จะไม่ถูกกำหนด
หรือคุณกำลังถามสิ่งที่เทียบเท่าใน JavaScript ธรรมดา? ในกรณีนี้คุณอาจต้องการwindow.onload
ซึ่งไม่เทียบเท่ากัน แต่เป็นวิธีที่เร็วและง่ายที่สุดในการเข้าใกล้เอฟเฟกต์เดียวกันใน vanilla JavaScript
วิธีที่ง่ายที่สุดในเบราว์เซอร์ที่ผ่านมาจะใช้ที่เหมาะสมGlobalEventHandlers , onDOMContentLoaded , onload , onloadeddata ( ... )
onDOMContentLoaded = (function(){ console.log("DOM ready!") })()
onload = (function(){ console.log("Page fully loaded!") })()
onloadeddata = (function(){ console.log("Data loaded!") })()
เหตุการณ์ DOMContentLoaded จะเริ่มทำงานเมื่อเอกสาร HTML เริ่มต้นถูกโหลดและวิเคราะห์โดยสมบูรณ์โดยไม่ต้องรอสไตล์ชีทรูปภาพและเฟรมย่อยเพื่อให้การโหลดเสร็จสิ้น การโหลดเหตุการณ์ที่แตกต่างกันมากควรใช้เพื่อตรวจจับหน้าเว็บที่โหลดเต็มเท่านั้น มันเป็นความผิดพลาดที่ได้รับความนิยมอย่างไม่น่าเชื่อในการใช้โหลดโดยที่ DOMContentLoaded จะมีความเหมาะสมมากกว่าดังนั้นควรระมัดระวัง
https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
ฟังก์ชั่นที่ใช้คือ IIFE ซึ่งมีประโยชน์มากในกรณีนี้เพราะมันจะกระตุ้นตัวเองเมื่อพร้อม:
https://en.wikipedia.org/wiki/Immediately-invoked_function_expression
เห็นได้ชัดว่าเหมาะสมกว่าที่จะวางไว้ที่ส่วนท้ายของสคริปต์ใด ๆ
ใน ES6 เราสามารถเขียนเป็นฟังก์ชันลูกศรได้ด้วย:
onload = (() => { console.log("ES6 page fully loaded!") })()
ที่ดีที่สุดคือการใช้องค์ประกอบ DOM เราสามารถรอตัวแปรใด ๆ ให้พร้อมที่จะเรียกใช้ IIFE ที่เป็นลูกศร
พฤติกรรมจะเหมือนกัน แต่มีผลกระทบต่อหน่วยความจำน้อยกว่า
ในหลายกรณีวัตถุเอกสารจะเปิดขึ้นมาเมื่อพร้อมอย่างน้อยในเบราว์เซอร์ของฉัน ไวยากรณ์นั้นดีมาก แต่ก็ต้องการการทดสอบเพิ่มเติมเกี่ยวกับความเข้ากันได้
document=(()=>{ /*Ready*/ })()
เนื้อความโหลดอาจเป็นทางเลือกเช่นกัน:
<html>
<head><title>Body onLoad Exmaple</title>
<script type="text/javascript">
function window_onload() {
//do something
}
</script>
</head>
<body onLoad="window_onload()">
</body>
</html>
$(document).ready()
เหตุการณ์ของ jQuery โดยไม่ต้องใช้ห้องสมุดใด ๆ ให้ดูที่: stackoverflow.com/questions/1795089/…