Roots Discourse

Where to add Typekit, window.onload, etc?

Hey, guys… First timer here. I apologize ahead of time if the following topic is lame, but I’m stuck and could really use some guidance.

I’ve been playing with Sage and Bedrock for a few days now trying to wrap my head around how it all works. I’m really loving it for the most part, and I think the only reasons I’m not loving it are solely because I don’t fully understand everything yet.

My topic has to do with a site I’m building with Sage for the very first time. I’ve got my styles and most of my templates working wonderfully and really digging the structure. I’m also being forced to learn SASS as I’ve historically been a LESS user. All good stuff nonetheless.

I’m using Typekit to pull in custom fonts, but I’m unsure where to add my Typekit embed script. My instinct was to put it in the main.js ‘common’ area, but that doesn’t seem to be working. Where do I put my code? Any additional insights or instruction would be greatly appreciated.

My second issue is with getting Masonry to fire. I’ve only incorporated it on the homepage in this design, so again my instinct was to put it in main.js ‘home’ area, again to no avail. I’m also getting an error as follows: TypeError: undefined is not an object (evaluating ‘t.Outlayer.Item’). I’ve read through some other topics and set my bower.json overrides to masonry.pkgd.js and still getting the error. So, where do I put my code and how do I address the error?

The third issue is that I’ve included a sort of preloader overlay that I’d like to fadeOut on window.load. Same question as above, really. Where do I put this code?

I’m essentially a beginner when it comes to javascript and jQuery and only know enough to get myself in trouble, so I apologize if this topic is too simple for the community. Just know it’s of great interest and value to me and I appreciate any and all help provided.

Cordially,
– Patrick

Here is what I’m trying in _main.js. Hopefully this helps and someone can point out my mistake pretty quickly.

  // Use this variable to set up the common and page specific functions. If you
  // rename this variable, you will also need to rename the namespace below.
  var Sage = {
    // All pages
    'common': {
      init: function() {
        // JavaScript to be fired on all pages
        (function(d) {
          var tkTimeout=3000;
          if(window.sessionStorage){if(sessionStorage.getItem('useTypekit')==='false'){tkTimeout=0;}}
          var config = {
            kitId: 'XXXXXXX',
            scriptTimeout: tkTimeout
          },
          h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+"wf-inactive";if(window.sessionStorage){sessionStorage.setItem("useTypekit","false")}},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+="wf-loading";tk.src='//use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
        })(document);
      },
      finalize: function() {
        // JavaScript to be fired on all pages, after page specific JS is fired
        window.onload = function() {
          $('#loading').fadeOut(250);
        }
      }
    },
    // Home page
    'home': {
      init: function() {
        // JavaScript to be fired on the home page
        var $grid;
        function triggerMasonry() {
          // don't proceed if $grid has not been selected
          if ( !$grid ) {
            return;
          }
          // init Masonry
          $grid.masonry({
            itemSelector: '.card',
            columnWidth: '.col-md-4',
            percentPosition: true
          });
        }
      },
      finalize: function() {
        // JavaScript to be fired on the home page, after the init JS
        window.onload = function() {
          $('#loading').fadeOut( 250, function() {
            // trigger masonry on document ready
            $(function(){
              $grid = $('.grid');
              triggerMasonry();
            });
            // trigger masonry when fonts have loaded
            Typekit.load({
              active: triggerMasonry,
              inactive: triggerMasonry
            });
            // layout Masonry after each image loads
            $(function(){
              $grid.imagesLoaded().progress( function() {
                $grid.masonry('layout');
              });
            });
          });
        }
      }
    }
  };

To my somewhat-amateur eye it seems as though you’re adding code in the right places. Two questions:

  1. Can you confirm that when you alter the main.js file, the browser dev tools reflect that you are actually seeing the correct code and file in the browser?

  2. Do you have any errors in the browser dev tools console? Typically one error in console will halt any further scripts from executing as expected…

Tobyl! Thanks for looking at this!

