Note to {JT} about javascript customization

jfriendjfriend Registered Users Posts: 8,097 Major grins
This is a note to {JT}. We need a new event (kind of like onPhotoshow.subscribe) that signifies that as far as Smugmug is concerned, the page is fully done and everything they are going to add to the page has been added.

Problem Statement: How do you trigger your own javascript event when Smugmug is done adding things to the page?

With the recent addition to Smugmug pages of more and more dynamically created objects that are created at YE.onDOMReady time, it has suddenly become quite difficult to reliably do certain kinds of javascript customization because there's no reliable way to trigger an event when Smugmug is done building the page. It used to be that at YE.onDOMReady time, anything Smugmug was putting in the page was there because it came from the page load. But now some things are added dynamically to the page at YE.onDOMReady time (slideshow button, share button, buy button, cart button, etc...). Since there is no guaranteed execution order of YE.onDOMReady calls, it's very difficult to find a way to trigger execution of your own javascript function when Smugmug is done with the page.

If you only care about modifying one javascript object, you can use YE.onContentReady for that one object. But, if you want to run some javascript that operates on multiple objects and some of those are dynamically craeted things, there is no easy way to do it.

An example: A user wants a javascript function that will move the slideshow button and place it on the same row as the buy button. Both of those buttons are dynamically created things. How do I trigger a javascript function at the earliest possible moment that both of these objects and their containers are fully formed?

One Solution: While there are probably many ways to solve this dilemna, one way would be by creating a new page-level event that Smugmug triggers when all their own dynamically created objects are done (perhaps similar to the way onPhotoShow.subscribe() works). Then, we could just register an interest in the event that tells us that Smugmug is done adding things to the page and we'd know the page was ours to safely modify now.
--John
HomepagePopular
JFriend's javascript customizationsSecrets for getting fast answers on Dgrin
Always include a link to your site when posting a question

