Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forced into window.jQuery #235

Closed
jblandry opened this issue Apr 1, 2014 · 10 comments
Closed

Forced into window.jQuery #235

jblandry opened this issue Apr 1, 2014 · 10 comments

Comments

@jblandry
Copy link

jblandry commented Apr 1, 2014

I was wondering if there was a reason why the jQuery used is always the window.jQuery instead of the 'local' jQuery? Because I sometimes have to use different jQuery versions on a same site and I can't attach jsrender to the local jQuery.

(function($) { ... })(this.jQuery);
instead of
(function($) { ... })(jQuery);

Thanks

@BorisMoore
Copy link
Owner

Can you explain the scenario you have where you load the jsrender.js or jsviews.js and have jQuery !== this.jQuery at file scope? Generally jQuery === this.jQuery and this === window.

@jblandry
Copy link
Author

jblandry commented Apr 1, 2014

For example with certain Drupal plugins, I have to keep the global jQuery version (which Drupal uses) to a fixed outdated version (ex:1.7). So I load another jQuery (more recent ex: 2.1) which I isolate via jQuery.noConflict(true) into a variable. I then do all my custom stuff inside a anonymous function where jQuery is my new version.

// Drupal loads jQuery (window.jQuery = 1.7)
// I load jQuery (window.jQuery = 2.1)

// I isolate my jQuery
var myjq = window.jQuery.noConflict(true); // myjq = 2.1, window.jQuery = 1.7

// then I work my custom stuff with my jQuery
(function(jQuery) {
   // load jsrender here
})(myjq);

I normally don't have any problem with this pattern because plugins usually use jQuery instead of window.jQuery

I hope this is clear.

@BorisMoore
Copy link
Owner

Yes, it is clear. I understand how you obtain references to the different versions of jQuery - and I see the need to load jsrender with your myjq version. Just curious though about how you are loading jsrender within the closure:

(function(jQuery) {
   // load jsrender here
})(myjq);

If you load it as a script file in the browser it will be at global scope - not within your closure. Is this loading on the server? What is the mechanism used to load jsrender.js? Is there some kind of module composition mechanism which allows jsrender.js code to be somehow inserted - concatenated between (function(jQuery) { and })(myjq); ?:

@jblandry
Copy link
Author

jblandry commented Apr 3, 2014

It is inserted via a build workflow with Grunt, so every file I use is concatenated into one file. :)

@BorisMoore
Copy link
Owner

So of course you can work around the issue by writing

(function(jQuery) {
  var outerjQuery = window.jQuery;
  window.jQuery = jQuery;   
  // load jsrender here
  window.jQuery = outerjQuery;
})(myjq);

But I could change jsrender to pass in jQuery rather than this.jQuery. I'm ready to make that change, but my one concern is whether that might break other users' scenarios., In particular will NodeJS users have a problem since currently this.jQuery is equivalent to global.jQuery for them. In Node, will the local jQuery default to this.jQuery.
@coolbloke1324 (Rob Evans): Rob - do you have a view on this one?

@Irrelon
Copy link

Irrelon commented Apr 5, 2014

Hey ya, that won't affect the node version AFAIK. Certainly can work around it if something pops up so gets my vote. Thanks for asking :)

@jblandry
Copy link
Author

jblandry commented Apr 6, 2014

👍

@BorisMoore
Copy link
Owner

@jblandry; @coolbloke1324:
Unfortunately there is an issue. JsRender can be used without jQuery. Passing in (function($) { ... })(jQuery); if jQuery is not defined causes most browsers (IE, Safari and Firefox) to throw ("'jQuery' is undefined"), whereas passing in (function($) { ... })(this.jQuery); treats this.jQuery as undefined without throwing.

There is a fix - to write:

try {
    jQuery = jQuery;
} catch(e) {
    jQuery = undefined;
}  
(function($) { ... })(jQuery);

but I am a bit reluctant to add that code. The alternative is for folks who are concatenating files to write a wrapper:

(function(jQuery) {
  var outerjQuery = window.jQuery;
  window.jQuery = jQuery;   
  // load jsrender here
  window.jQuery = outerjQuery;
})(myjq);

So for the next update (53) at least, I will not make the change stay with (function($) { ... })(this.jQuery);...

Comments?

@jblandry
Copy link
Author

jblandry commented May 8, 2014

Not a problem I'll change my inclusion. Thanks

@BorisMoore
Copy link
Owner

OK, sounds good - I'll close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants