5
\$\begingroup\$

I am a newbie jQuery developer and i have created a responsive image solution where the HTML custom data attributes are used for loading images according to size like desktop, laptop, iPad etc...

Here is a live demo of the project.

I hope you like the project. Please tell me how to improve this.

// Mezzaraine Beta Version (function ($) { jQuery.fn.extend({ mezzaraine: function () { return this.each(function () { // Optimisation: store the references outside the event handler: var $img = $(this); //Got this is a variable that hold the img id or class tag. var $window = $(window), currentWindowWidth, // width of current Window flagIs, flagWas = ''; function res() { currentWindowWidth = $window.width(); //set flag string . if (currentWindowWidth <= 640) { flagIs = "mobileLowEnd"; } else if (currentWindowWidth >= 641 && currentWindowWidth <= 768) { flagIs = "mobileHighEnd"; } else if (currentWindowWidth >= 769 && currentWindowWidth <= 1025) { flagIs = "tablet"; } else if (currentWindowWidth >= 1026 && currentWindowWidth <= 1499) { flagIs = "laptop"; } else if (currentWindowWidth >= 1500 && currentWindowWidth <= 2800) { flagIs = "large-desktop"; } if (flagIs !== flagWas) { switch (flagIs) { case 'mobileLowEnd': $('img').each(function () { if (!($(this).attr('data-mobLow') === undefined)) { $img.attr("src", $img.attr("data-mobLow")); } // Finally Without A Data Attribute Set the Original to Src// else { $img.attr("src", $img.attr("src")); } }); break; case 'mobileHighEnd': $('img').each(function () { if (!($(this).attr('data-mobHigh') === undefined)) { $img.attr("src", $(this).attr("data-mobHigh")); } else if (!($(this).attr('data-mobLow') === undefined)) { $img.attr("src", $img.attr("data-mobLow")); } // Finally Without A Data Attribute Set the Original to Src// else { $img.attr("src", $img.attr("src")); } }); break; case 'tablet': $('img').each(function () { if (!($(this).attr('data-tab') === undefined)) { $img.attr("src", $img.attr("data-tab")); } else if (!($(this).attr('data-mobHigh') === undefined)) { $img.attr("src", $img.attr("data-mobHigh")); } else if (!($(this).attr('data-mobLow') === undefined)) { $img.attr("src", $img.attr("data-mobLow")); } // Finally Without A Data Attribute Set the Original to Src// else { $img.attr("src", $img.attr("src")); } }); break; case 'laptop': $('img').each(function () { if (!($(this).attr('data-lap') === undefined)) { $img.attr("src", $img.attr("data-lap")); } else if (!($(this).attr('data-tab') === undefined)) { $img.attr("src", $img.attr("data-tab")); } else if (!($(this).attr('data-mobHigh') === undefined)) { $img.attr("src", $img.attr("data-mobHigh")); } else if (!($(this).attr('data-mobLow') === undefined)) { $img.attr("src", $img.attr("data-mobLow")); } // Finally Without A Data Attribute Set the Original to Src// else { $img.attr("src", $img.attr("src")); } }); break; case 'large-desktop': $('img').each(function () { // Check if Data-Desk Exixts then Change Src To Desk if (!($(this).attr('data-desk') === undefined)) { $img.attr("src", $(this).attr("data-desk")); } else if (!($(this).attr('data-lap') === undefined)) { $img.attr("src", $img.attr("data-lap")); } else if (!($(this).attr('data-tab') === undefined)) { $img.attr("src", $img.attr("data-tab")); } else if (!($(this).attr('data-mobHigh') === undefined)) { $img.attr("src", $img.attr("data-mobHigh")); } else if (!($(this).attr('data-mobLow') === undefined)) { $img.attr("src", $img.attr("data-mobLow")); } // Finally Without A Data Attribute Set the Original to Src// else { $img.attr("src", $img.attr("src")); } }); break; } //after we done with all this just write our present flagString to pastString (so we can use it later for compare like we did it before, variables are global, so we can access them from one iteration to another) flagWas = flagIs; } } // Execute function on load res(); // the same function will be execute each time we resize window // When Window is Resized. $(window).resize(function () { res(); }); // Page Load res(); }); } }); })(jQuery); //End Function 

