[jQuery] 반응형 이미지로더(Responsive image loader) on redgoose note

[jQuery] 반응형 이미지로더(Responsive image loader)

Nest: Development Category: Javascript 2013-07-18

  • 반응형 레이아웃에서 pc화면에서 큰 이미지를 사용할때 <img/>엘리먼트가 들어가면 무조건 전송요청을 하게되어 화면표시 속도에 지장을 준다.
  • 이 responsiveImageLoader plugin은 모바일화면일때 pc화면의 이미지를 전송요청하지 않으며, pc화면으로 바뀔 때 전송요청을 하게된다.
  • jQuery를 사용하는 플러그인
  • 샘플 URL : http://codepen.io/redgoose/pen/ilzvK

Load matchMedia

미디어쿼리를 확인하기 위하여 먼저 로드한다.

/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */
window.matchMedia = window.matchMedia || (function(doc,undefined) {
    "use strict";

    var bool,
        docElem = doc.documentElement,
        refNode = docElem.firstElementChild || docElem.firstChild,
        // fakeBody required for FF4 when executed in <head>
        fakeBody = doc.createElement( "body" ),
        div = doc.createElement( "div" )
    ;

    div.id = "mq-test-1";
    div.style.cssText = "position:absolute;top:-100em";
    fakeBody.style.background = "none";
    fakeBody.appendChild(div);

    return function(q){
        div.innerHTML = "­<style media=\"" + q + "\"> #mq-test-1 { width: 42px; }</style>";

        docElem.insertBefore( fakeBody, refNode );
        bool = div.offsetWidth === 42;
        docElem.removeChild( fakeBody );

        return {
        matches: bool,
        media: q
        };
    };
}(document));

responsiveImageLoader

플러그인 호출하기 이전에 로드한다.

// Responsive image loader
$.fn.responsiveImageLoader = function()
{
    var
        $this = $(this)
        ,rwd = function(item)
        {
            var matches = new Array();
            item.children('[data-src]').each(function(){
                var media = $(this).attr('data-media');

                if (!media || (window.matchMedia && matchMedia(media).matches))
                {
                    matches.push($(this)[0]);
                }
            });

            var images = item.find('img');

            if (matches.length)
            {
                var matchElement = $(matches.pop());
                if (!matchElement.children().length)
                {
                    images.remove();
                    matchElement.append(
                        '<img src="' + matchElement.attr('data-src') + '" alt="' + item.attr('data-alt') + '" />'
                    );
                }
            }
            else
            {
                images.remove();
            }
        }
    ;

    $this.each(function(){
        var item = $(this);
        $(window).on('resize', function(){
            rwd(item);
        });
        $(document).ready(function(){
            rwd(item);
        });
    });
}

html

<div id="wrap">
    <i rwd-image data-alt="image alt">
        <i data-src="default.jpg"></i>
        <i data-src="mobile.jpg" data-media="(min-width:320px)"></i>
        <i data-src="tablet.jpg" data-media="(min-width:768px)"></i>
        <!--[if (lt IE 9) & (!IEMobile)]>
            <i data-src="old_ie.jpg"></i>
        <![endif]-->
    </i>
</div>

플러그인 호출

$('#wrap [rwd-image]').responsiveImageLoader();