delay-test.html (2715B)
1 <!DOCTYPE html> 2 <meta name="viewport" content="width=device-width,initial-scale=1"> 3 <script src="/resources/testharness.js"></script> 4 <script src="/resources/testharnessreport.js"></script> 5 <script src="../resources/intersection-observer-test-utils.js"></script> 6 7 <style> 8 body, html { 9 margin: 0; 10 } 11 pre, #log { 12 position: absolute; 13 top: 0; 14 left: 200px; 15 } 16 #target { 17 width: 100px; 18 height: 100px; 19 background-color: green; 20 } 21 #occluder { 22 width: 100px; 23 height: 100px; 24 background-color: blue; 25 } 26 </style> 27 28 <div id="target"></div> 29 <div id="occluder"></div> 30 31 <script> 32 async_test(t => { 33 let entries = []; 34 let delay = 100; 35 let target = document.getElementById("target"); 36 let occluder = document.getElementById("occluder"); 37 38 assert_true(!!target, "target exists"); 39 assert_true(!!occluder, "occluder exists"); 40 let observer = new IntersectionObserver(function(changes) { 41 entries = entries.concat(changes) 42 }, {trackVisibility: true, delay: delay}); 43 observer.observe(target); 44 entries = entries.concat(observer.takeRecords()); 45 assert_equals(entries.length, 0, "No initial notifications."); 46 // The first notification should be sent without delay. 47 waitForNotification(t, t.step_func(step0)); 48 49 function waitForDelay(timerExpiredBeforeLastFrame, nextStep) { 50 requestAnimationFrame(t.step_func(() => { 51 if (timerExpiredBeforeLastFrame) { 52 // New notifications should have been generated during the previous 53 // frame and delivered by now. 54 assert_equals(entries.length, 2); 55 assert_greater_than(entries[1].time - entries[0].time, delay); 56 assert_false(entries[1].isVisible); 57 nextStep(); 58 } else { 59 // Observer may not have updated yet. Wait for next frame. 60 let timerExpired = performance.now() - entries[0].time >= delay; 61 waitForDelay(timerExpired, nextStep); 62 } 63 })); 64 } 65 66 function step0() { 67 assert_equals(entries.length, 1); 68 assert_true(entries[0].isVisible); 69 // This should trigger a notification on the next run. 70 occluder.style.marginTop = "-10px"; 71 // Enter a rAF loop until the delay timer expires. 72 waitForDelay(false, step1); 73 } 74 75 function step1() { 76 occluder.style.marginTop = "10px"; 77 // This style invalidation should cause a frame to run before the observer 78 // can generate a notification (due to delay parameter). Make sure the 79 // notification will still be generated even if we don't force more frames 80 // with a rAF loop. 81 t.step_timeout(() => { 82 assert_equals(entries.length, 3); 83 assert_true(entries[0].isVisible); 84 t.done(); 85 }, 2 * delay); 86 } 87 88 }, "'delay' parameter throttles frequency of notifications."); 89 </script>