jquery - is not a function error

Here is my code:

(function($){
    $.fn.pluginbutton = function (options) {
        myoptions = $.extend({ left: true });
        return this.each(function () {
            var focus = false;
            if (focus === false) {
                this.hover(function () {
                    this.animate({ backgroundPosition: "0 -30px" }, { duration: 0 });
                    this.removeClass('VBfocus').addClass('VBHover');
                }, function () {
                    this.animate({ backgroundPosition: "0 0" }, { duration: 0 });
                    this.removeClass('VBfocus').removeClass('VBHover');
                });
            }
            this.mousedown(function () {
                focus = true
                this.animate({ backgroundPosition: "0 30px" }, { duration: 0 });
                this.addClass('VBfocus').removeClass('VBHover');
            }, function () {
                focus = false;
                this.animate({ backgroundPosition: "0 0" }, { duration: 0 });
                this.removeClass('VBfocus').addClass('VBHover');
            });
        });
    }
});


$(document).ready(function () {
    $('.smallTabsHeader a').pluginbutton();
});

It gives me an error. What's wrong?


Solution 1:

This problem is "best" solved by using an anonymous function to pass-in the jQuery object thusly:

The Anonymous Function Looks Like:

<script type="text/javascript">
    (function($) {
        // You pass-in jQuery and then alias it with the $-sign
        // So your internal code doesn't change
    })(jQuery);
</script>

This is JavaScript's method of implementing (poor man's) 'Dependency Injection' when used alongside things like the 'Module Pattern'.

So Your Code Would Look Like:
Of course, you might want to make some changes to your internal code now, but you get the idea.

<script type="text/javascript">
    (function($) {
        $.fn.pluginbutton = function(options) {
            myoptions = $.extend({ left: true });
            return this.each(function() {
                var focus = false;
                if (focus === false) {
                    this.hover(function() {
                        this.animate({ backgroundPosition: "0 -30px" }, { duration: 0 });
                        this.removeClass('VBfocus').addClass('VBHover');
                    }, function() {
                        this.animate({ backgroundPosition: "0 0" }, { duration: 0 });
                        this.removeClass('VBfocus').removeClass('VBHover');
                    });
                }
                this.mousedown(function() {
                    focus = true
                    this.animate({ backgroundPosition: "0 30px" }, { duration: 0 });
                    this.addClass('VBfocus').removeClass('VBHover');
                }, function() {
                    focus = false;
                    this.animate({ backgroundPosition: "0 0" }, { duration: 0 });
                    this.removeClass('VBfocus').addClass('VBHover');
                });
            });
        }
    })(jQuery);
</script>

Solution 2:

The problem arises when a different system grabs the $ variable. You have multiple $ variables being used as objects from multiple libraries, resulting in the error.

To solve it, use jQuery.noConflict just before your (function($){:

jQuery.noConflict();
(function($){
$.fn.pluginbutton = function (options) {
...

Solution 3:

change

});


$(document).ready(function () {
    $('.smallTabsHeader a').pluginbutton();
});

to

})(jQuery); //<-- ADD THIS


$(document).ready(function () {
    $('.smallTabsHeader a').pluginbutton();
});

This is needed because, you need to call the anonymous function that you created with

(function($){

and notice that it expects an argument that it will use internally as $, so you need to pass a reference to the jQuery object.

Additionally, you will need to change all the this. to $(this)., except the first one, in which you do return this.each

In the first one (where you do not need the $()) it is because in the plugin body, this holds a reference to the jQuery object matching your selector, but anywhere deeper than that, this refers to the specific DOM element, so you need to wrap it in $().

Full code at http://jsfiddle.net/gaby/NXESk/

Solution 4:

It works on my case:

import * as JQuery from "jquery";
const $ = JQuery.default;

Solution 5:

When converting an ASP.Net webform prototype to a MVC site I got these errors:

TypeError: $(...).accordion is not a function
$("#accordion").accordion(


$('#dialog').dialog({
TypeError: $(...).dialog is not a function

It worked fine in the webforms. The problem/solution was this line in the _Layout.cshtml

@Scripts.Render("~/bundles/jquery")

Comment it out to see if the errors go away. Then fix it in the BundlesConfig:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));