Comments

  • devbobodevbobo Registered Users, Retired Mod Posts: 4,339 SmugMug Employee
    edited February 4, 2009
    jfriend wrote:
    An example: A user wants a javascript function that will move the slideshow button and place it on the same row as the buy button. Both of those buttons are dynamically created things. How do I trigger a javascript function at the earliest possible moment that both of these objects and their containers are fully formed?

    John,

    I believe that this case should be simple enough to handle with two cascaded YE.onContentReady events.
    YE.onContentReady('fsssButton', function() { YE.onContentReady('buyButton', moveSlideshowButton) });
    
    function moveSlideshowButton() {
     // add move code here
    }
    

    Cheers,

    David
    David Parry
    SmugMug API Developer
    My Photos
  • jfriendjfriend Registered Users Posts: 8,097 Major grins
    edited February 4, 2009
    devbobo wrote:
    John,

    I believe that this case should be simple enough to handle with two cascaded YE.onContentReady events.
    YE.onContentReady('fsssButton', function() { YE.onContentReady('buyButton', moveSlideshowButton) });
    
    function moveSlideshowButton() {
     // add move code here
    }
    
    Cheers,

    David
    Thanks for the idea. I solved it yesterday with something similar here (your idea is slightly better than what I used). But, it has a bunch of edge cases. Like, what if there is no buy button on the page and my code wants to do something different in the case of no buy button? I couldn't think of any way to solve that case other than a timer and by the time you're sure an object isn't going to get put in the page, the page has already been displayed for awhile.

    It would be really useful to have an event when Smumug is done adding things to the page.
    --John
    HomepagePopular
    JFriend's javascript customizationsSecrets for getting fast answers on Dgrin
    Always include a link to your site when posting a question
  • {JT}{JT} Registered Users Posts: 1,016 Major grins
    edited February 4, 2009
    This may have to wait for the rewrite of the site, since each page is different from the next and on several pages we are truly never done writing or altering the page.

    jfriend wrote:
    Thanks for the idea. I solved it yesterday with something similar here (your idea is slightly better than what I used). But, it has a bunch of edge cases. Like, what if there is no buy button on the page and my code wants to do something different in the case of no buy button? I couldn't think of any way to solve that case other than a timer and by the time you're sure an object isn't going to get put in the page, the page has already been displayed for awhile.

    It would be really useful to have an event when Smumug is done adding things to the page.
  • jfriendjfriend Registered Users Posts: 8,097 Major grins
    edited February 4, 2009
    {JT} wrote:
    This may have to wait for the rewrite of the site, since each page is different from the next and on several pages we are truly never done writing or altering the page.

    I'm not sure what you mean by "truly never done". I''m just interested in when all the static elements that are added via javascript have been added to the page (slideshow button, buy button, cart button, etc...). I'm just look for something similar to onPhotoShow.subscribe(), but in this case it would be onPageBuilt.subscribe() of something like that.
    --John
    HomepagePopular
    JFriend's javascript customizationsSecrets for getting fast answers on Dgrin
    Always include a link to your site when posting a question
  • {JT}{JT} Registered Users Posts: 1,016 Major grins
    edited February 4, 2009
    So it would fire after the thumbs loaded, or the main image then? Or what if the lightbox had to come up?
    jfriend wrote:
    I'm not sure what you mean by "truly never done". I''m just interested in when all the static elements that are added via javascript have been added to the page (slideshow button, buy button, cart button, etc...). I'm just look for something similar to onPhotoShow.subscribe(), but in this case it would be onPageBuilt.subscribe() of something like that.
  • devbobodevbobo Registered Users, Retired Mod Posts: 4,339 SmugMug Employee
    edited February 4, 2009
    jfriend wrote:
    Thanks for the idea. I solved it yesterday with something similar here (your idea is slightly better than what I used). But, it has a bunch of edge cases. Like, what if there is no buy button on the page and my code wants to do something different in the case of no buy button? I couldn't think of any way to solve that case other than a timer and by the time you're sure an object isn't going to get put in the page, the page has already been displayed for awhile.

    It would be really useful to have an event when Smumug is done adding things to the page.

    John,

    This could be achieved with some additional logic pretty easily...
    var actionTaken = false;
    
    YE.onContentReady('fsssButton', function() { YE.onContentReady('buyButton', moveSlideshowButton) });
    
    YE.on(window, "load", noSlideshowButton);
    
    function moveSlideshowButton() {
      actionTaken = true;
     // add move code here
    }
    
    function noSlideshowButton() {
      if (actionTaken)
        return;
    
      //add code for alternate action
    }
    

    Cheers,

    David
    David Parry
    SmugMug API Developer
    My Photos
  • jfriendjfriend Registered Users Posts: 8,097 Major grins
    edited February 4, 2009
    devbobo wrote:
    John,

    This could be achieved with some additional logic pretty easily...
    var actionTaken = false;
    
    YE.onContentReady('fsssButton', function() { YE.onContentReady('buyButton', moveSlideshowButton) });
    
    YE.on(window, "load", noSlideshowButton);
    
    function moveSlideshowButton() {
      actionTaken = true;
     // add move code here
    }
    
    function noSlideshowButton() {
      if (actionTaken)
        return;
    
      //add code for alternate action
    }
    
    Cheers,

    David

    Is window load guaranteed to be after all calls to onDOMReady?
    --John
    HomepagePopular
    JFriend's javascript customizationsSecrets for getting fast answers on Dgrin
    Always include a link to your site when posting a question
  • devbobodevbobo Registered Users, Retired Mod Posts: 4,339 SmugMug Employee
    edited February 4, 2009
    jfriend wrote:
    Is window load guaranteed to be after all calls to onDOMReady?

    i'm pretty certain you should be fine, since window.load isn't called until all images etc have been loaded.
    David Parry
    SmugMug API Developer
    My Photos
  • jfriendjfriend Registered Users Posts: 8,097 Major grins
    edited February 4, 2009
    devbobo wrote:
    i'm pretty certain you should be fine, since window.load isn't called until all images etc have been loaded.
    OK, that could work. It would be a little less than ideal because it could be a lot later than required, but I guess it's all I've got.

    If YUI would guarantee that onDOMReady calls were called in the order they registered, my onDOMReady call in the footer javascript could work too, but I can't find anything written about onDOMReady calling order. I could look at their code to see how it works, but if it's not documented, then it could change.
    --John
    HomepagePopular
    JFriend's javascript customizationsSecrets for getting fast answers on Dgrin
    Always include a link to your site when posting a question
  • bwgbwg Registered Users, Retired Mod Posts: 2,119 SmugMug Employee
    edited February 4, 2009
    jfriend wrote:
    OK, that could work. It would be a little less than ideal because it could be a lot later than required, but I guess it's all I've got.

    If YUI would guarantee that onDOMReady calls were called in the order they registered, my onDOMReady call in the footer javascript could work too, but I can't find anything written about onDOMReady calling order. I could look at their code to see how it works, but if it's not documented, then it could change.
    event subscribers are fired in the order they are added.
    Pedal faster
  • jfriendjfriend Registered Users Posts: 8,097 Major grins
    edited February 4, 2009
    bigwebguy wrote:
    event subscribers are fired in the order they are added.
    Is that documented to be that way or just happens to be that way? It makes logical sense, but I'm wondering if it's a behavior that you can rely on never changing?
    --John
    HomepagePopular
    JFriend's javascript customizationsSecrets for getting fast answers on Dgrin
    Always include a link to your site when posting a question
  • bwgbwg Registered Users, Retired Mod Posts: 2,119 SmugMug Employee
    edited February 5, 2009
    jfriend wrote:
    Is that documented to be that way or just happens to be that way? It makes logical sense, but I'm wondering if it's a behavior that you can rely on never changing?
    there is no documentation that i can find that says they are guaranteed to be fired in order, but the code guarantees it.

    How you interpret that is up to you.
    Pedal faster
Sign In or Register to comment.