Side navigation
#13458 closed bug (notabug)
Opened February 15, 2013 09:35AM UTC
Closed February 15, 2013 03:05PM UTC
Last modified February 15, 2013 03:42PM UTC
jQuery conflict
Reported by: | guybazelet | Owned by: | guybazelet |
---|---|---|---|
Priority: | undecided | Milestone: | None |
Component: | unfiled | Version: | 1.9.1 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
Problem was detected in jQuery 1.8.2, but was recreated in 1.9.1 as well.
2 jQuery versions are loaded to the same website one synchronously and one asynchronously (widget). The asynchronous is not called even once but just loaded.
When the site loads it attaches objects to DOM elements using .data() of the synchronous jQuery.
Sometimes that data is deleted because of the asynchronous jQuery.
Note that the asynchronous is not called even once, but merely loaded. Problem happens even when after load it is called with noConflict(true), since the deletion has already occurred.
In my setup it happens once every 5-10 times.
If I look at $.cache and myjquery.cache I see that when the problem occurs (data deleted) the $.cache is much smaller than when page loads ok.
When I manually change the asynchronous jQuery such that it does not use $ at all - the problem doesn't happen.
I suspect that during the time until the global scope is restored the caches get mixed and the asynchronous jQuery overwrites the original cache (maybe by setting cache: {} )
Attachments (0)
Change History (14)
Changed February 15, 2013 12:40PM UTC by comment:1
resolution: | → notabug |
---|---|
status: | new → closed |
Changed February 15, 2013 01:07PM UTC by comment:2
Like I mentioned above it happens when the jQuery library is loaded to browser memory, before there is a chance to call jQuery.noConflict (which I tried calling immediately, but with no affect). Closure not relevant here since happens without any call to asynchronous jQuery). The init of jQuery is called when the library is loaded to memory and at that stage the cache of the other jQuery gets messed up sometimes (depending on timing issues of the load time of the two instances)
Changed February 15, 2013 01:14PM UTC by comment:3
resolution: | notabug |
---|---|
status: | closed → reopened |
This really sounds like a bug in your code, not jQuery. Unless you can provide a reduced test case showing the problem, there's nothing we can do.
Changed February 15, 2013 01:15PM UTC by comment:4
Changed February 15, 2013 01:19PM UTC by comment:5
status: | pending → new |
---|
It can't be recreated in jsFiddle since it relates to timing issues. I will try to recreate in a public available URL and update
Changed February 15, 2013 01:27PM UTC by comment:6
status: | new → pending |
---|
I'm not sure how jsFiddle solves your timing issues, but we'll take what we can get.
Changed February 15, 2013 02:31PM UTC by comment:7
status: | pending → new |
---|
URL for 'good' version: http://xyanalytics.com/www/test_jquery_good/
URL for 'bad' version: http://xyanalytics.com/www/test_jquery_bad/
'good' version loads jQuery 1.9.1 and uses .data to attach data to 'test_div'. Click on 'test' to see the data content.
'bad' version is exactly as 'good' version but loads asynchronously jQuery 1.8.2.
In 'bad' version the data is deleted by jQuery 1.8.2.
I think it will be recreated will any jQuery version - not specific those two.
You might need to reload the page several times to see the problem.
I think it is related to Sizzle which is defined in the window namespace.
Please update if you could recreate the problem.
Changed February 15, 2013 02:43PM UTC by comment:8
status: | new → pending |
---|
I don't see any use of jQuery.noConflict()
in those pages. Can you add one at the top for the version loaded via the script tag?
Also you need to be clear on which version you were expecting $
to be in the init function. As it currently is without .noConfict()
the definition will change as soon as the dynamic version is loaded. Something like that could certainly create the behavior you're seeing, but it's a result of not using .noConflict()
Changed February 15, 2013 02:57PM UTC by comment:9
status: | pending → new |
---|
Adding noConflict to the 1st jQuery does fix it but in my real scenario I don't have control over the static jQuery as it is loaded by the website.
I can control only the 2nd jQuery which I load asynchronously from my widget. Adding noConflict on the 2nd jQuery doesn't help.
Is this expected behavior?
Changed February 15, 2013 03:05PM UTC by comment:10
resolution: | → notabug |
---|---|
status: | new → closed |
Yes. By the time your second script loads it has already clobbered the first one. That's not a scenario we can support.
Changed February 15, 2013 03:11PM UTC by comment:11
In any case since the 2 jQuery libaries are loaded with separate timing it can always happen that until the noConflict is processed, the other jQuery (which was not intended) is actually called.
The noConflict() is intended to affect direct calls to the library (using $ or jQuery). The library's internal memory should not be affected and be deleted just by loading another instance. Looks like something there is not robust enough. Does it make sense what I am saying?
Changed February 15, 2013 03:28PM UTC by comment:12
I see what you're saying, you'd like to be able to load two copies of jQuery in non-cooperative situations. It's not designed for that. You could call .noConflict()
on the first instance before loading the second, but that would seem to create a window where the original page would have *no available jQuery. In any case, if you want to work this out please take the discussion to a forum or StackOverflow since it's not a bug.
Changed February 15, 2013 03:35PM UTC by comment:13
OK. It should at least be documented as a known limitation, since currently jQuery's documentation says multiple versions are supported by using noConflict (which is true to some extent). No mentioning of memory being overwritten just by loading another instance.
Thanks anyway for the quick feedback.
Changed February 15, 2013 03:42PM UTC by comment:14
The library's internal memory should not be affected and be deleted just by loading another instance.
This never happens. In your test case, you're using the newly loaded jQuery's data.
I see what you're saying, you'd like to be able to load two copies of jQuery in non-cooperative situations. It's not designed for that.
It is :-) jQuery.noConflict()
can be used before or after loading the second version of jQuery with proper results.
Here's the provided test case with a proper noConflict call (see the script
element generation section): http://jsfiddle.net/X2679/
Here's the provided test case using a stored jQuery instance to avoid the conflict (see the click
event handling section): http://jsfiddle.net/X2679/1/
There are other ways to handle this as well, like the normal wrap-all-code-in-a-closure solution.
You need to use jQuery.noConflict() or write your code using closures to always use the correct version of jQuery. Please ask for help on the forums or Stack Overflow.