Skip navigation
WebleyWest
Currently Being Moderated

Spry menu open on reload (back button)

Jul 23, 2009 8:21 PM

Hello,

 

This would never have bothered me, but my client is disturbed by it so....

 

In Firefox 3, when one uses his/her back button, the previous Spry menu remains open. Is there a way to close this when someone returns to a page?

 

For instance, if you click here:

http://72.29.74.171/~heritage/concerts/concert_summary.htm

and go to

Concerts/Pops (or any other page), when you return to the concert_summary.htm page, the menu is still open.

 

Can the menu be closed when one returns to the page?

 

Many thanks....just trying to please them all!

 

Webley

 
Replies
  • Currently Being Moderated
    Jul 23, 2009 11:46 PM   in reply to WebleyWest

    I see that you are still using Spry 1.4. The latest version is 1.6.1 updating to the latest version might correct this.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 27, 2009 3:17 AM   in reply to WebleyWest

    I tested in FF 3.0 and 3.5 but I'm unable to find the issue. Did you do hard refresh? clear the cache etc.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 27, 2009 1:59 PM   in reply to WebleyWest

    tested it in FF 3.5

     

    opened your link -> opened Concert Pop Page (-> menu is now closed) -> went back with the back-button in Firefox (menu is still closed)

    i tested this with other subpages and the menu is still closed when i use the back button

     

    maybe you can try to reinstall your browser (save bookmarks first)

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 27, 2009 2:24 PM   in reply to WebleyWest

    When I visit your site I see the same problem using FF 3.5. In IE 8 it works fine.

    Unfortunately, on my own site I have this problem too, and not only in FF but also IE 8. If you go to: http://www.solutionsinbalance.com/ and in the horizontal menu at the top click on 'About us' and then on the back button, you will see that the 'About us' menu item continues to be selected and the submenu shown. I tried to write an additional function that clears the entire menu upon each page reload, but it seems that not every 'back' function triggers a page reload and therefore the function is not called. Any suggestions are welcome.

     

    Niels

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 27, 2009 2:37 PM   in reply to NielsHofkes

    NielsHofkes wrote:

     

    If you go to: http://www.solutionsinbalance.com/

    and in the horizontal menu at the top click on 'About us' and then on the back button, you will see that the 'About us' menu item continues to be selected and the submenu shown.

    When I go back with the back button the home menu is selected, no submenu is shown. the submenu is only shown if i hover over "Services" and "About us"... strange

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 27, 2009 11:58 PM   in reply to WebleyWest

    The only things I see similar to your pages, is that the constructor for the Spry Menu's is at the bottom of the page. You could try to place it directly Under the menu bar to see if that helps.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 28, 2009 2:44 AM   in reply to WebleyWest

    can you also post your exact. browser info? version number, platform, and maybe additional addons you got installed? I'll try to create a test case tonight. And mimic your "browser" so i can hopefully find what is going on.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 28, 2009 6:43 PM   in reply to WebleyWest

    Perhaps the 'hanging submenus' are caused by Firefox' caching behaviour. According to this page https://developer.mozilla.org/En/Using_Firefox_1.5_caching#New_browser _events Firefox 1.5 uses in-memory caching for entire Web pages, including their JavaScript states. If this is also true for FF 3.5.1 (which I am using), then this would explain it. If a user selects an item from a submenu, then the submenu is shown and the page would be saved by FF in that state for the purpose of the cache. Therefore, if the user clicks the back-button on a subsequent page to go back to the previous page, he sees the page including the last Javascript state which is the open submenu.

     

    So in order to resolve this I tried to prevent FF from caching, both by setting the headers for the page ("cache-control" and "Expires") and by changing the browser.cache.disk.enable config setting, but all of this wouldn't help. I then made a function to clear the entire menubar (i.e. removing submenus and clearing the hover classnames) and added an unload event handler calling this function, with the effect that upon each page unload, the menubar is in its initial state and upon clicking the back-button this is what is shown. It seems to work OK in FF but probably has the disadvantage that the unload event handler prevents caching which slows down browsing. Also, I still have the problem in IE 8 (not the hanging submenus, but the top row menu item of the old page remains selected despite going back to another page). So I will continue looking for a solution for this small but annoying issue.

     

    Niels

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 28, 2009 11:43 PM   in reply to WebleyWest

    I have now tried a slightly different approach which seems to work OK, at least when I tested this with IE 8 and FF 3.5.1. In SpryMenuBar.js I added the following event handler:

     

    Spry.Widget.MenuBar.prototype.mouseClick = function (listitem, e)
    {
     link = listitem.getElementsByTagName('a')[0];
     var submenus = listitem.getElementsByTagName('ul');
     var menu = (submenus.length > 0 ? submenus[0] : null);
     var hasSubMenu = (menu) ? true : false;
     this.removeClassName(link, hasSubMenu ? this.subHoverClass : this.hoverClass);
     if (menu)
      this.hideSubmenu(menu);
     if (this.hasFocus)
      link.blur();
    };
    

     

    This is hooked up in Spry.Widget.MenuBar.prototype.initialize, just below the addEventListener calls for mouseover en mouseout, with:

    this.addEventListener(listitem, 'click', function(e){self.mouseClick(listitem, e);}, false);
    


    As you see, the additional 'mouseClick' event handler is a simplified version of mouseOut but doesn't use the timing delay.

     

    You can try this on http://www.solutionsinbalance.com. Any comments are welcome.

     

    Niels

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 29, 2009 8:05 AM   in reply to NielsHofkes

    I just tested your site using Safari (Actually webkit nightly) and the issue also occurs there. So I think there is a fundamental error in the Spry Menu Bar.

     

    I still remember when the bug was present in my FireFox that they had multiple showSubmenu classes on the elements. So what might help is to loop over the <ul>'s and check if the class is present, and remove it if its found. This can just be done in the initialize part of the MenuBar. I think it might be a better solution instead of adding a extra mouse click listener to your MenuBar.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 29, 2009 9:40 AM   in reply to Arnout Kazemier

    I agree that adding some code to the initialize part of the Menubar would be the easiest way to fix it. Unfortunately, it doesn't work. The reason is that upon clicking the back-button, FF simply withdraws the cached copy of the page including the Javascript state and does not 'load' the page, therefore the initialize code is not called at all - indeed the menubar is not initialized as such but recreated from the cache memory including all changes to elements that existed before the page was unloaded.

     

    Therefore, in my view there is in itself not a fundamental error in the Spry Menu Bar, but the principle of how a Menu Bar show ideally operate is fundamentally contrary to the way that FF uses disk caching: if a user clicks on a submenu item (or a menu-item that has a submenu), by definition that submenu is shown on the page when the user (by clicking the link) unloads the page and moves to another page. Therefore the shown submenu is part of the page state upon onload and this is what FF recreates when the user later clicks on the back-button.

     

    I can think of a couple of possible solutions but each has its drawbacks:

     

    1. Preventing FF from caching and forcing a reload. I tried this last night but FF thinks to know better and continues caching despite my explicit instructions not to do so (by config settings or page header settings). But admittedly, disabling caching just for the purpose of a menu bar on a page that is otherwise static is probably not a good solution anyway.

     

    2. Implementing an onUnload event handler, which clears the entire menubar just before unloading the page. This should then be the page state that FF uses when recreating the page from cache upon clicking the back-button. I also tried this approach and it worked in FF, but for some reason not in IE. Moreover, it has the disadvantage that an onUnload event handler also prevents caching which therefore slows down browsing.

     

    3. Adding an event handler for pageshow. This should fire everytime the page is loaded, also when it's loaded from the cache (in contrast to the 'load' event which (in FF) doesn't fire upon a reload from cache. I guess this approach would work but has the disadvantage that the pageshow event is not supported in all browsers (I think - if this is not true please let me know) and therefore a browser-specific event would be included in the Spry framework. I was hoping that there is a general approach that works in all browsers and would not have to resort to browser-specific work-arounds.

     

    The essence with a MenuBar is, is that the state that it is in when you use it to exit a page is by definition not the state that you want when you go back to the page. So if that's the way that FF uses caching, I think that a solution must either consist of clearing the menubar just before page unload or clearing it immediately upon pageshow.

     

    Niels

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 29, 2009 11:59 AM   in reply to NielsHofkes

    Hello Niels,

     

    I agree with your points and I have been playing with the menu bar a bit. And I see to have found a really simple solution. That at least works in Safari and FireFox (at least for my versions) I have been unable to test on IE8 because I use a Mac.

     

    Near line 365, you will find the eventListener:

     

    this.addEventListener(listitem, 'mouseout', function(e){if (self.enableKeyboardNavigation) self.clearSelection(); self.mouseOut(listitem, e);}, false);
    

    Directly under that add the following line:

     

    this.addEventListener(link, 'click', function(e){ self.clearMenus(self.element); }, false);
    

    And that should fix the issue when users click on it.. and reloads.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 29, 2009 2:15 PM   in reply to Arnout Kazemier

    .V1,

     

    Thank you for your help, this is very much appreciated. Indeed the clearMenus() function seems a logical and simple solution. I tried this yesterday and have also tried your short-form version, but unfortunately it does not work, at least not for all menu items. This is because clearMenus() actually does not clear the entire menubar but only removes any visible submenus. This means that any toplevel menu items with class name hoverClass or subHoverClass (in CSS: MenuBarItemHover and MenuBarSubmenuHover) are not corrected. This is visible if clicking on the back-button from a page corresponding to a menu item without a submenu: both the old and the new menu item are selected because the hoverClass name is not removed. This is why I added this in the mouseClick() event handler (in addition to removing focus, which is more a style preference).

     

    As to your earlier comment about Safari: I tested with Safari 4.0.2 (on a Windows Vista PC) and indeed the problem with multiple selected top-level menu items still exists. However, the submenus do actually disappear. What's more, the 'old' menu item is cleared once the mouse is moved, even when the mouse is not on the menu at all but somewhere else on the page. How this is possible is a mystery to me, moving the mouse outside the menu should not trigger an event for the menubar causing it to change state. But it does actually mean that the menu is OK once the Safari user has moved the mouse if only for one pixel and on a completely different part of the screen (well, in the browser of course). That's a score of 99% which is good enough for me on this particular issue.

     

    Niels

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 30, 2009 12:22 AM   in reply to NielsHofkes

    NielsHofkes wrote:

     

    .V1,

     

    Thank you for your help, this is very much appreciated. Indeed the clearMenus() function seems a logical and simple solution. I tried this yesterday and have also tried your short-form version, but unfortunately it does not work, at least not for all menu items. This is because clearMenus() actually does not clear the entire menubar but only removes any visible submenus. This means that any toplevel menu items with class name hoverClass or subHoverClass (in CSS: MenuBarItemHover and MenuBarSubmenuHover) are not corrected. This is visible if clicking on the back-button from a page corresponding to a menu item without a submenu: both the old and the new menu item are selected because the hoverClass name is not removed. This is why I added this in the mouseClick() event handler (in addition to removing focus, which is more a style preference).

     

    As to your earlier comment about Safari: I tested with Safari 4.0.2 (on a Windows Vista PC) and indeed the problem with multiple selected top-level menu items still exists. However, the submenus do actually disappear. What's more, the 'old' menu item is cleared once the mouse is moved, even when the mouse is not on the menu at all but somewhere else on the page. How this is possible is a mystery to me, moving the mouse outside the menu should not trigger an event for the menubar causing it to change state. But it does actually mean that the menu is OK once the Safari user has moved the mouse if only for one pixel and on a completely different part of the screen (well, in the browser of course). That's a score of 99% which is good enough for me on this particular issue.

     

    Niels

    Thanks for you comments on this issue. And I have been digging a little bit further in to this issue. With this is as result, a smaller script that you created above, because this reuses all Spry's methods.

     

     

    this.addEventListener(link, 'click', function(e){ 
              self.clearMenus(self.element);
              self.clearSelection();
         }, false);
    

     

     

    And in your CSS, remove the following line:

     

     

    ul.MenuBarHorizontal a:hover, ul.MenuBarHorizontal a:focus
    {
         background-color: #33C;
         color: #FFF;
    }
    

     

    This fixes all issue addressed above in Safari, and hopefully the same in the other browsers. The browser cache also stored "native" events so a a:hover would still be present in the cache. By removing that line, all classes, and native events will be removed from the menu bar.

     
    |
    Mark as:
  • Currently Being Moderated
    Jul 31, 2009 2:00 PM   in reply to Arnout Kazemier

    Thank your for your suggestion. I tried this in my script but for some reason still have the hanging-menu issue. So I prefer to use my solution even though it's a few extra lines of code.

     

    Niels

     
    |
    Mark as:
  • Currently Being Moderated
    Sep 23, 2009 7:58 PM   in reply to WebleyWest

    I added an unload function to the bottom of my SpryMenuBar.js file. This seemed to fix everything for me. None of the other solutions did.

     

    window.addEventListener("unload", function(e)
    {
         self.clearMenus(self.element);
        self.clearSelection();
    }, false);
     
    |
    Mark as:
  • Currently Being Moderated
    Sep 24, 2009 1:36 PM   in reply to punk_rock_eric

    Opera doesn't call the onuload event if they cached the page. So your solution will fail on Opera browsers. Make sure you are using Spry 1.6.1

     
    |
    Mark as:
  • Currently Being Moderated
    Jan 29, 2011 12:41 PM   in reply to Arnout Kazemier

    .V1 wrote:

     

    Hello Niels,

     

    I agree with your points and I have been playing with the menu bar a bit. And I see to have found a really simple solution. That at least works in Safari and FireFox (at least for my versions) I have been unable to test on IE8 because I use a Mac.

     

    Near line 365, you will find the eventListener:

     

     

    this.addEventListener(listitem, 'mouseout', function(e){if (self.enableKeyboardNavigation) self.clearSelection(); self.mouseOut(listitem, e);}, false);
    

     

    Directly under that add the following line:

     

     

    this.addEventListener(link, 'click', function(e){ self.clearMenus(self.element); }, false);
    

     

    And that should fix the issue when users click on it.. and reloads.

     

    I've searched and cannot find this event listener in the JavaScript. I need to have my menu clear when navigating back to pages with touch screen. There seems to be no other answer to this problem on the entire internet.

     

    I tried using Niels' code in the SpryMenu.js file, but it just made my entire dropdown list invisible.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 6, 2011 1:48 PM   in reply to WebleyWest

    Hi all, i had same problem with rollover buttons. I added function to buttons in Dreamweaver: onClick:Swap Image Restore. It is not fixing the problem but now when you click the button it is going back to original version.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points