0

NOTE: This is a different issue than two different versions of jQuery (what's mentioned here: Can I use multiple versions of jQuery on the same page?). The difference are these are two copies of jQuery of the same version number but with different included libraries loaded by external sources, meaning normal solutions to two different versions of calling with jquery does not work.

I have two different variants of jquery on the same website, loaded by different sources.

One, when running by one path, when I run console.log(jQuery.fn.jquery);:

3.4.1 -ajax,-ajax/jsonp,-ajax/load,-ajax/parseXML,-ajax/script,-ajax/var/location,-ajax/var/nonce,-ajax/var/rquery,-ajax/xhr,-manipulation/_evalUrl,-event/ajax,-effects,-effects/Tween,-effects/animatedSelector

The other path returns

3.4.1

However, both are on the system, path mainly affects load order. The problem is made worse that the former slim version seems to be what is defaulted to when it loads, and is loaded external to my app.

So the question is... one lacks ajax, the other does not, and by one path, ajax versions don't work because jquery thinks there's no such function. How do I tell it to check the other jquery file?

lilHar
  • 1,367
  • 2
  • 15
  • 28
  • Why not just use the non-slim version, if there are cases that you need the non-slim version? – Taplar Dec 11 '19 at 17:56
  • Because the ones loaded externally from my app are overriding anything I'm loading internally. – lilHar Dec 11 '19 at 17:57
  • Then you can try [jQuery noConflict](https://api.jquery.com/jQuery.noConflict/) to revert to a previous version of jQuery, provided the version with ajax was included before the slim version. – Taplar Dec 11 '19 at 17:58
  • If they are both run without no conflict, the second one overrides the first and you are out of luck. – epascarello Dec 11 '19 at 17:59
  • @Taplar So you're saying load a new one internally, do noConflict on that one, and then use the unique calls on that one? The problem with that is it's not a new app, just a new implementation of the app. That'd require re-writing literally decades worth of code. – lilHar Dec 11 '19 at 18:00
  • For more clarity, which one are you importing and which one is the loaded by the app and doing the overriding? – Taplar Dec 11 '19 at 18:00
  • The app is used in multiple places, loaded in by other apps. the slim one ( the one with -ajax) is one larger app that's loading my app, and it's overriding any other version of jquery. The normal version is also loaded by another app in a different context, but I at least have more pull to get that one changed, but that doesn't help me much. – lilHar Dec 11 '19 at 18:02

2 Answers2

1

Going off of the comments...

You could approach this issue with an Immediately Invoked Functional Expression (IIFE) to scope your logic, or with a noConflict call. Lets say you have something like the following.

<script src="locationOfNormalJQuery"></script> <!-- included by you -->
...html...
<script src="locationOfSlimJQuery"></script> <!-- included by app out of your control -->

<script>
  ...your logic...
</script>

"your logic" would only be able to access the jQuery included from the second include because each jQuery include replaces the global window.jQuery and window.$ references. This can be altered in two possible ways.

noConflict

<script src="locationOfNormalJQuery"></script> <!-- included by you -->
<script>
  window.jQueryWithAjax = jQuery.noConflict();
</script>
...html...
<script src="locationOfSlimJQuery"></script> <!-- included by app out of your control -->

<script>
  jQueryWithAjax.find(<whatever>);
</script>

IIFE approach

<script src="locationOfNormalJQuery"></script> <!-- included by you -->
<script>
  (function($){
    $(<whatever>);
  }(jQuery));
</script>
...html...
<script src="locationOfSlimJQuery"></script> <!-- included by app out of your control -->

The noConflict approach saves off the previous version of the jQuery into a secondary variable that can be used later. The IIFE approach moves the logic before the second script include happens, and passes in the current jQuery to it. At that point, all the logic in the IIFE will use the $ as the version that was passed in, regardless of how it may change on the window later.

Taplar
  • 24,246
  • 4
  • 18
  • 33
  • Good answer, and definitely upvoting to encourage awareness of people not suffering my particular use case. Unfortunately for me, load order and adding noConficts are out of my hands. That said, it does give me an idea... – lilHar Dec 11 '19 at 18:13
0

Figured out a possible solution:

Since a later-loaded version of jQuery overrided an earlier version of jQuery, I can use a javascript to do constant checking via jQuery.fn.jquery and inspired by @Taplar's solution and this answer to another question: Listening for variable changes in JavaScript

I add a listener to window.jQuery and window.$

On change, I check the results of jQuery.fn.jquery and if it's different than what I want it to be, I reload jquery with the version I want. (If someone posts the code on how to do this before I figure it out, they'll get the checkmark).

lilHar
  • 1,367
  • 2
  • 15
  • 28