Using jquery.bgpos.js with jQuery 1.8

Today, I spent way too much time working on a front-end problem to a code base that I wasn’t very familiar with.  This project’s animated navigation menu stopped working when upgrading from jQuery 1.7 to jQuery 1.8, and we needed jQuery 1.8 because of another dependency.  After digging my way through the code, I finally found that the problem was occurring because Alexander Farkas’ jquery.bgpos.js jQuery plugin was not compatible with jQuery 1.8.

Since the internals of jQuery’s animation code has changed from 1.7 to 1.8, the plugin needed to be updated as well.  I’m pasting the entirety of the change here so that, hopefully, maybe, someone else doesn’t go through the same frustration that I went through today.  I’ve made the necessary changes bold and italic in the following code block.  I can’t guarantee this code would work with jQuery versions less than 1.8 ;)

/**
 * @author Alexander Farkas
 * v. 1.02
 *
 * Edited by Nelson Wells for jQuery 1.8 compatibility
 */
(function($) {
    $.extend($.fx.step,{
        backgroundPosition: function(fx) {
            if (fx.pos === 0 && typeof fx.end == 'string') {
                var start = $.css(fx.elem,'backgroundPosition');
                start = toArray(start);
                fx.start = [start[0],start[2]];
                var end = toArray(fx.end);
                fx.end = [end[0],end[2]];
                fx.unit = [end[1],end[3]];
            }
            var nowPosX = [];
            nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
            nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
            fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];
 
           function toArray(strg){
               strg = strg.replace(/left|top/g,'0px');
               strg = strg.replace(/right|bottom/g,'100%');
               strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
               var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
               return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
           }
        }
    });
})(jQuery);
Leave a comment ?

20 Comments.

  1. Hi, I detected the same problem, but with my own code. :-)

    fx.pos works on my project, also with jquery versions less than 1.8 because this property already exist (f.e. in version 1.7.1)

    :-)

  2. Why not use JQueryUI for animations?

  3. Honestly, that’s a good question ;). JQueryUI claims that it adds the ability to animate background-position on elements, but at the time we couldn’t get it it to work. Someone else on my team had added bgpos to our project since that seemed to be the answer, but it was failing as well. I took a look after that and found this fix for bgpos so that’s what we went with.

    In an upcoming refactor, I would like to take a look at JQueryUI’s background-position animation stuff and see if I can replace bgpos altogether.

    For those that don’t want the dependency of JQueryUI, though, this is a good solution.

  4. Nelson: your solution saved me countless hours. I was about to put my debugging hat on, but instead all I had to do was copy/paste your updated function over Farkas’ 1.02 code. Thank you!!

  5. Really appreciate the share Nelson, that saved me precious time ! thank you

  6. Jquery background-position sorunu | Sofistler - pingback on October 23, 2012 at 4:42 pm
  7. Hi Nelson,

    Thank you so much for sharing.

    Regards,
    Kendalf

  8. :razz: I’m a hardcore webzer my whole life. I’ve read thousands of blogs and tutorials. I never comment, but for you. I must say, thank you very much. You saved me a lot of time with one search and one click. :)

  9. Thank’s man!
    Work perfect for me :)

  10. Thanks bro..
    I went to the same frustation as well, until i found your article.

  11. Thank you very much!

  12. Wow, Nelson, you’ve saved me. I’ve got some smooth menu working based on that script and jQuery 1.2.6. I love that menu and also I want to use jquery UI widgets on my site with that menu. You solved my problem.
    Thank you very much! Everything works perfectly.

  13. Excellent – i was mucking around with hosting two versions of jQuery on the page, which compatibility issues. Thanks.

  14. Thanks a lot for sharing… saved me al lot of trouble!

  15. So Many Thanks for this issue. I was looking for a solution since 3 days.
    My boss is happy now :mrgreen:

  16. Thanks for this post.. I was working with this script with the Touchsense theme (with the dmslider). When updating the jQuery version it suddenly stopped working.. but then I found out it was the jquery.backgroundposition.js that gave me problems.

    Updated my version with the version of Nelson and now everything works, I am running the latest jquery AND the slider still works!

    Great work !

    Ps: one thing wonders me.. the versie I had was version 1.2.2. and your version is v. 1.02 .. how come an older version works great and the newest doesn’t..

  17. including a fix for ie7/8:

    /**
    * @author Alexander Farkas
    * v. 1.02
    *
    * Edited by Nelson Wells for jQuery 1.8 compatibility
    */
    (function($) {
    $.extend($.fx.step,{
    backgroundPosition: function(fx) {
    if (fx.pos === 0 && typeof fx.end == 'string') {

    var start = $.css(fx.elem,'backgroundPosition');
    if(undefined === start){
    start = $.css(fx.elem,'backgroundPositionX')+' '+$.css(fx.elem,'backgroundPositionY');
    }
    start = toArray(start);
    fx.start = [start[0],start[2]];
    var end = toArray(fx.end);
    fx.end = [end[0],end[2]];
    fx.unit = [end[1],end[3]];
    }
    var nowPosX = [];
    nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
    nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
    fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];

    function toArray(strg){
    strg = strg.replace(/left|top/g,'0px');
    strg = strg.replace(/right|bottom/g,'100%');
    strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
    var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
    return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
    }
    }
    });
    })(jQuery);

  18. Thanks WishedBy, I included your change in my Github repository. In the future, if you want to contribute you can fork and afterward put in a pull request :)

    https://github.com/nelsonwellswku/jquery.bgpos

  19. NELSON!!!! can’t thank you enough. The last developer here used bgpos and of course it wasn’t working on our newer site. this did the trick..on jquery 1.10.1 BTW

  20. Thank you Nelson!

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackbacks and Pingbacks: