Settimeout ()
เมธอด settimeout () ใช้เพื่อระบุว่าฟังก์ชันหรือสตริงถูกดำเนินการหลังจากจำนวนมิลลิวินาทีที่ระบุ มันส่งคืนจำนวนเต็มแทนหมายเลขของตัวจับเวลาซึ่งสามารถส่งผ่านไปยัง ClearTimeOut () เพื่อยกเลิกการดำเนินการของฟังก์ชั่นนี้
ในรหัสต่อไปนี้คอนโซลเอาต์พุต 0 ก่อนหลังจากประมาณ 1,000ms นั่นคือ 1S ค่าส่งคืนของวิธีการจับเวลา setTimeout () คือเอาต์พุต
var timer = settimeout (function () {console.log (ตัวจับเวลา);}, 1000); console.log (0);นอกจากนี้ยังสามารถเขียนเป็นพารามิเตอร์สตริง เนื่องจากแบบฟอร์มนี้จะทำให้เอ็นจิ้น JavaScript แยกวิเคราะห์สองครั้งลดประสิทธิภาพจึงไม่แนะนำให้ใช้
var timer = settimeout ('console.log (ตัวจับเวลา);', 1000); console.log (0);หากมีการละเว้นพารามิเตอร์ที่สองของ settimeout พารามิเตอร์จะเริ่มต้นเป็น 0
ในรหัสต่อไปนี้ 0 และ 1 ปรากฏบนคอนโซล แต่ 0 อยู่ข้างหน้าและคำถามนี้จะอธิบายในภายหลัง
var timer = settimeout (function () {console.log (ตัวจับเวลา);}); console.log (0);ในความเป็นจริงนอกเหนือจากพารามิเตอร์สองตัวแรกวิธี SetTimeOut () ยังอนุญาตให้เพิ่มพารามิเตอร์เพิ่มเติมซึ่งจะถูกส่งผ่านไปยังฟังก์ชั่นในตัวจับเวลา
ในรหัสต่อไปนี้คอนโซลจะส่งออก 2 หลังจากประมาณ 1,000ms นั่นคือ 1s อย่างไรก็ตาม IE9-Browser อนุญาตให้ SettimeOut มีพารามิเตอร์สองตัวเท่านั้นและไม่รองรับพารามิเตอร์เพิ่มเติม น่านจะถูกส่งออกบนคอนโซล
settimeout (ฟังก์ชั่น (a, b) {console.log (a+b);}, 1,000,1,1);คุณสามารถใช้การถ่ายโอนพารามิเตอร์ IIFE เพื่อเข้ากันได้กับการถ่ายโอนพารามิเตอร์ฟังก์ชัน IE9-Browser
settimeout ((ฟังก์ชั่น (a, b) {return function () {console.log (a+b);}}) (1,1), 1,000);หรือเขียนฟังก์ชั่นนอกตัวจับเวลาจากนั้นฟังก์ชั่นจะถูกเรียกด้วยพารามิเตอร์ในฟังก์ชันที่ไม่ระบุชื่อในตัวจับเวลา
การทดสอบฟังก์ชั่น (a, b) {console.log (a+b);} settimeout (function () {test (1,1);}, 1,000);ชี้ไปที่
กฎการผูกมัดทั้งสี่ที่ชี้ไปที่กลไกนี้ได้รับการแนะนำในรายละเอียดในชุดนี้ เนื่องจากสิ่งนี้ในตัวจับเวลาจะหายไปโดยปริยายและมีแนวโน้มที่จะเกิดข้อผิดพลาดมากจึงจะอธิบายได้อีกครั้งที่นี่
var a = 0; function foo () {console.log (this.a);}; var obj = {a: 2, foo: foo} settimeout (obj.foo, 100); // 0 // เทียบเท่ากับ var a = 0; settimeoutหากคุณต้องการรับค่าคุณสมบัติ A ในวัตถุ OBJ คุณสามารถวางฟังก์ชั่น OBJ.FOO ในฟังก์ชันที่ไม่ระบุชื่อในตัวจับเวลาสำหรับการเชื่อมโยงโดยนัย
var a = 0; function foo () {console.log (this.a);}; var obj = {a: 2, foo: foo} settimeout (ฟังก์ชั่น () {obj.foo ();}, 100); // 2หรือคุณสามารถใช้วิธีการผูกเพื่อผูกมัดวิธีการนี้ของ foo () เพื่อ obj
var a = 0; function foo () {console.log (this.a);}; var obj = {a: 2, foo: foo} settimeout (obj.foo.bind (obj), 100); // 2ClearTimeout ()
ฟังก์ชั่น settimeout ส่งคืนค่าจำนวนเต็มแทนหมายเลขตัวนับส่งจำนวนเต็มไปยังฟังก์ชัน ClearTimeOut โดยยกเลิกตัวจับเวลาที่เกี่ยวข้อง
// หลังจาก 100ms คอนโซลส่งออกค่าส่งคืนของเมธอด settimeout () ตัวจับเวลา 1VAR = settimeout (ฟังก์ชัน () {console.log (ตัวจับเวลา);}, 100);ดังนั้นค่านี้สามารถใช้ในการยกเลิกตัวจับเวลาที่เกี่ยวข้อง
var timer = settimeout (function () {console.log (ตัวจับเวลา);}, 100); ClearTimeout (ตัวจับเวลา);หรือใช้ค่าส่งคืนโดยตรงเป็นพารามิเตอร์
var timer = settimeout (function () {console.log (ตัวจับเวลา);}, 100); ClearTimeout (1);โดยทั่วไปแล้วค่าจำนวนเต็มที่ส่งคืนโดย settimeout นั้นต่อเนื่องนั่นคือค่าจำนวนเต็มที่ส่งคืนโดยวิธีการตั้งถิ่นฐานครั้งที่สองมีขนาดใหญ่กว่าค่าจำนวนเต็มแรก 1
// เอาต์พุตคอนโซล 1, 2, 3VAR Timer1 = settimeout (ฟังก์ชัน () {console.log (timer1);}, 100); var timer2 = settimeout (ฟังก์ชัน () {console.log (timer2);}, 100); var timer3 = settimeoutsetInterval ()
การใช้ setInterval นั้นเหมือนกับ settimeout ความแตกต่างเพียงอย่างเดียวคือ SetInterval ระบุว่างานจะถูกดำเนินการทุกครั้งนั่นคือการดำเนินการตามกำหนดเวลาไม่ จำกัด
<button id = "btn"> 0 </button> <script> var timer = setInterval (function () {btn.innerhtml = number (btn.innerhtml) + 1;}, 1000); btn.onclick = function () {clearinterval (timer);[หมายเหตุ] มาตรฐาน HTML5 กำหนดว่าช่วงเวลาที่สั้นที่สุดของ settimeout คือ 4 มิลลิวินาที; ช่วงเวลาที่สั้นที่สุดของ setInterval คือ 10 มิลลิวินาทีนั่นคือช่วงเวลาน้อยกว่า 10 มิลลิวินาทีจะถูกปรับเป็น 10 มิลลิวินาที
ความถี่รีเฟรชของจอภาพคอมพิวเตอร์ส่วนใหญ่คือ 60Hz ซึ่งเทียบเท่ากับการทาสีใหม่ 60 ครั้งต่อวินาที ดังนั้นช่วงเวลาวนรอบที่ดีที่สุดสำหรับเอฟเฟกต์แอนิเมชั่นที่ราบรื่นที่สุดคือ 1,000ms/60 ซึ่งเท่ากับ 16.6ms
เพื่อประหยัดพลังงานเบราว์เซอร์จะขยายช่วงเวลาเป็น 1,000 มิลลิวินาทีสำหรับหน้าเว็บที่ไม่ได้อยู่ในหน้าต่างปัจจุบัน นอกจากนี้หากแล็ปท็อปใช้พลังงานแบตเตอรี่ Chrome และ IE 9 หรือสูงกว่าจะเปลี่ยนช่วงเวลาเป็นตัวจับเวลาระบบซึ่งประมาณ 16.6 มิลลิวินาที
กลไกการดำเนินงาน
มาอธิบายส่วนก่อนหน้าของคำถามทำไม 0 ถึงปรากฏต่อหน้า 1 ในผลลัพธ์ของคอนโซลของรหัสด้านล่าง
settimeout (function () {console.log (1);}); console.log (0);ในความเป็นจริงการตั้งค่าพารามิเตอร์ที่สองของ settimeout เป็น 0s ไม่ได้หมายถึงการดำเนินการฟังก์ชั่นทันที แต่เพียงแค่ใส่ฟังก์ชันลงในคิวรหัส
ในตัวอย่างต่อไปนี้ตัวจัดการเหตุการณ์ถูกตั้งค่าเป็นปุ่ม BTN ตัวจัดการเหตุการณ์ตั้งค่าตัวจับเวลาเพื่อโทรหลัง 250ms หลังจากคลิกปุ่มนี้ก่อนอื่นให้เพิ่มตัวจัดการเหตุการณ์ onclick ลงในคิว ตัวจับเวลาถูกตั้งค่าหลังจากดำเนินการโปรแกรม หลังจาก 250ms รหัสที่ระบุจะถูกเพิ่มลงในคิวและรอการดำเนินการ
btn.onclick = function () {settimeout (function () {console.log (1);}, 250);}หากตัวจัดการเหตุการณ์ onclick ในรหัสข้างต้นถูกเรียกใช้งานสำหรับ 300ms รหัสตัวจับเวลาจะต้องดำเนินการอย่างน้อย 300ms หลังจากตั้งค่าตัวจับเวลา รหัสทั้งหมดในคิวจะต้องรอจนกว่ากระบวนการ JavaScript จะไม่ได้ใช้งานโดยไม่คำนึงถึงวิธีการเพิ่มเข้ากับคิว
ดังที่แสดงในรูปแม้ว่ารหัสตัวจับเวลาจะถูกเพิ่มที่ 255 เมซ์ แต่ก็ไม่สามารถดำเนินการได้ในเวลานี้เนื่องจากตัวจัดการเหตุการณ์ onClick ยังคงทำงานอยู่ รหัสจับเวลาที่เร็วที่สุดสามารถดำเนินการได้คือ 300ms นั่นคือหลังจากตัวจัดการเหตุการณ์ onclick เสร็จสิ้น
ปัญหา setInterval
ปัญหาเกี่ยวกับการใช้ setInterval () คือรหัสตัวจับเวลาอาจไม่ถูกเรียกใช้ก่อนที่รหัสจะถูกเพิ่มลงในคิวอีกครั้งส่งผลให้รหัสจับเวลาทำงานหลายครั้งติดต่อกันโดยไม่หยุดพักระหว่างพวกเขา การแก้ปัญหานี้โดยเอ็นจิ้น JavaScript คือการเพิ่มรหัสตัวจับเวลาลงในคิวเมื่อใช้ setInterval () สิ่งนี้ทำให้มั่นใจได้ว่าช่วงเวลาขั้นต่ำสำหรับรหัสจับเวลาที่จะเพิ่มลงในคิวคือช่วงเวลาที่ระบุ
อย่างไรก็ตามสิ่งนี้สามารถนำไปสู่ปัญหาสองประการ: 1. บางช่วงเวลาถูกข้าม; 2. ช่วงเวลาระหว่างการดำเนินการรหัสของตัวจับเวลาหลายตัวอาจมีขนาดเล็กกว่าที่คาดไว้
สมมติว่าตัวจัดการเหตุการณ์ onclick บางตัวตั้งค่าตัวจับเวลาช่วงเวลา 200ms โดยใช้ serinterval () หากตัวจัดการเหตุการณ์ใช้เวลามากกว่า 300ms ในการดำเนินการให้เสร็จสมบูรณ์และรหัสตัวจับเวลาก็ใช้เวลาในเวลาเดียวกันช่วงเวลาที่แน่นอนจะถูกข้ามในเวลาเดียวกัน
ตัวจับเวลาแรกในตัวอย่างจะถูกเพิ่มลงในคิวที่ 205ms แต่ไม่สามารถดำเนินการได้จนกว่าจะผ่านไป 300ms เมื่อรหัสจับเวลานี้ถูกเรียกใช้งานสำเนาอื่นจะถูกเพิ่มลงในคิวที่ 405ms ในช่วงเวลาถัดไป 605ms รหัสตัวจับเวลาแรกยังคงทำงานอยู่และมีอินสแตนซ์ของรหัสตัวจับเวลาในคิวอยู่แล้ว เป็นผลให้รหัสตัวจับเวลา ณ เวลานี้จะไม่ถูกเพิ่มลงในคิว
ทำซ้ำการตั้งถิ่นฐาน
เพื่อหลีกเลี่ยงปัญหาการจับเวลา setInterval () คุณสามารถใช้การโทรที่ถูกล่ามโซ่ ()
settimeout (ฟังก์ชั่น fn () {settimeout (fn, interval);}, ช่วงเวลา);การเรียกใช้โซ่รูปแบบนี้ SetTimeOut () และตัวจับเวลาใหม่จะถูกสร้างขึ้นทุกครั้งที่มีการดำเนินการฟังก์ชั่น Section Settimeout () เรียกใช้ฟังก์ชันที่ดำเนินการในปัจจุบันและตั้งค่าตัวจับเวลาอื่นสำหรับมัน ข้อดีของสิ่งนี้คือรหัสจับเวลาใหม่จะไม่ถูกแทรกลงในคิวจนกว่าจะมีการดำเนินการรหัสจับเวลาก่อนหน้านี้เพื่อให้แน่ใจว่าไม่มีช่วงเวลาที่หายไป ยิ่งไปกว่านั้นก็ยังช่วยให้มั่นใจได้ว่าก่อนที่จะดำเนินการรหัสจับเวลาครั้งต่อไปอย่างน้อยก็ต้องรอช่วงเวลาที่ระบุเพื่อหลีกเลี่ยงการดำเนินการอย่างต่อเนื่อง
ใช้ setInterval ()
<div id = "mydiv" style = "ความสูง: 100px; ความกว้าง: 100px; พื้นหลังสี: สีชมพู; ตำแหน่ง: สัมบูรณ์; ซ้าย: 0;"> </div> <script> mydiv.onclick = function () {timer var = setInterval (ฟังก์ชัน () false;} mydiv.style.left = parseint (mydiv.style.left) + 5 + 'px'; } </script>ใช้ chained settimeout ()
<div id = "mydiv" style = "ความสูง: 100px; ความกว้าง: 100px; พื้นหลัง-สี: สีชมพู; ตำแหน่ง: สัมบูรณ์; ซ้าย: 0;"> </div> <script> mydiv.onclick = function () {settimeout false;} mydiv.style.left = parseint (mydiv.style.left) + 5 + 'px'; } </script>แอปพลิเคชัน
ใช้ตัวจับเวลาเพื่อปรับลำดับเหตุการณ์
[1] ในการพัฒนาเว็บเหตุการณ์แรกเกิดขึ้นในองค์ประกอบเด็กจากนั้นฟองขึ้นไปที่องค์ประกอบหลักนั่นคือฟังก์ชั่นการเรียกกลับเหตุการณ์ขององค์ประกอบลูกจะถูกเรียกเร็วกว่าฟังก์ชั่นการเรียกกลับเหตุการณ์ขององค์ประกอบหลัก หากเราปล่อยให้ฟังก์ชั่นการโทรกลับเหตุการณ์ขององค์ประกอบหลักเกิดขึ้นก่อนเราต้องใช้ settimeout (f, 0)
ภายใต้สถานการณ์ปกติคลิกที่องค์ประกอบ div, ป๊อปอัพครั้งแรก 0 จากนั้นปรากฏขึ้น 1
<div id = "mydiv" style = "ความสูง: 100px; ความกว้าง: 100px; พื้นหลัง-สี: สีชมพู;"> </div> <script> mydiv.onclick = function () {แจ้งเตือน (0);} document.onclick = function () {Alert (1);} </script>หากคุณต้องการให้เหตุการณ์ onclick ของเอกสารเกิดขึ้นก่อนนั่นคือคลิกที่องค์ประกอบ div 1 จะปรากฏขึ้นก่อนแล้ว 0 จะปรากฏขึ้น จากนั้นทำการตั้งค่าต่อไปนี้
<div id = "mydiv" style = "ความสูง: 100px; ความกว้าง: 100px; พื้นหลัง-สี: สีชมพู;"> </div> <script> mydiv.onclick = function () {settimeout (ฟังก์ชั่น () {Alert (0);})} document.onclick = function ()【 2 】ฟังก์ชั่นการโทรกลับที่ผู้ใช้กำหนดโดยปกติจะถูกเรียกใช้ก่อนการดำเนินการเริ่มต้นของเบราว์เซอร์ ตัวอย่างเช่นหากผู้ใช้ป้อนข้อความในกล่องอินพุตเหตุการณ์ KeyPress จะถูกเรียกใช้ก่อนที่เบราว์เซอร์จะได้รับข้อความ ดังนั้นฟังก์ชั่นการโทรกลับต่อไปนี้ไม่สามารถบรรลุเป้าหมายได้
<อินพุต type = "text" id = "myInput"> <script> myInput.onkeypress = function (เหตุการณ์) {this.value = this.value.touppercase ();} </script>รหัสข้างต้นต้องการแปลงอักขระเป็นตัวพิมพ์ใหญ่ทันทีหลังจากผู้ใช้ป้อนข้อความ แต่ในความเป็นจริงมันสามารถแปลงอักขระก่อนหน้าเป็นตัวพิมพ์ใหญ่ได้เท่านั้นเนื่องจากเบราว์เซอร์ยังไม่ได้รับข้อความในเวลานี้ดังนั้นค่านี้ไม่สามารถรับอักขระอินพุตล่าสุดได้
โดยการเขียนใหม่ด้วยรหัสด้านบนเท่านั้น
<อินพุต type = "text" id = "myInput"> <script> myInput.onkeypress = function (เหตุการณ์) {settimeout (function () {myInput.Value = myInput.value.touppercase ();});} </script>รหัสสิ้นสุดที่นี่ บทความถัดไปจะแนะนำให้คุณฟัง
BOM Series: RequestAnimationFrame
แอปพลิเคชันตัวจับเวลาที่สามของซีรีส์ BOM (นาฬิกา, นับถอยหลัง, นาฬิกาจับเวลาและนาฬิกาปลุก)
ด้านบนเป็นตัวจับเวลาครั้งแรก settimeout และ setInterval ของซีรี่ส์ BOM ที่แนะนำโดยบรรณาธิการ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!