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
\$\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\$
  • \$\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\$ – Marc Andre Jiacarrini Dec 3 '14 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\$ – Stop ongoing harm to Monica Dec 3 '14 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\$ – Marc Andre Jiacarrini Dec 3 '14 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\$
  • \$\begingroup\$ maybe we can do something better by Open Source or something.. \$\endgroup\$ – Marc Andre Jiacarrini Dec 2 '14 at 12:24
  • \$\begingroup\$ Sorry, I don't understand what you mean. \$\endgroup\$ – hon2a Dec 2 '14 at 14:56
  • \$\begingroup\$ I mean we can make it open source project. \$\endgroup\$ – Marc Andre Jiacarrini Dec 3 '14 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 Dec 3 '14 at 12:31
  • 1
    \$\begingroup\$ @Marc you can always follow the latest spec and then modify it to create something new.. \$\endgroup\$ – designerNProgrammer Dec 21 '14 at 4:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.