views:

196

answers:

2

Why does Firefox 3.6 alter jQuery and CSS properties?

Alright, more specifically. I have a crossfade plugin to create a glow effect between two images that are placed on top of each other. The function (posted below) will make the top image transition to an opacity of 0 in 200 ms on hover and transition back to an opacity of 1 in 500 ms on hover-off. My problem is that the original image is not being displayed now within Firefox 3.6.6.

HTML looks like this:

  <div id="logout-button">
     <img class="fade" src='/img/test/control-logout.jpg' style="background:url(/img/test/control-logout-hover.jpg); border:none;"/>
  </div>

CSS looks like this:

  #control-bar #logout-button{
      float:right;
      margin:3px 30px 0 0;
  }

  #logout-button img.fade{
      margin:-1px 0 0 0;
      width:33px;
      height:22px;
      cursor:pointer;
      border:none;
  }

jQuery functions page looks like this:

  $(window).bind('load', function(){
    $("img.fade").crossfade();
  });

jQuery Crossfade plugin looks like this:

    $.fn.crossfade = function(){
        return this.each(function(){
            var $$ = $(this);
            var target = $$.css('backgroundImage').replace(/^url|[\(\)]/g, '');
            $$.wrap('<span style="position: relative;"></span>').parent().prepend('<img>').find(':first-child').attr('src', target).css({border:'none'});
            if(jQuery.browser.msie){
                $$.css({position:'absolute', left:0, top:'0px', border:'none'});
            }else{
                $$.css({position:'absolute', left:0, top:'-6px', border:'none'});
            };
            $$.hover(function(){
                     $$.stop().animate({opacity: 0}, 200);
            }, function(){
                  $$.stop().animate({opacity: 1}, 500);
            }, 0);
        });
    };
+1  A: 

When you create the target value with:

        var target = $$.css('backgroundImage').replace(/^url|[\(\)]|/g, '');

The target value comes out wrapped in quotes ("). When the src attribute is then set, it is double quoted ""foo.jpg"" and thus is invalid HTML.

Changing the above to:

        var target = $$.css('backgroundImage').replace(/^url|[\(\)]|"/g, '');

Will eliminate the extra quotes and should make it work...

Edit: Hmm, it worked for me, but I don't have an older firefox available... Perhaps it would be easier to work with just background urls...

HTML:

<div class="pic"><div class="pic2"></div></div>

CSS:

div.pic {
    position: relative;
    width:50px; 
    height: 48px;
    background: url(http://static.jquery.com/ui/images/logo.gif);
    float:right;
    margin:3px 30px 0 0;
}
div.pic2 {
    position: absolute; 
    top: 0; bottom: 0; 
    left: 0; right: 0;
    background: url(http://static.jquery.com/files/rocker/images/btn_downloadLarge.gif);
}

JS:

$.fn.crossfade = function(){
    return this.each(function(){ 
        var $$ = $(this).find('.pic2');
        $$.hover(function(){
            $$.stop().animate({opacity: 0}, 200);
        }, function(){
            $$.stop().animate({opacity: 1}, 500);
        }, 0);
    });
}
$("div.pic").crossfade();

You can see a live example at jsfiddle: http://jsfiddle.net/MntuZ/1/

This works for me on FF3.6 and Chrome 5 (all I have access to on this computer.) This is assuming the example does what you're trying to do...

carpie
no that does not work, infact that solution makes earlier versions of firefox (previously working properly) do the same thing as 3.6 is doing (not displaying the image).
sadmicrowave
+1  A: 

Here, this will do it: http://jsfiddle.net/nfLrg/

After some serious debugging there, I found out same what carpie found, that..
var target = $$.css('backgroundImage').replace(/^url|[\(\)]/g, '');
..leaves quotes around the result, and when you insert it later in image src, the quotes are doubled resulting in src="%22<target>%22" with %22 being the doubled quote.

Therefore, changing it into..
var target = $$.css('backgroundImage').replace(/^url|[\(\)]|['"]/g, '');
..will remove the unneeded quotes. (see the |['"] added inside regex)

Plus, I removed all the unnecessary .css() calls, because it is much easier to handle those inside css itself.

This is all CSS I used:

#logout-button {
}
#logout-button img.fade {
    cursor: pointer;
}
#logout-button span.fake img {
    position: absolute;
}

And, yeah, in jsFiddle CSS I left more tags and commented them.

By the way, tested and works perfectly on IE6, IE7, IE 8, Firefox 3.6, Google Chrome 5, Opera 10.60, Safari 4.0.5. And that kind of gives me feeling that it should work on other browsers too.

EDIT:

Actually, I think there are easier solutions available. I will check for them when I get home tomorrow.

Tom
I ended up getting rid of the plugin entirely and positioning the images directly over each other in my CSS then on top image hover made the opacity turn to 0 and on hover out turn opacity back to 1 in a jQuery function. Basically the same as the plugin but without having to use an extra plugin and js reference. While I'm going to use my current way of doing this function I tested Tom's 'fix' and it worked for me so I will be awarding the credit to Tom. Thanks anyways Carpie and all others, your replies are very appreciated!!!
sadmicrowave