none
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

    Monday, April 16, 2012 5:42 PM

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 PM
  • 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 05, 2012 2:44 PM
  • I have sent it.

    Valentin Iliescu

    Friday, April 06, 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

    Monday, April 16, 2012 5:42 PM
  • My sample is based on the App Settings sample with before/after events:

    http://code.msdn.microsoft.com/windowsapps/App-settings-sample-1f762f49/sourcecode?fileId=50852&pathId=1420071992 

    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