You can also check the resize.js from the demo project to view code locally.

\$\endgroup\$

    2 Answers 2

    2
    \$\begingroup\$

    There's a lot of duplication in this code.

    Instead of this:

    if (currentWindowWidth <= 640) { flagIs = "mobileLowEnd"; } else if (currentWindowWidth >= 641 && currentWindowWidth <= 768) { flagIs = "mobileHighEnd"; } else if (currentWindowWidth >= 769 && currentWindowWidth <= 1025) { flagIs = "tablet"; } 

    This is the same, and if someday you'll want to adjust the thresholds, it will be a lot easier:

    if (currentWindowWidth <= 640) { flagIs = "mobileLowEnd"; } else if (currentWindowWidth <= 768) { flagIs = "mobileHighEnd"; } else if (currentWindowWidth <= 1025) { flagIs = "tablet"; } 

    In fact, it would be best to make a list of width-class pairs, and use a loop to find the first match instead of repetitive else-ifs.

    Here's another example of duplicated logic:

    if (!($(this).attr('data-tab') === undefined)) { $img.attr("src", $img.attr("data-tab")); } else if (!($(this).attr('data-mobHigh') === undefined)) { $img.attr("src", $img.attr("data-mobHigh")); } else if (!($(this).attr('data-mobLow') === undefined)) { $img.attr("src", $img.attr("data-mobLow")); } 

    The checking and setting of attributes can be simplified, using a list and a loop, something like this:

    var names = ['data-tab', 'data-mobHigh', 'data-mobLow']; for (var i in names) { var name = names[i]; if (!($(this).attr(name) === undefined)) { $img.attr("src", $img.attr(name)); break; } } 

    As a next step, you could turn this into a function and reuse in all the mobile, tablet, laptop, and other conditional branches with a different names array parameter.

    I don't know if I'm missing something but this looks utterly pointless:

    $img.attr("src", $img.attr("src")); 

    Finally, although I like to have a comfortable amount whitespace in code, this code uses a bit too much vertical spacing even for my taste.

    \$\endgroup\$
    3
    • \$\begingroup\$i have a few questions. Firstly if i do this <640 if Won't it conflict with the <768 i mean what if the values is say 300 won't it fall in both of the categories?\$\endgroup\$CommentedDec 3, 2014 at 4:52
    • \$\begingroup\$It won't. An "else if" is only executed when the "if" or "else if" before it was not matched\$\endgroup\$
      – janos
      CommentedDec 3, 2014 at 5:24
    • \$\begingroup\$@Thanks. i have a another question. How can i use a switch statement if i have to use a <640 rather than if else??\$\endgroup\$CommentedDec 3, 2014 at 5:26
    0
    \$\begingroup\$

    IMO the answer is simple: Don't implement your own JavaScript solution for responsive images, when there's already a working technology in place dealing with that. If you need to support older browsers, you might want to add a shim as well.

    \$\endgroup\$
    8
    • \$\begingroup\$maybe we can do something better by Open Source or something..\$\endgroup\$CommentedDec 2, 2014 at 12:24
    • \$\begingroup\$Sorry, I don't understand what you mean.\$\endgroup\$
      – hon2a
      CommentedDec 2, 2014 at 14:56
    • \$\begingroup\$I mean we can make it open source project.\$\endgroup\$CommentedDec 3, 2014 at 5:00
    • \$\begingroup\$I don't see how that relates to my answer. You're basically creating a JavaScript tool to accomplish something that is a brand new part of HTML5 spec. So, your tool offers less functionality than the present native solution and requires the potential user to learn your proprietary API instead of the universally useful one from the HTML5 spec.\$\endgroup\$
      – hon2a
      CommentedDec 3, 2014 at 12:31
    • 1
      \$\begingroup\$@Marc you can always follow the latest spec and then modify it to create something new..\$\endgroup\$CommentedDec 21, 2014 at 4:30

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.