1

I'm working on a script uses jQuery's data() function and HTML5 data attributes to dynamically switch an image's src attribute based on a media query. The idea behind this is to serve a lo-fi image by default (optimized for mobile), and serve a hi-fi image for larger screens. (This is not necessarily limited to images.) The script works 100% in Chrome/Opera/Safari/iOS but not completely in FF and IE.

<img src="ex1_lo-res.png" data-websrc="ex2_hi-res.png" alt="example">
<img src="ex2_lo-res.png" data-websrc="ex2_hi-res.png" alt="example">

A live example of this in use is responsetheme.com, where above 480px wide, the image should be pink, and below 480px wide, it should be yellow. I know that both data() and Modernizr.mq are supported in FF and IE—I tested them without the resize() function. So I think the issue has something to do with the trigger or the each() or resize() function. Any idea on what I'm missing?

jQuery(document).ready(function($) {
    /* get elements that have a data-websrc attribute */
    $websrc = $('[data-websrc]');   

    $websrc.each(function() {   
        /*
        Set data-osrc equal to element's original src value.
        This allows us the ability to access the original src
        (even after we replace the attribute).
        */
        var $this = $(this);    
        $this.data('osrc', $this.attr('src'));
    });             

    $(window).resize(function() {
        /*
        Check breakpoint. 
        (Modernizr.mq checks the media query and returns boolean.)
        */
        airsrcWEB = Modernizr.mq('screen and (min-width:480px)');

        /*
        Replace src with data-websrc (if above breakpoint). 
        Otherwise fallback to data-osrc (original src).
        */
        $websrc.each(function() {           
        var $this = $(this);    
            var src = ( window.airsrcWEB ) ? $this.data('websrc') : $this.data('osrc');
            $this.attr('src', src);
        });                 
    }).resize(); // trigger resize handlers
});

Also, I wasn't sure as to whether I have the functions in the most efficient way as far as which was inside which, so I'd also like to hear any tips for speeding this up. =)

Update 1: I also tried with the ternary like this and still the same issue:

var src = ( airsrcWEB ) ? $this.data('websrc') : $this.data('osrc');

Update 2: I figured out the issue with FF. Apparently a FF6 window won't resize below about 556px wide. I tested the script with a breakpoint above that and the switch worked. (Even the examples on mediaqueri.es won't shrink below 556px wide in FF6.)

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
ryanve
  • 50,076
  • 30
  • 102
  • 137
  • What does `Modernizr.mq('screen and (min-width:480px)')` return? – ShankarSangoli Aug 21 '11 at 00:11
  • 1
    I think its already returning false so you are not seeing any change. – ShankarSangoli Aug 21 '11 at 00:23
  • It returns true when the window is wider than 480px. I had also tried using `$(window).width() >= 480` rather than the Modernizr check but that didn't make a difference. FYI: [modernizr.com/docs/#mq](http://www.modernizr.com/docs/#mq) – ryanve Aug 21 '11 at 00:49
  • @ShankarSangoli It returns true when the window is wider than 480px. (forgot to @ you in the previous comment) – ryanve Aug 21 '11 at 01:35
  • 1
    I think your each-loop is wrong. It should read `$.each($websrc, function() {......` – Alxandr Aug 21 '11 at 02:19
  • @Alxandr Thx—both ways seem to work and neither gives an error in the console. What makes the other way wrong? – ryanve Aug 21 '11 at 02:41
  • 1
    It's not cross-browser. It relies on the javascript array supporting the each-function (which in most newer browser it does), but it'll probably crash in IE (at least older versions) saying something like "object not defined" or "each is not a function" or something like that. – Alxandr Aug 21 '11 at 02:43
  • @Alxandr Cool/thanks—I'll definitely use that way then. I got it working everywhere now but to support IE I had to use a function that checked `$(window).width() >= 480px` rather than Modernizr.mq – ryanve Aug 21 '11 at 04:40
  • @ShankarSangoli In old IE you're right about the `false' from Modernizr.mq - Good call. I didn't think my previous check worked b/c I'd had the CSS embedded. For media queries to work in old IE via [respond.js](https://github.com/scottjehl/Respond/blob/master/README.md) they need to be in an external stylesheet. – ryanve Aug 21 '11 at 04:45
  • @ryanve - Did you debug `window.airsrcWEB` and see in other browsers after window resize? – ShankarSangoli Aug 21 '11 at 04:52
  • What a neat solution, I'd love to integrate this script [with responsive web design I'm working on using Featured Images](http://wordpress.stackexchange.com/questions/27385/whats-the-best-way-to-use-the-featured-image-for-responsive-web-design). – micah Sep 03 '11 at 07:20

1 Answers1

0

You already found out that FF has a minimal window size. I don't know the exact value, but I believe it's a percentage of the initially available viewport width. This is a restriction of XUL, the language in which FF was written.

The question is, is this really a problem in your case? The only persons that fiddle around with the window size are (front-end) webdevelopers. Normal users just load a page and stick with it, so basically I'm thinking that you might not really need to attach this functionality to a resize event.

Furthermore, this is only an issue when users are shrinking the window, not when expanding. If they already loaded the hi-res image, why bother loading the low-res aswell?

publicJorn
  • 193
  • 2
  • 10