I'm making angular web component to improve another component built on JEE application, but it broke with Jquery.
I have made a minimal test to reproduce the error.
<html>
<head>
<script src="./jquery.min.js"></script>
<script src="./main.js"></script>
</head>
<body>
<app-test></app-test>
<button id="testBtn">Click</button>
<script>
$("#testBtn").click(function () {
alert("jQuery fonctionne !");
});
</script>
</body>
</html>
If i comment script mains.js
, jquery work and if i comment
<script>
$("#testBtn").click(function () {
alert("jQuery fonctionne !");
});
</script>
my angular component works, but when the two are loaded together, it throws an error: main.js:4 ERROR TypeError: $ is not a function
I don't know how solve this. I have made a stackblitz minimal reproduction.
the problem is conflict in global scope ($
variable is used by angular, hence the error, using jQuery('#testBtn')...
or another alias would work), which means that it's leaking into global namespace.
Angular shouldn't leak, so you need to load angular code as a module by adding type="module"
to script tag to prevent leakage to global scope:
<script src="./main.js" type="module"></script>
Module-defined variables are scoped to the module unless explicitly attached to the global object. On the other hand, globally-defined variables are available within the module
As a side note, jQuery allows avoiding global namespace conflict with jQuery.noConflict()
jQuery.noConflict();
(function ($) {
$('#testBtn').click(function () {
alert('jQuery fonctionne !');
});
})(jQuery);
Many JavaScript libraries use
$
as a function or variable name, just as jQuery does. In jQuery's case,$
is just an alias forjQuery
, so all functionality is available without using$
. If you need to use another JavaScript library alongside jQuery, return control of$
back to the other library with a call to$.noConflict()
. Old references of$
are saved during jQuery initialization;noConflict()
simply restores them.