An Extendible Deferred Asset Responsive Framework
A cross browser platform for implementing and creating gracefully degrading Responsive techniques
<noscript></noscript></style>Respondu now uses
</noscript-->must have the two dashes for cross browser compatibility
<!-- -->(comment tags) inside the
<noscript>tags, only relevant content (such as a picture element) goes inside a noscript tag
<noscript></noscript-->tag, processes the code and reinserts it in the place where Respondu is called
Examples can be found at http://respondu.davidmarkclements.com
The end dashes in
</noscript--> are essential for Respondu to operate in certain browsers (Safari, IE8)
and to block the img src's from loading prior to responsive processing.
The positioning of the Respondu call in the body, just before the noscript tag is also essential. See How It Works.
Basic usage will apply the default breakpoints
breakpoints:typical: 500 //typical will leave src unchangedmedium : 1000 //configurable properties, will be reflected in requested image e.g. name.medium.pnglarge : Infinity //largest size set to infinity
Break points can be set thusly
Respondu also provides an implementations system, it currently includes the picture and srcset implementations plus the new hybrid implementation which combines the best of both.
For picture we would do something like
For srcset we could do
We create an implementation by adding it to the Respondu prototype, the format for creating an implementation is:
Responduplugin'MyNewImplementation'// all your code heredone;;
doc parameter is a DOM object (but not the actual DOM)
done paremeter is called as a function when processing is complete
done callback function allows for any async stuff)
We could then use it with
Here's how we could implement picture (already included):
Responduplugin'picture'if 'srcset' in documentcreateElement'picture' //if picture is implemented then just pass throughif done done;return;var pictures = docgetElementsByTagName'picture' pic attrs sources src i cmedia sourceImg img sW = windowscreenwidth pixelRatiopr = windowdevicePixelRatio || 1;//set devices pixel ratio;fori = 0; i < pictureslength; i++pic = picturesi;attrs = picattributes;sources = picgetElementsByTagName'source';sourceCandidates = ;forc = 0; c < sourceslength; c++srcel = sourcesc;media = srcelgetAttribute'media';//!media means no media attribute, so will be used if no other source elements qualifyif !media || matchMediamediamatches sourceCandidatespushsrcel;var x = sourceCandidateslength closest = 0;if x > 1whilex--media = sourceCandidatesxgetAttribute'media';if !media && sourceCandidateslength > 1delete sourceCandidatesx;break;media = mediamatch/\(-width:\)/;if Mathabsmedia2 - sW <= Mathabsclosest - sWclosest = media2;sourceImg = sourceCandidatesx;elsesourceImg = sourceCandidates0;var srcset srcsetCounter srcsetToken imageSrc;if sourceImgsrcset = sourceImggetAttribute'srcset'split',';srcsetCounter = srcsetlength;while srcsetCounter--srcsetToken = srcsetsrcsetCounterreplace/^\s\s*/ ''replace/\s\s*$/ ''split' ';if srcsetToken1 === pr + 'x'imageSrc = srcsetToken0;if !srcsetToken1//no density supplied, assume defaultimageSrc = srcsetToken0;img = doccreateElement'img'; //create a new image element on the ghost DOMimgsetAttribute'src' imageSrc;forc = 0; c < attrslength; c++imgsetAttributeattrscnodeName attrscnodeValue;picparentNodereplaceChildimg pic; //replace picture element with created img elementdone; //finished.;
Wrapping content in
<noscript> tags stops it from being added to the DOM, whilst also providing complete content to non-js clients (such as
search engine bots, screen readers, text browsers).
On some browsers its possible to extract and process the content of the
<noscript> tags using normal methods (e.g. getElementById etc.)
So Respondu uses a hack to to ensure the content can be extracted from all browsers.
We do this by dynamically wrapping the
<noscript> tags in another context - there are several ways: comments, textareas, script tags, style tags...
After experimentation and thought, Respondu's chosen way is to use the
<noscript>#content#</noscript--> technique, once Respondu has been called
<--<noscript>#content#<noscript-->. The dashes in the closing noscript tag enables us to close a dynamically inserted comment opener.
Dynamically wrapping the noscript tags in a comment prevents browsers such as IE and Safari from stripping the contents out of noscript. Respondu reliest on being called just before the noscript tags, so that it
As a result, we can't put HTML comments inside our noscript tags (which means conditional comments are out). If we really want to have
comments within our noscript HTML we can use
Once the noscript content has been extracted, Respondu loads it into a "ghost DOM". (see createHTMLDocument)
The ghost DOM doesn't load any src's. We can manipulate this ghost DOM as the
doc parameter when creating implementations (see Creating an Implementation)
When all changes have been made to our ghost document (e.g. when we've replaced img src's according to screen width), we load it into the real document
If we want to have scripts execute once the DOM has loaded, the best place for them (if possible) is usually just before the closing
If you're using Respondu, you want them to be just before the closing
</noscript--> tags, Respondu will then ensure they are loaded and executed
after all the content has loaded.
<body><script>Respondu();</script><noscript>content etc.<script src=myScriptWhichWillManipulateTheDocument.js></script></noscript--></body>
If you're using jQuery, and absolutely need to include scripts in the head but you're using
to defer execution until the DOM has loaded then Respondu can accomodate you.
Just include doclate.js after jQuery, but before R.js
<script src=//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js></script><script src='js/doclate.js'></script><script src='js/R.js'></script>
In production you'll probably want to merge (and minify) doclate.js and R.js to reduce the amount of HTTP connections on page load.
Any calls to any variations of jQuery's DOM ready (
$(document).bind('ready', fn) or simply
will be buffered by doclate and then executed (in order) by R.js after all the responsive processing has completed.
Whilst this makes things easier, it's not as efficient as simply including your scripts at the bottom of the body.
I warmly welcome all contributions, you can help by