That’s what I thought. It’s seems like I’m on the right track, but I must be missing something simple. Answers to your questions are below.

Yes, when I make changes to _main.js Im seeing the updated code in my dev tools. Here’s is what it’s outputting:

var e = {
    common: {
        init: function() {
            !function(t) {
                var e = 3e3;
                window.sessionStorage && "false" === sessionStorage.getItem("useTypekit") && (e = 0);
                var n, i = {
                    kitId: "ltt3yak",
                    scriptTimeout: e
                }, o = t.documentElement, r = setTimeout(function() {
                    o.className = o.className.replace(/\bwf-loading\b/g, "") + "wf-inactive", window.sessionStorage && sessionStorage.setItem("useTypekit", "false")
                }, i.scriptTimeout), s = t.createElement("script"), a=!1, u = t.getElementsByTagName("script")[0];
                o.className += "wf-loading", s.src = "//use.typekit.net/" + i.kitId + ".js", s.async=!0, s.onload = s.onreadystatechange = function() {
                    if (n = this.readyState, !(a || n && "complete" != n && "loaded" != n)) {
                        a=!0, clearTimeout(r);
                        try {
                            Typekit.load(i)
                        } catch (t) {}
                    }
                }, u.parentNode.insertBefore(s, u)
            }(document)
        },
        finalize: function() {
            window.onload = function() {
                t("#loading").fadeOut(250)
            }
        }
    },
    home: {
        init: function() {},
        finalize: function() {
            window.onload = function() {
                t("#loading").fadeOut(250, function() {
                    t(function() {
                        $grid = t(".grid"), triggerMasonry()
                    }), Typekit.load({
                        active: triggerMasonry,
                        inactive: triggerMasonry
                    }), t(function() {
                        $grid.imagesLoaded().progress(function() {
                            $grid.masonry("layout")
                        })
                    })
                })
            }
        }
    }
}, n = {
    fire: function(t, n, i) {
        var o, r = e;
        n = void 0 === n ? "init" : n, o = "" !== t, o = o && r[t], o = o && "function" == typeof r[t][n], o && r[t][n](i)
    },
    loadEvents: function() {
        n.fire("common"), t.each(document.body.className.replace(/-/g, "_").split(/\s+/), function(t, e) {
            n.fire(e), n.fire(e, "finalize")
        }), n.fire("common", "finalize")
    }
};
t(document).ready(n.loadEvents)

The only error I’m getting is:

TypeError: undefined is not an object (evaluating 't.Outlayer.Item')

Also, when I run Gulp I get some jshint warnings that mostly seem to deal with that Typekit code:

  line 29  col 193  Missing semicolon.
  line 29  col 455  Expected '!==' and instead saw '!='.
  line 29  col 470  Expected '!==' and instead saw '!='.
  line 29  col 479  Expected '{' and instead saw 'return'.
  line 29  col 533  Missing semicolon.
  line 29  col 577  Missing semicolon.
  line 36  col 10   Missing semicolon.
  line 78  col 10   Missing semicolon.

  ⚠  8 warnings

I’d start with the jshint warnings - Sage includes jshint which will at the very least prevent you from publishing javascript with errors (it also encourages best practices and tidy coding too). So long as you have errors in the Gulp output, I’d work on resolving them before going to the browser. Line 29 col 479 seems particularly problematic.

Second, if you see errors in the browser javascript console, any javascript code run after that error will either not run, or it will run with unexpected results. Try removing your Masonry code to see if code at least runs where and when you expect it to?

Sure enough… I removed Masonry and ImagesLoaded and things start to work again.

I have set my bower.json overrides to use masonry.pkgd.js and imagesloaded.pkgd.js which I read in other related topics.

Have you seen anyone successfully run Masonry through the Sage/Gulp workflow?

I followed this thread (Error when masonry installed with bower + gulp) and have successfully got Masonry working with some additional _main.js edits. Thank you, @tobyl for your help!