suppression of radrotator animation when handline onhashchange event

3 posts, 1 answers
  1. Felipe
    Felipe avatar
    33 posts
    Member since:
    Dec 2010

    Posted 27 Mar 2011 Link to this post

    I am trying to make a page which operates mostly on the client with radrotator.  you can think of it as a simple slide-show type interface.  radrotator has thumbnails, which switching between index, larger image updates (along with some other things)

    I am using hash parameters in the URL to allow users to "bookmark" pages meaningfully, and below is what i see as the relevant javascript code.

    i use a boolean "stateHandled" variable which lets the code know whether or not it should look at the hash value and update the page accordingly, or if the state change has already been handled....

    thus, if user presses back button, the onhashchange event updates the gui.
    on the other hand, if user interacts with the radrotator - the onhashchange event does nothing.

    what is REALLY weird is that all of this works fine except for one thing...  the animation of the radrotator is suppressed now for when the user is changing the index via interactions with the radrotator, but the forward/back buttons of the browser work fine (they have animation).

    window.onload = function () {
        initializeStateFromURL();
    }
      
    window.onhashchange = function () {
        initializeStateFromURL();
    }
      
    function initializeStateFromURL() {
        if (!stateHandled) {
            var navSetting = window.location.hash;
            var slide = FromHash("slide", navSetting);
            if (slide) {
                SetRotatorToSlideID(slide);
            }
        }
    }
      
    var stateHandled = false;
      
    function SetRotatorToSlideID(slideID) {
        var items = rotator.get_items();
        for (i in items) {
            if (slideID == GetAttributeValue(items[i], "SlideID")) {
                rotator.set_currentItemIndex(items[i].get_index(), true);
                UpdateGUI(items[i]);
            }
        }
    }
      
    function RotatorClientItemShowing(sender, args) {
        stateHandled = true;
        UpdateGUI(args.get_item());
        stateHandled = false;
    }
      
    function RotatorClientItemClicked(sender, args) {
        stateHandled = true;
        sender.set_currentItemIndex(args.get_item().get_index(), true);
          
        UpdateGUI(args.get_item());
        stateHandled = false;
    }
      
    function UpdateGUI(item) {
        //update some things on the page
      
        setHash(GetAttributeValue(item,"DocumentID"),GetAttributeValue(item,"SlideID"));
    }


    on the other hand, if i make the changes to the above code, having:

    function RotatorClientItemShowing(sender, args) {
        stateHandled = true;
        UpdateGUI(args.get_item());
    }
       
    function RotatorClientItemClicked(sender, args) {
        stateHandled = true;
        sender.set_currentItemIndex(args.get_item().get_index(), true);
           
        UpdateGUI(args.get_item());
    }


    then the animations work fine...  (however the logic of the code isn't exactly perfect... the forward/back buttons only work every other hash change)

    any ideas?  thanks.
  2. Answer
    Niko
    Admin
    Niko avatar
    387 posts

    Posted 29 Mar 2011 Link to this post

    Hello Leland,

    It appears that the issue comes from the onhashchange event. Naturally it should fire when the location hash has changed, in the user's case when he/she hits the back button. However when using JavaScript to change the hash string, the event is being fired as well. This is the reason why you have decided to use flags to store the moment the hash should be changed. However there is one very tricky detail for the native events on the client-side - the handlers are not raised until the currently executing function has finished. Therefore the onhashchange event will be raised barely when RotatorClientItemShowing has completed, i.e. the stateHandled flag is already false. This will lead to a double executing of the set_currentItemIndex method and the animation is canceled.
    Fortunately, there is a solution and it is a very simple one. Create an OnClientItemShown event handler and reset the stateHandled flag there.
    function RotatorClientItemShowing(sender, args)
    {
        stateHandled = true;
        UpdateGUI(args.get_item());
    }
    function RotatorClientItemShown(sender, args)
    {
        stateHandled = false;
    }

    One more note - handling the hash change in RotatorClientItemClicked appears irrelevant as this event handler forces another item to show thus raising the RotatorClientItemShowing event handler, where the hash change is already being handled. Therefore the method could be simplified to this:
    function RotatorClientItemClicked(sender, args)
    {
        sender.set_currentItemIndex(args.get_item().get_index(), true);
    }

    Please, find attached a sample page with the code you provided and the modifications on my side.

    Best wishes,
    Niko
    the Telerik team
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Felipe
    Felipe avatar
    33 posts
    Member since:
    Dec 2010

    Posted 29 Mar 2011 Link to this post

    Niko,

    This works perfectly!  Thank you.
Back to Top