Laurence
Laurence

Reputation: 60038

$ is undefined but loading jQuery twice fixes it

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??

Upvotes: 0

Views: 723

Answers (3)

jfriend00
jfriend00

Reputation: 707218

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>

Upvotes: 1

Jivings
Jivings

Reputation: 23250

preloader.js should be in a ready block.

(function($) {
    $.fn.preloader = function(options) {
        // your code here.
    }
})(jQuery);

Upvotes: 2

Amadan
Amadan

Reputation: 198324

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.

Upvotes: 2

Related Questions