2

I am trying to build a jQuery plugin that implements some functionality I already have in my site (but in an easy to reuse way): changing the "src" attribute of an image based on the width of the browser.

The problem is that when loading the new image, the img element collapses to 0 height and width for a moment, and then jumps to the new height. Even preloading the image is not enough (I think that it's because of the huge dimensions that makes it take its time loading even after being pre-downloaded).

I decided to do this:

  • Set the current src as a CSS background-image attibute.
  • Force the size of the image to match the one that's now the background.
  • Then setting the new src.
  • When the new src loads, revert the forced size to let the new src (or whatever other rules or properties the programmer used before) define it again.

I don't want to mess up the user's (by user I mean the programmer using my library) CSS rules and HTML attributes.

The problem is that the size can be defined in different ways, por example:

  • using <img width="xx" height="yy">
  • using CSS: img { width: xx, height: yy }
  • letting the loaded file impose it's own dimensions

So, the behavior I am looking for is:

  • the programmer defines the img dimensions any way he wants
  • my plugin momentarily force-freezes those dimensions during src change
  • when it unfreezes them, the dimensions are again determined by the programmers original rules

The question is: How can I unset the forced dimensions in a way that restores previous rules, even when it's just the image file the one ruling them?

Sebastián Grignoli
  • 32,444
  • 17
  • 71
  • 86
  • Can this be related? http://stackoverflow.com/questions/754607/can-jquery-get-all-css-styles-associated-with-an-element – Sergio Aug 16 '13 at 22:37

2 Answers2

1

Simply use inline style. It overrides all other style attributes. You can use !important for good measure.

demo

Community
  • 1
  • 1
raam86
  • 6,785
  • 2
  • 31
  • 46
1

Use the fact that !important inline style overrides everything else. So, your algorithm should:

  1. Store previous inline settings. The easiest way by far is just storing element.style.cssText;
  2. Then set your freeze-values;
  3. Then restore the previous settings (again, by setting element.style.cssText).

=== (Edited so I can add the solution in code and accept the answer)

Okay, I did what you said and it worked fine:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

<div>
<img id="myimg" src="http://i.imgur.com/8eos7vW.jpg" height="200" style="height:300px;"/>
<img id="myimg2" src="http://i.imgur.com/8eos7vW.jpg" height="200"/>
<img id="myimg3" src="http://i.imgur.com/8eos7vW.jpg"/>
</div>

<script>
$('div').append("<BR>element height: " + document.getElementById('myimg').height + "px");
top.backupcss = document.getElementById('myimg').style.cssText;
top.backupcss2 = document.getElementById('myimg2').style.cssText;
top.backupcss3 = document.getElementById('myimg3').style.cssText;
$('div').append("<BR>element.style.cssText: " + top.backupcss);
$('div').append("<BR>element.style.cssText (2): " + top.backupcss2);
$('div').append("<BR>element.style.cssText (3): " + top.backupcss3);
$("#myimg").css({"width": "10px", "height": "10px"});
$("#myimg2").css({"width": "10px", "height": "10px"});
$("#myimg3").css({"width": "10px", "height": "10px"});
setTimeout(function(){
    document.getElementById('myimg').style.cssText = top.backupcss;
    document.getElementById('myimg2').style.cssText = top.backupcss2;
    document.getElementById('myimg3').style.cssText = top.backupcss3;
},10000);
</script>

The !important bit did not work: If I add !important to the .css() call, it stops working altogether.

Sebastián Grignoli
  • 32,444
  • 17
  • 71
  • 86
just_dont
  • 141
  • 7
  • Ah, I didn't know you use jQuery. The ability to set the `!important` bit is in `setProperty` method of `element.style`, but IEs older than 9 do not support that. However, I'm pretty sure that jQuery supports that way, if not by its `.css` method, then by something else. – just_dont Aug 17 '13 at 07:23