SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Member
    Join Date
    Jun 2011
    Location
    Chicago
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [code review] sizeit.js - js utility for responsive web design

    I've created a javascript utility for detecting screen size and dynamically loading css. Works kinda like media queries. I posted the code and examples on github. It is open source and free for anyone to use as they like. You can read more information about it on github or on the sizeit.js website.

    I have a couple simple demos posted: demo1 and demo2

    My background is first in art/design, then Flash/AS3 design and development. Getting into JavaScript has been fun. Always trying to get better, so feedback is appreciated.

    The code for the utility itself is:

    Code javascript:
    (function(window) {
     
        var config = {};
        var screenW = window.innerWidth || document.body.clientWidth;
     
        function update() {
     
            screenW = window.innerWidth || document.body.clientWidth;
            var newSize;
     
            for (var i = 0; i < config.settings.length;  i++) {
     
                var setting = config.settings[i];
     
                if (screenW < setting.max) {
                    newSize = setting;
                    break;
                } else if (!setting.max) {
                    newSize =  setting;
                }
            }
     
            if (!config.size || newSize.name != config.size.name) {
                config.size = newSize;
            } else {
                newSize = null;
            }
     
            if (config.size.css && newSize) {
     
                // if there is a stylesheet, update it, otherwise make new
                if (config.css) {
     
                    var links = document.getElementsByTagName("link");
     
                    for (i = 0; i < links.length; i++) {
     
                        if (links[i].getAttribute("title") == "sizeit") {
                            config.css.href = config.size.css;
                            break;
                        }
                    }
     
                } else {
     
                    config.css = window.document.createElement("link");
                    config.css.href = config.size.css;
                    config.css.type = "text/css";
                    config.css.rel = "stylesheet";
                    config.css.title = "sizeit";
                    window.document.getElementsByTagName("head")[0].appendChild(config.css);
                }
            }      
        }
     
        window.sizeit = {
     
            configure : function() {
     
                config.settings = arguments;
     
                // sort by breakpoints, lowest to highest
                for (var i = 0; i < config.settings.length; i++)
                {
                    for (var j = i + 1; j < config.settings.length; j++)
                    {
                        if (config.settings[i].max > config.settings[j].max)
                        {
                            s = config.settings[j];	
                            config.settings[j] = config.settings[i];
                            config.settings[i] = s;
                        }
                    }
                }
     
                update();
     
                if (window.addEventListener) {
                    window.addEventListener("resize", update, false);
                } else if (window.attachEvent) {
                    window.attachEvent("resize", update);
                } else {
                    window.onresize = update;
                }
     
            },
     
            size : function() {
                return config.size.name;
            },
     
            width : function() {
                return screenW;
            }
        };
     
    })(this);

    You use it like this:

    Code javascript:
    sizeit.configure(
        {
            max: 600,
            css: "css/small.css",
            name: "small"
        },
        {
            max: 1024,
            css: "css/medium.css",
            name: "medium"
        },
        {
            css: "css/large.css",
            name: "large"
        }
    );

  2. #2
    SitePoint Wizard bronze trophy chris.upjohn's Avatar
    Join Date
    Apr 2010
    Location
    Melbourne, AU
    Posts
    2,183
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Nice job bud but there was a major issue with your code which stopped it from working in Internet Explorer, i have submitted 2 forks to your GitHub project so you can see the changes i made.
    Blog/Portfolio | Evolution Xtreme | DFG Design | DFG Hosting | CSS-Tricks | Stack Overflow | Paul Irish
    Having lame problems with your code? Let us help by using a jsFiddle

  3. #3
    SitePoint Member
    Join Date
    Jun 2011
    Location
    Chicago
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Sgt! Coming from flash, having to deal with IE issues has been a new thing for me, so I appreciate your help. I merged your changes into the repo.

  4. #4
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    8,892
    Mentioned
    138 Post(s)
    Tagged
    2 Thread(s)
    I have three things that stand out to me from this script:

    1) Why does the user need to supply a name for the script? It looks like you're using the name internally to see if the script is already loaded, but you could just as well take the index of the CSS you're loading in the list. E.g.

    Code javascript:
    screenW = windowSize();
    var newSize;
    var newIndex;
    var i;
     
    for (i = 0; i < config.settings.length; i++) {
       var setting = config.settings[i];
     
       if (screenW < setting.max) {
          newSize = setting;
          newIndex = i;
          break;
       } else if (!setting.max) {
          newSize = setting;
          newIndex = i;
       }
    }
     
    if (!config.size || newIndex != config.index) {
      config.size = newSize;
      config.index = newIndex;
    }
    (not tested)

    Sure it makes the code a bit more verbose, but it prevents the extra parameter 'name' that I don't feel should be there in the first place (plus, it'll prevent questions from others asking "what do I set for the name? does it matter what I set? Can I give two scripts the same name? etc... etc...")

    2) It would be cool if instead of one CSS file, the script could accept an array of CSS files, so you can add multiple CSS files at once

    Code javascript:
    {
       css: ["style1.css", "style2.css"],
       max: 1024
    }

    3) This is a bit picky maybe, but I wouldn't expect a function called 'configure' to actually do something, other than just configuring the object so I can later call another function that actually makes the object do it's thing.
    A more appropriate name for that function would IMHO be something like 'apply', 'initialize', 'go', etc.

    Other than that it looks good to me, nice job
    Rémon - Hosting Advisor

    Minimal Bookmarks Tree
    My Google Chrome extension: browsing bookmarks made easy

  5. #5
    SitePoint Member
    Join Date
    Jun 2011
    Location
    Chicago
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for your feedback Scallio

    1) I have the name parameter so I can get the current size setting from other scripts (for example, to use with Mustache to add html to the page based on the size). I think you have a good point though, so I think I will make the param optional. Maybe I'll have it return the index instead if it isn't set. I'll think some more about this one...

    2) I like that. Will do.

    3) The configure function both configures the settings and starts 'doing its thing', all in one function. There is no second function call to start it working.

    Glad I posted this here. Just the type of responses I was hoping for.


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •