Bug Tracker

Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#13458 closed bug (notabug)

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: {} )

Change History (14)

comment:1 Changed 7 years ago by scottgonzalez

Resolution: notabug
Status: newclosed

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.

comment:2 Changed 7 years ago by guybazelet

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)

comment:3 Changed 7 years ago by scottgonzalez

Resolution: notabug
Status: closedreopened

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.

comment:4 Changed 7 years ago by scottgonzalez

Owner: set to guybazelet
Status: reopenedpending

We'll wait for the reduced test case. You can use jsbin or jsFiddle to create one.

comment:5 Changed 7 years ago by guybazelet

Status: pendingnew

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

comment:6 Changed 7 years ago by scottgonzalez

Status: newpending

I'm not sure how jsFiddle solves your timing issues, but we'll take what we can get.

comment:7 Changed 7 years ago by guybazelet

Status: pendingnew

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.

comment:8 Changed 7 years ago by dmethvin

Status: newpending

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()

comment:9 Changed 7 years ago by guybazelet

Status: pendingnew

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?

comment:10 Changed 7 years ago by dmethvin

Resolution: notabug
Status: newclosed

Yes. By the time your second script loads it has already clobbered the first one. That's not a scenario we can support.

comment:11 Changed 7 years ago by guybazelet

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?

comment:12 Changed 7 years ago by dmethvin

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.

comment:13 Changed 7 years ago by guybazelet

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.

comment:14 Changed 7 years ago by scottgonzalez

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.

Note: See TracTickets for help on using tickets.