beforeunload_test_page.html (2415B)
1 <!doctype html> 2 <html> 3 <body> 4 5 <p> 6 There are currently <span id="totalInnerHandlers">0</span> beforeunload handlers registered in this frame. 7 </p> 8 <p> 9 There are currently <span id="totalOuterHandlers">0</span> beforeunload handlers registered on my subframe. 10 </p> 11 12 <iframe src="about:blank" id="subframe"></iframe> 13 14 <script> 15 this.BeforeUnloader = { 16 _innerEventHandlers: [], 17 _outerEventHandlers: [], 18 19 get $totalInner() { 20 delete this.$totalInner; 21 return this.$totalInner = document.getElementById("totalInnerHandlers"); 22 }, 23 24 get $totalOuter() { 25 delete this.$totalOuter; 26 return this.$totalOuter = document.getElementById("totalOuterHandlers"); 27 }, 28 29 get $subframe() { 30 delete this.$subframe; 31 return this.$subframe = document.getElementById("subframe"); 32 }, 33 34 pushInner(howMany) { 35 for (let i = 0; i < howMany; ++i) { 36 let func = () => {}; 37 this._innerEventHandlers.push(func); 38 addEventListener("beforeunload", func); 39 } 40 41 this.$totalInner.textContent = this._innerEventHandlers.length; 42 }, 43 44 popInner(howMany) { 45 for (let i = 0; i < howMany; ++i) { 46 let func = this._innerEventHandlers.pop(); 47 if (func) { 48 removeEventListener("beforeunload", func); 49 } 50 } 51 52 this.$totalInner.textContent = this._innerEventHandlers.length; 53 }, 54 55 pushOuter(howMany) { 56 if (!this.$subframe.parentNode) { 57 throw new Error("Subframe I'm holding a reference to detached!"); 58 } 59 60 for (let i = 0; i < howMany; ++i) { 61 let func = () => {}; 62 this._outerEventHandlers.push(func); 63 this.$subframe.contentWindow.addEventListener("beforeunload", func); 64 } 65 66 this.$totalOuter.textContent = this._outerEventHandlers.length; 67 }, 68 69 popOuter(howMany) { 70 if (!this.$subframe.parentNode) { 71 throw new Error("Subframe I'm holding a reference to detached!"); 72 } 73 74 for (let i = 0; i < howMany; ++i) { 75 let func = this._outerEventHandlers.pop(); 76 if (func) { 77 this.$subframe.contentWindow.removeEventListener("beforeunload", func); 78 } 79 } 80 81 this.$totalOuter.textContent = this._outerEventHandlers.length; 82 }, 83 84 reset() { 85 this.popInner(this._innerEventHandlers.length); 86 this.popOuter(this._outerEventHandlers.length); 87 }, 88 }; 89 </script> 90 91 </body> 92 </html>