ก่อนอื่นฉันต้องการพูดคุยเกี่ยวกับการโหลดและการดำเนินการของ JavaScript โดยทั่วไปแล้วเบราว์เซอร์มีคุณสมบัติหลักสองประการสำหรับการดำเนินการ JavaScript: 1) ดำเนินการทันทีหลังจากโหลด 2) มันจะบล็อกเนื้อหาที่ตามมาของหน้า (รวมถึงการแสดงผลหน้าและการดาวน์โหลดทรัพยากรอื่น ๆ ) ในระหว่างการดำเนินการ ดังนั้นหากมีการเปิดตัวไฟล์ JS หลายไฟล์ดังนั้นสำหรับเบราว์เซอร์ไฟล์ JS เหล่านี้จะถูกโหลดแบบอนุกรมและดำเนินการตามลำดับ
เนื่องจาก JavaScript อาจใช้งานทรี DOM ของเอกสาร HTML เบราว์เซอร์โดยทั่วไปจะไม่ดาวน์โหลดไฟล์ CSS ในแบบขนานเช่นการดาวน์โหลดแบบขนานเนื่องจากสิ่งนี้เกิดจากไฟล์ JS โดยเฉพาะ ดังนั้นหากจาวาสคริปต์ของคุณต้องการใช้งานองค์ประกอบ DOM ที่ตามมาโดยทั่วไปเบราว์เซอร์จะรายงานข้อผิดพลาดโดยบอกว่าไม่พบวัตถุ เพราะเมื่อ JavaScript ถูกเรียกใช้งาน HTML ที่อยู่ด้านหลังจะถูกบล็อกและไม่มีโหนด DOM อยู่ด้านหลังแผนผัง DOM ดังนั้นโปรแกรมจึงถูกรายงานว่าเป็นข้อผิดพลาด
วิธีดั้งเดิม
ดังนั้นเมื่อคุณเขียนรหัสต่อไปนี้ในรหัส:
การคัดลอกรหัสมีดังนี้:
<script type = "text/javascript"
src = "http://coolshell.cn/asyncjs/alert.js"> </script>
โดยทั่วไปแท็ก <Script> ในหัวจะบล็อกการโหลดทรัพยากรที่ตามมาและการสร้างทั้งหน้า ฉันได้ทำตัวอย่างพิเศษที่คุณสามารถดูได้: ตัวอย่าง 1. หมายเหตุ: มีเพียงหนึ่งประโยคในการแจ้งเตือนของฉัน Js: การแจ้งเตือน ("Hello World") ซึ่งทำให้คุณดูได้ง่ายขึ้นว่า JavaScript บล็อกสิ่งที่อยู่เบื้องหลังได้อย่างไร
ดังนั้นคุณจะรู้ว่าทำไมเว็บไซต์หลายแห่งจึงวาง JavaScript ไว้ที่ส่วนท้ายของหน้าเว็บไม่ว่าจะใช้กิจกรรมเช่น window.onload หรือ Docmuemt พร้อม
นอกจากนี้เนื่องจากรหัส JavaScript ส่วนใหญ่ไม่จำเป็นต้องรอหน้าเว็บเราจึงโหลดฟังก์ชั่นแบบอะซิงโครนัส แล้วเราจะโหลดแบบอะซิงโครนัสได้อย่างไร?
document.write method
ดังนั้นคุณอาจคิดว่า document.write () สามารถแก้ปัญหาที่ไม่บล็อก แน่นอนคุณจะคิดว่าหลังจาก document.write <script> แท็กสามารถดำเนินการได้สิ่งต่อไปนี้สามารถดำเนินการได้ซึ่งถูกต้อง นี่เป็นจริงสำหรับรหัส JavaScript ในแท็กสคริปต์เดียวกัน แต่สำหรับทั้งหน้าสิ่งนี้จะยังคงบล็อกอยู่ นี่คือรหัสทดสอบ:
การคัดลอกรหัสมีดังนี้:
<script type = "text/javascript" language = "JavaScript">
ฟังก์ชั่น loadjs (script_filename) {
document.write ('<' + 'script language = "JavaScript" type = "text/javascript"');
document.write ('src = "' + script_filename + '">');
document.write ('<'+'/สคริปต์'+'>');
การแจ้งเตือน ("loadjs () ออก ... ");
-
var script = 'http://coolshell.cn/asyncjs/alert.js';
loadjs (สคริปต์);
การแจ้งเตือน ("loadjs () เสร็จสิ้น!");
</script>
<script type = "text/javascript" language = "JavaScript">
การแจ้งเตือน ("บล็อกอื่น");
</script>
คุณคิดว่าลำดับการแจ้งเตือนคืออะไร? คุณสามารถลองใช้ในเบราว์เซอร์ที่แตกต่างกัน นี่คือหน้าทดสอบที่คุณต้องการปิด: ตัวอย่างที่ 2
คุณสมบัติเลื่อนและ async ของสคริปต์
IE ได้รองรับแท็กเลื่อนเวลาตั้งแต่ IE6 เช่น:
การคัดลอกรหัสมีดังนี้:
<script defer type = "text/javascript" src = "./ alert.js">
</script>
สำหรับ IE แท็กนี้จะอนุญาตให้ IE ดาวน์โหลดไฟล์ JS ในแบบขนานและค้างไว้ค้างไว้จนกว่าการโหลด DOM ทั้งหมดจะเสร็จสมบูรณ์ (DomContentLoaded) การเลื่อนเวลาหลายครั้ง <Script> จะทำงานตามลำดับที่ปรากฏเมื่อดำเนินการ สิ่งที่สำคัญที่สุดคือหลังจากการเลื่อนเลื่อนลงใน <Script> มันจะไม่บล็อกการแสดงผลของ DOM ที่ตามมา อย่างไรก็ตามเนื่องจากการเลื่อนเวลานี้ใช้สำหรับ IE เท่านั้นจึงใช้โดยทั่วไปน้อยกว่า
HTML5 มาตรฐานของเรายังเพิ่มแอตทริบิวต์ที่โหลด JavaScript แบบอะซิงโครนัส: Async ไม่ว่าคุณจะกำหนดค่าใดให้กับมันตราบใดที่มันปรากฏขึ้นมันจะเริ่มโหลดไฟล์ js แบบอะซิงโครนัส อย่างไรก็ตามการโหลดแบบ async จะมีปัญหาร้ายแรงนั่นคือมันใช้ "ดำเนินการทันทีหลังจากโหลด" ดังนั้นแม้ว่ามันจะไม่ปิดกั้นการเรนเดอร์ของหน้าคุณไม่สามารถควบคุมคำสั่งและเวลาของการดำเนินการได้ คุณสามารถดูตัวอย่างนี้เพื่อสัมผัสได้
เบราว์เซอร์ที่รองรับแท็ก Async คือ: Firefox 3.6+, Chrome 8.0+, Safari 5.0+, IE 10+, Opera ไม่รองรับ (จากที่นี่) ดังนั้นวิธีนี้ก็ไม่ดีเช่นกัน เพราะเบราว์เซอร์ไม่สามารถทำได้
สร้าง DOM แบบไดนามิกแบบไดนามิก
วิธีนี้น่าจะใช้มากที่สุด
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น loadjs (script_filename) {
var script = document.createElement ('script');
script.setAttribute ('type', 'text/javascript');
script.setAttribute ('src', script_filename);
script.setAttribute ('id', 'coolshell_script_id');
script_id = document.getElementById ('coolshell_script_id');
if (script_id) {
document.getElementByTagname ('head') [0] .removeChild (script_id);
-
document.getElementByTagname ('head') [0] .AppendChild (สคริปต์);
-
var script = 'http://coolshell.cn/asyncjs/alert.js';
loadjs (สคริปต์);
วิธีนี้เกือบจะกลายเป็นวิธีแบบอะซิงโครนัสมาตรฐานในการโหลดไฟล์ JS สำหรับการสาธิตวิธีนี้โปรดดูที่: ตัวอย่างที่ 3 วิธีนี้ยังเล่นกับสิ่ง JSONP นั่นคือฉันสามารถระบุสคริปต์พื้นหลัง (เช่น PHP) สำหรับสคริปต์ SRC และ PHP นี้ส่งคืนฟังก์ชัน JavaScript ซึ่งพารามิเตอร์เป็นสตริง JSON คุณสามารถดูตัวอย่างนี้ได้: T.JS (ตัวอย่างนี้เป็นตัวอย่างเล็ก ๆ ของการโทร Ajax แบบอะซิงโครนัสที่ฉันรวบรวมบน Weibo มาก่อน)
โหลด JS แบบอะซิงโครนัสตามความต้องการ
ตัวอย่างข้างต้นของวิธี DOM แก้ปัญหาของการโหลดแบบอะซิงโครนัสของ JavaScript แต่ไม่ได้แก้ปัญหาที่เราต้องการให้ทำงานในเวลาที่เราระบุ ดังนั้นเราเพียงแค่ต้องผูกเมธอด DOM ข้างต้นกับเหตุการณ์บางอย่าง
ตัวอย่างเช่น:
เชื่อมโยงกับ Window.load Event - ตัวอย่างที่ 4
คุณต้องเปรียบเทียบความแตกต่างในการดำเนินการระหว่างตัวอย่างที่ 4 และตัวอย่าง 3 ในตัวอย่างทั้งสองฉันใช้ JavaScript เป็นพิเศษกับรหัสที่เน้นเพื่อดูการดำเนินการของสคริปต์ด้วยการเน้นรหัสและการดำเนินการของการแจ้งเตือนของฉัน คุณจะรู้ความแตกต่าง)
การคัดลอกรหัสมีดังนี้:
window.load = loadjs ("http://coolshell.cn/asyncjs/alert.js")
เชื่อมโยงกับเหตุการณ์เฉพาะ - ตัวอย่างที่ 5
การคัดลอกรหัสมีดังนี้:
<p style = "เคอร์เซอร์: ตัวชี้" onclick = "loadjs ()"> คลิกเพื่อโหลด alert.js </p>
ตัวอย่างนี้ง่ายมาก เฉพาะเมื่อคุณคลิกที่องค์ประกอบ DOM จะทำการแจ้งเตือน Js ของเราจะถูกโหลดจริง
มากกว่า
อย่างไรก็ตามการเชื่อมโยงกับเหตุการณ์เฉพาะดูเหมือนว่าจะผ่านไปเล็กน้อยเนื่องจากการดาวน์โหลดจริงของ JS จะเสร็จสิ้นเมื่อคลิกซึ่งจะช้าเกินไปอีกครั้ง โอเคที่นี่เราต้องโยนปัญหาที่ดีที่สุดของเรา - เราต้องการดาวน์โหลดไฟล์ js แบบอะซิงโครนัสไปยังพื้นที่ท้องถิ่นของผู้ใช้ แต่ไม่ดำเนินการเฉพาะในกรณีที่เราต้องการดำเนินการ
มันจะดีถ้าเรามีวิธีการดังต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
var script = document.createElement ("สคริปต์");
script.noExecute = true;
script.src = "Alert.js";
document.body.appendchild (สคริปต์);
// เราสามารถทำได้ในภายหลัง
script.execute ();
น่าเสียดายที่นี่เป็นเพียงความฝันที่สวยงาม วันนี้ JavaScript ของเรายังคงค่อนข้างดั้งเดิมและ "JS Dream" นี้ยังไม่ได้รับการรับรู้
ดังนั้นโปรแกรมเมอร์ของเราสามารถใช้แฮ็คเพื่อทำมันได้เท่านั้น
โปรแกรมเมอร์บางตัวใช้ประเภทสคริปต์ที่ไม่ได้มาตรฐานเพื่อแคช JavaScript ชอบ:
การคัดลอกรหัสมีดังนี้:
<script type = cache/script src = "./ alert.js"> </script>
เนื่องจาก "แคช/สคริปต์" สิ่งนี้ไม่สามารถแยกวิเคราะห์ได้โดยเบราว์เซอร์เลยดังนั้นเบราว์เซอร์จึงไม่สามารถเรียกใช้งาน Alert.js เป็น JavaScript ได้ แต่ต้องดาวน์โหลดไฟล์ JS ดังนั้นจึงสามารถทำได้ น่าเสียดายที่ WebKit ปฏิบัติตามมาตรฐาน HTML อย่างเคร่งครัด - สำหรับสิ่งที่ไม่รู้จักเช่นนั้นพวกเขาจะลบโดยตรงและไม่ทำอะไรเลย ดังนั้นความฝันของเราก็พังอีกครั้ง
ดังนั้นเราต้องแฮ็คอีกเล็กน้อย เช่นเดียวกับ N เล่นภาพล่วงหน้าเมื่อหลายปีก่อนเราสามารถใช้แท็กวัตถุ (หรือแท็ก iframe) ดังนั้นเราจึงมีรหัสต่อไปนี้:
การคัดลอกรหัสมีดังนี้:
ฟังก์ชัน cachejs (script_filename) {
var cache = document.createElement ('Object');
cache.data = script_filename;
cache.id = "coolshell_script_cache_id";
cache.width = 0;
CACHE.HEIGHT = 0;
document.body.appendchild (แคช);
-
จากนั้นเราเรียกฟังก์ชั่นนี้ในตอนท้าย โปรดดูตัวอย่างที่เกี่ยวข้อง: ตัวอย่างที่ 6
กด Ctrl+shit+I ภายใต้ Chrome สลับไปที่หน้าเครือข่ายและคุณจะเห็นว่าการ Alert.js ได้รับการดาวน์โหลด แต่ยังไม่ได้ดำเนินการ จากนั้นเราใช้วิธีการของตัวอย่างที่ 5 เนื่องจากด้านเบราว์เซอร์มีแคช Alert.js จะไม่ถูกดาวน์โหลดจากเซิร์ฟเวอร์อีกต่อไป ดังนั้นความเร็วในการดำเนินการสามารถรับประกันได้
คุณควรคุ้นเคยกับการโหลดล่วงหน้าแบบนี้ นอกจากนี้คุณยังสามารถใช้วิธีการ AJAX เช่น:
การคัดลอกรหัสมีดังนี้:
var xhr = ใหม่ xmlhttprequest ();
xhr.open ('get', 'new.js');
xhr.send ('');
ฉันจะไม่พูดมากขึ้นและยกตัวอย่างที่นี่ คุณสามารถลองด้วยตัวเอง
ในที่สุดขอพูดถึง JS สองตัวหนึ่งตัวคือ ControlJs และอีกอันคือ headjs ซึ่งใช้เป็นพิเศษเพื่อสร้างไฟล์จาวาสคริปต์แบบอะซิงโครนัส
ตกลงนี่คือเนื้อหาทั้งหมด ฉันหวังว่าคุณจะมีความเข้าใจในการโหลดและการดำเนินการของ JavaScript รวมถึงเทคโนโลยีที่เกี่ยวข้องหลังจากอ่าน ในเวลาเดียวกันฉันก็หวังว่าผู้เชี่ยวชาญด้านส่วนหน้าจะให้คำแนะนำกับคุณ!