Fix for background-position in IE
Asked Answered
S

11

13

I get this problem in IE7 when running a piece of code that uses jquery and 2 jquery plugins. The code works in FF3 and Chrome.

The full error is:

Line: 33 
Char: 6 
Error: bg is null or not an object 
Code: 0 
URL: http://localhost/index2.html

However line 33 is a blank line.

I am using 2 plugins: draggable and zoom. No matter what I do to the code it is always line 33 that is at fault. I check the source has update via view source but I feel this could be lying to me.

<body>
<div id="zoom" class="zoom"></div>
<div id="draggable" class="main_internal"><img src="tiles/mapSpain-smaller.jpg" alt=""></div>

<script type="text/javascript">
$(document).ready(function() {
    $('#draggable').drag();
    $('#zoom').zoom({target_div:"draggable", zoom_images:new Array('tiles/mapSpain-smaller.jpg', 'tiles/mapSpain.jpg') });
});
</script>

</body>

Essentially what I am trying to do is recreate the Pragmatic Ajax map demo with jQuery.


It would appear that the second line of this snippet is causing the trouble:

bg = $(this).css('background-position');                    
if(bg.indexOf('%')>1){

It seems to be trying to select the background-position property of #draggable and not finding it? Manually adding a background-position: 0 0; didn't fix it. Any ideas on how to get around this problem?

I tried using the MS Script Debugger but that is nearly useless. Can't inspect variables or anything else.

Satchel answered 27/2, 2009 at 14:1 Comment(2)
You can get a CSS hook plugin for this - github.com/brandonaaron/jquery-cssHooksPublishing
Unfortunately when I needed that it wasn't available but could be useful for those coming past this way in the future.Satchel
S
34

A bit more digging about on the Interweb has revealed the answer: IE doesn't understand the selector background-position. It understands the non-standard background-position-x and background-position-y.

Currently hacking something together to workaround it.

Nice one, Redmond.

Satchel answered 27/2, 2009 at 16:51 Comment(5)
Good catch. In general the ‘shortcut’ aggregated CSS properties like ‘background’ don't work using element.currentStyle (which is how jQuery calculates current styles on IE). ‘background-position’ shouldn't be a shortcut property in general, but IE's separate X/Y extension effectively makes it one.Studley
I'm not really sure what the code's actually trying to do though — it would match the string ‘0% 0%’ but not ‘1% 100px’ or many other possible values. Looks like dodgy, fragile code to me...Studley
Okay. I will modify it so it is more robust. I've installed IE8 so I can debug easier.Satchel
It's worth noting that Firefox (at least up the 3.5) doesn't support background-position-x/y. So it a rock-and-a-headache kinda placeHomeomorphism
It is also worth nothing that IE doesn't seem to support retrieving percentage value. For some reason, the value retrieved is always in pixel.Involuntary
B
4

To get around the fact that Internet Explorer does not support the "background-position" CSS attribute, as of jQuery 1.4.3+ you can use the .cssHooks object to normalize this attribute between browsers.

To save yourself some time, there is a background position jQuery plugin available that allows both "background-position" and "background-position-x/y" to work as expected in browsers that don't support one or the other by default.

Buroker answered 17/2, 2011 at 7:12 Comment(0)
E
4

It is interesting. IE8 doesn't understand getter backgroundPosition, but it understands setter.

$('.promo3').mousewheel(function(e,d){
  var promo3 = $(this);
  var p = promo3.css('backgroundPosition');
  if (p === undefined) {
    p = promo3.css('backgroundPositionX') + ' ' + promo3.css('backgroundPositionY');
  }
  var a = p.split(' ');
  var y = parseInt(a[1]);
  if (d > 0) {
    if (y < -1107) y += 1107; 
    y -= 40;
  }
  else {
    if (y > 1107) y -= 1107;
    y += 40;
  }
  promo3.css('backgroundPosition', a[0] + ' ' + y + 'px');
  return false;
});

It works great in IE8 and IE8 compatible view.

Edea answered 23/10, 2011 at 1:44 Comment(0)
N
3

This worked for me:

    if (navigator.appName=='Microsoft Internet Explorer')
   {
    bg = $(drag_div).css('backgroundPositionX') + " " + $(drag_div).css('backgroundPositionY');
   }
   else
   {
    bg = $(drag_div).css('background-position');
   }

hope it does for you.

Nosy answered 25/2, 2010 at 1:5 Comment(1)
In the end the lack of MSIE compliance and converting SVG to JPEG in PHP forced me away from the background image trick and I now use Raphael and jQuery. The bonus is that it works in IE6 too!Satchel
P
2

You may want to check to make sure that you are loading your js files in the correct order so that any dependencies are taken into account.

Pickerel answered 27/2, 2009 at 14:5 Comment(2)
jquery followed by draggable and then zoom.Satchel
Debugging is such a hassle in IE. Try isolating it by only loading one of the two js files (of draggable and zoom). You may need to do some alerting to really isolate it :(Pickerel
S
2

A bit of thinking (and a cup of tea) later I came up with:

if(bg == 'undefined' || bg == null){
    bg = $(this).css('background-position-x') + " " + $(this).css('background-position-y');
}

Unfortunately it returns center center despite the online resources I can find state it should return 0 0 if the values are undefined.

Beginning to wonder if there is an actual fix/workaround to this. A lot of people have tried and all so far fail to catch all edge cases.

The camelCase version of backgroundPosition seems viable but I don't know enough of jQuery to make an accurate assessment of how to go about it - from what I have read you can only use camelCase as getters if the property has been set previously. Please tell me if I am mistaken.

Satchel answered 27/2, 2009 at 23:45 Comment(0)
S
1

However line 33 is a blank line.

It'll be line 33 of one of your .js files, not line 33 of the HTML itself. IE fails to report which actual file the error was in. Look at line 33 of each .js for something about ‘bg’; if the worst comes to the worst you can start inserting newlines at the start of each .js and see whether the line number changes.

I check the source has update via view source but I feel this could be lying to me.

View source will always show you what IE got from the server. It won't show any updates to the DOM.

Studley answered 27/2, 2009 at 14:48 Comment(3)
bg is referenced in draggable.js but it isn't on line 33. It is on 34,35,39,40, and 41. I guess I will start looking there. Pity IE doesn't have a FireBug plugin:-(Satchel
It'll be 34 then — IE's method of counting line numbers is generally off-by-one compared to text editors. There are JS debuggers for IE, for example you get one with the IE8 beta.Studley
I've found the line numbers referenced by IE are utterly useless. I've never seen it anywhere close to where the problem is in the code.Putrescine
R
0

try backgroundPosition istead

Also, make sure that 'this' exists and that your request for an attribute returns a value. IE will throw this kind of errors when you try to call a method on a property that does not exist, therefore bg is null or null an object. if you dont care about IE you can do bg = $(this)... || '' so that theres always something referenced.

Also, unrelated to the error you're getting, but is your index value of 1 correct? Did you mean -1 ?

Remaremain answered 27/2, 2009 at 22:6 Comment(1)
The smallest value you can have is 0% - so the smallest index of the percentage symbol will be 1. Bobince has pointed out that that code is fragile, and reading around the web means I will have to rewrite it. Personally I thought jQuery was supposed to normalise this across browsers?!Satchel
G
0

You can't use dashes in the jquery css function. You have to do it in camelCase: .css('backgroundPosition') or .css('backgroundPositionX') and .css('backgroundPositionY') for IE

Gravimetric answered 6/2, 2011 at 22:44 Comment(1)
Yes you can. Both .css('background-color', '#000') and .css({ backgroundColor : '#00f' }) will work; but note that the camel case example needs to be inside an object {}... see this demo: jsfiddle.net/Mottie/guMdvPhyliciaphylis
V
0

Yupp,
Try background-position instead or just set the background-position with jquery before you call it. Ill guess one often knows the positions through CSS before calling it. It isnt pretty, but somehow it did the trick for me.)

eg:

//set it in with javascript.
$("someid").css("background-position", "10px 0");
...
//do some funky stuff
//call it
$("someid").css("background-position");
//and it would return "10px 0" even in IE7
Vidovik answered 24/4, 2013 at 9:54 Comment(0)
U
0

if nothing helps, it's also possible to make the following trick.

We can replace a background of an element by an inner absolutely positioned element (with the same background). The coordinates will be replaced by left and top properties. This will work in all browsers.

For better understanding, please, check the code:

Before

<div></div>

div {
  background: url(mySprite.png);
  background-position: -100px 0;
}

After

<div>
  <span></span>
</div>

div {
  position: relative;
  overflow: hidden;
  width: 100px;       /* required width to show a part of your sprite */
  height: 100px;      /* required height ... */
}

div span {
  position: absolute;
  left: -100px;       /* bg left position */
  top: 0;             /* bg top position */
  display: block;
  width: 500px;       /* full sprite width */
  height: 500px;      /* full sprite height */
  background: url(mySprite.png);
}

This solution is not very flexible, but it helped me to show icons hover state properly.

Unamuno answered 6/7, 2013 at 10:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.