0

I have a jQuery preloader that is loaded in my html file:

<script type="text/javascript">
        jQuery.noConflict()(function($){
            $(".view").preloader();
            $(".flexslider").preloader();
            });
</script>

My jquery.preloader.js

// JavaScript Document
$.fn.preloader = function(options){

    var defaults = {
                     delay:200,
                     preload_parent:"a",
                     check_timer:300,
                     ondone:function(){ },
                     oneachload:function(image){  },
                     fadein:500 
                    };

    // variables declaration and precaching images and parent container
     var options = $.extend(defaults, options),
     root = $(this) , images = root.find("img").css({"visibility":"hidden",opacity:0}) ,  timer ,  counter = 0, i=0 , checkFlag = [] , delaySum = options.delay ,

     init = function(){

        timer = setInterval(function(){

            if(counter>=checkFlag.length)
            {
            clearInterval(timer);
            options.ondone();
            return;
            }

            for(i=0;i<images.length;i++)
            {
                if(images[i].complete==true)
                {
                    if(checkFlag[i]==false)
                    {
                        checkFlag[i] = true;
                        options.oneachload(images[i]);
                        counter++;

                        delaySum = delaySum + options.delay;
                    }

                    $(images[i]).css("visibility","visible").delay(delaySum).animate({opacity:1},options.fadein,
                    function(){ $(this).parent().removeClass("preloader");   });




                }
            }

            },options.check_timer) 


         } ;

    images.each(function(){

        if($(this).parent(options.preload_parent).length==0)
        $(this).wrap("<a class='preloader' />");
        else
        $(this).parent().addClass("preloader");

        checkFlag[i++] = false;


        }); 
    images = $.makeArray(images); 


    var icon = jQuery("<img />",{

        id : 'loadingicon' ,
        src : '/assets/images/front/spinner.gif'

        }).hide().appendTo("body");



    timer = setInterval(function(){

        if(icon[0].complete==true)
        {
            clearInterval(timer);
            init();
             icon.remove();
            return;
        }

        },100);

    }

But when I run this, I get a "$ is undefined" and points to this line:

var options = $.extend(defaults, options),

But here's the weird thing - if I load jQuery 1.7.2 TWICE in my html file - the error goes away, and everything works as expected (including the preloader).

Question: how do I fix this, so I dont need to load jQuery twice to make this work??

1
  • Are you sure you are loading jQuery before you load the other scripts? Commented May 26, 2012 at 14:39

3 Answers 3

2

preloader.js should be in a ready block.

(function($) {
    $.fn.preloader = function(options) {
        // your code here.
    }
})(jQuery);
Sign up to request clarification or add additional context in comments.

2 Comments

sorry - which bit exactly? I'm a bit confused?
@Laurencei I've edited the answer slightly to help you identify which code goes inside there
2

You're executing the noConflict instruction, which makes jQuery rebind $ to its original value (normally undefined). Remove .noConflict(). Alternately, rewrite $.extend into jQuery.extend (outside the no-conflict mode, $ is just a shorthand synonym for jQuery), $(this) into jQuery(this), etc.

2 Comments

if I change "jQuery.noConflict()(function($)" to "jQuery.(function($)" I get a new error: XML filter is applied to non-XML value (function (a, b) {return new e.fn.init(a, b, h);}) ?
You haven't posted the whole error message so I really don't know what it refers to, but the line should be jQuery(function() {...}) or equivalently $(function() {...}) (without the dot). Since you don't engage the no-conflict mode, you can also see that it is also not necessary to receive $ as an argument to the callback.
1

You have several issues:

  1. You have to wait for the DOM to be ready before referencing elements in it. If the code you provided is not at the end of the body tag, then you need to put your code in a document.ready block.

  2. When you use jQuery.noConflict(), you can no longer use $ to reference jQuery. You must instead use the symbol jQuery.

  3. If you want to use $ again, you can pass in jQuery to a self executing function block that will assign jQuery to the $ symbol inside the function block which will allow you to use it there, but not interfere with any other code.

This is what I would suggest:

<script type="text/javascript">
    jQuery.noConflict();
    (function($){
        // you can now use $ here as a reference to jQuery 
        // again inside this function
        $(document).ready(function() {
            $(".view").preloader();
            $(".flexslider").preloader();
        });
    })(jQuery);
</script>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.