Answered by:
Settings events firing too many times

Question
-
I am trying to add settings to my Win8 JS project, and it seems the before/aftershow/hide events are firing too many times. I have created a repro:
In a blank Win8 JS project, add this code in default.js, before app.start()
app.onsettings = function (e) { e.detail.applicationcommands = { 'settingsDiv': { href: 'settings.html', title: 'Settings' } }; WinJS.UI.SettingsFlyout.populateSettings(e); }
Then add to the project the settings file
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Settings flyout</title> </head> <body> <div id="settingsDiv" data-win-control="WinJS.UI.SettingsFlyout" aria-label="App settings flyout" data-win-options="{width:'narrow'}"> <div class="win-header"> <button type="button" onclick="WinJS.UI.SettingsFlyout.show()" class="win-backbutton"> </button> <div class="win-label">Settings</div> <img src="images/smalllogo.png" style="position: absolute; right: 40px;" /> </div> <div class="win-content"> Some settings </div> </div> <script> document.body.addEventListener("DOMNodeInserted", onNodeInsertedIntoDocument, false); function onNodeInsertedIntoDocument(e) { var element = document.getElementById("settingsDiv"); if (element) { element.addEventListener("beforeshow", function () { console.log("beforeshow:"); }, false); element.addEventListener("aftershow", function () { console.log("aftershow:"); }, false); element.addEventListener("beforehide", function () { console.log("beforehide:"); }, false); element.addEventListener("afterhide", function () { console.log("afterhide:"); }, false); } } </script> </body> </html>
Debug the app and show/hide the settings once. But the JS log shows that each event fired more than once (approx. 10 times).
Valentin Iliescu
Friday, March 30, 2012 5:47 PM
Answers
-
Oleg is correct: You are adding a new event listener on settingsDiv's beforeshow/aftershow/beforehide/afterhide everytime a node is inserted into the document. If you add the listeners exactly one time, you will only get one set of events fired:
var NeedToAddEventListeners = true; function onNodeInsertedIntoDocument(e) { var element = document.getElementById("settingsDiv"); if (element && NeedToAddEventListeners) { element.addEventListener("beforeshow", function () { console.log("beforeshow:"); }, false); element.addEventListener("aftershow", function () { console.log("aftershow:"); }, false); element.addEventListener("beforehide", function () { console.log("beforehide:"); }, false); element.addEventListener("afterhide", function () { console.log("afterhide:"); }, false); NeedToAddEventListeners = false; } }
Matt Small - Microsoft Escalation Engineer - Forum Moderator
- Proposed as answer by Matt SmallMicrosoft employee, Moderator Monday, April 16, 2012 5:42 PM
- Marked as answer by Valentin Iliescu Wednesday, April 18, 2012 2:00 PM
Monday, April 16, 2012 5:42 PMModerator
All replies
-
Hi Valentin,
Put a bp in your function:
onNodeInsertedIntoDocument
How many times is that function getting called?
-Jeff
Jeff Sanders (MSFT)
Friday, March 30, 2012 7:39 PMModerator -
I put a console log in it (the breakpoint is not hit somehow, I am getting 'The breakpoint will not currently be hit. No symbols have been loaded for this document.'), the function is called the same number of times (around 10)
Valentin Iliescu
Saturday, March 31, 2012 3:45 AM -
Valentin - I followed your instructions exactly but am not getting the application to work. Can you just send me a repro application? MSMALL at Microsoft.
Matt Small - Microsoft Escalation Engineer - Forum Moderator
Thursday, April 5, 2012 2:44 PMModerator -
I have sent it.
Valentin Iliescu
Friday, April 6, 2012 5:13 PM -
It seems that DOMNodeInserted just bubbling for every inserted node (first is pagecontrol and the following is the content of setting flyout div).
You can check it by watching for event.target.
In regard to ability to set breakpoint: I've solved it by moving inline javascript code into external js file and referencing it in setting flyout html file.
Thanks,
Aleh
Saturday, April 14, 2012 10:10 AM -
Oleg is correct: You are adding a new event listener on settingsDiv's beforeshow/aftershow/beforehide/afterhide everytime a node is inserted into the document. If you add the listeners exactly one time, you will only get one set of events fired:
var NeedToAddEventListeners = true; function onNodeInsertedIntoDocument(e) { var element = document.getElementById("settingsDiv"); if (element && NeedToAddEventListeners) { element.addEventListener("beforeshow", function () { console.log("beforeshow:"); }, false); element.addEventListener("aftershow", function () { console.log("aftershow:"); }, false); element.addEventListener("beforehide", function () { console.log("beforehide:"); }, false); element.addEventListener("afterhide", function () { console.log("afterhide:"); }, false); NeedToAddEventListeners = false; } }
Matt Small - Microsoft Escalation Engineer - Forum Moderator
- Proposed as answer by Matt SmallMicrosoft employee, Moderator Monday, April 16, 2012 5:42 PM
- Marked as answer by Valentin Iliescu Wednesday, April 18, 2012 2:00 PM
Monday, April 16, 2012 5:42 PMModerator -
My sample is based on the App Settings sample with before/after events:
I have not tried the sample so I don't know if the sample is incorrect or my repro is actually different.
Valentin Iliescu
Wednesday, April 18, 2012 1:59 PM