Iva Iva - 6 months ago 12
jQuery Question

Why wrap JavaScript in this "(function($){ ... JavaScript code ..})(jQuery);"?

I use mvc5. Do not include jQuery in test.
_Layout.cshtml:



<!DOCTYPE html>
<html lang="en-US">
<head>
<title></title>
</head>
<body>
@RenderBody()
</body>
</html>





Test.cshtml:



<script type="javascript/text">
function myFunction() {
alert("its is working");
}
</script>
<button onclick="myFunction()">Click me</button>





In result I have an error: ReferenceError: myFunction is not defined

and the result code:

<!DOCTYPE html>
<html lang="en-US">
<head>
<title></title>
</head>
<body>
<button onclick="myFunction();">Click me</button>
<script type='text/javascript' >
(function($){
function myFunction() {
alert("I am working");
};
})(jQuery);
</script>
</body>
</html>


I have read a lot about this error and have not founded the answer. Could you clarify, who wrap JavaScript code? Is there any flag to cancel it? Is there any other way to resolve the problem?

Answer

Something (probably MVC5) is wrapped your code for you, but with good reason. Putting onclick handlers on elements pointing at a globally declared function is how JS was written in the '90s.

To resolve it, put an id attribute on your button and remove the inline event handler:

<button id="mybutton"> 

and then use jQuery to register the event handler:

$('#mybutton').on('click', function () {
  alert("I am working");
});

or, since you mentioned in later comments that you have a loop generating these elements, use a class and a data- attribute instead:

<button class="myclass" data-id="...">

with code:

$('.myclass').on('click', function() {
    var id = $(this).data('id');
    ...
});