kiltjs / jqlite

Tiny JavaScript DOM query library that uses pure CSS selectors
MIT License
99 stars 19 forks source link

How to avoid collision with Jquery #32

Closed Fire-Brand closed 8 years ago

Fire-Brand commented 9 years ago

I wrote a component with jqLite and now when others try to implement it in a webapp that uses JQuery a lot of things work differently or don't work at all.

Any idea how i can avoid it in my code? and if that's not possible then in their code?

Fire-Brand commented 9 years ago

And also, one app has both JQuery and a bit of Angular

Fire-Brand commented 9 years ago

it seems that the main effect is on event handlers mostly on a MediaAPI 'timeupdate' event

jgermade commented 9 years ago

Hi @Fire-Brand, could you send me a small code snippet to reproduce it?

Fire-Brand commented 9 years ago

That's a bit tricky, since the component works well on my webapp and don't on their's, i'm not sure what to send...

In my honest opinion it has got to be something that's related to JQuery.

jgermade commented 9 years ago

Maybe the issue happens when minifying the code?

Fire-Brand commented 9 years ago

I've used jqlite minified from the get go, and they use my files as a CDN- unminified

Fire-Brand commented 9 years ago

I'm guessing i need to some how use jQuery.noConflict(); so that they won't have to change anything.

What do you think is the right way? and ofcurse should my file be above or below the jquery.js script tag?

Fire-Brand commented 9 years ago

Using

if (window.jQuery) {
  jQuery.noConflict();
}

At the very top of my code did the trick, thanks for the help!

jgermade commented 9 years ago

awesome!! thanks for the info!!

Fire-Brand commented 9 years ago

Hi @jgermade, so i came across another option... Basically in-order for the solution i wrote above to work, jQuery needs to be called before my component's script file (which uses jqlite) otherwise some animation conflicts still occur (e.g. a button with an image from a sprite background that changes the background-position when it's clicked will change the image with a slide-left animation instead of simply changing quickly).

is there a possibility to change my code to use $j and not $ just like doing :

var $j = jQuery.noConflict();

???

Please assist

Fire-Brand commented 9 years ago

Maybe create a noConflict() for jqlite?

jgermade commented 9 years ago

Hi @Fire-Brand,

jqlite does not override '$' object if present, so if jquery is placed before jqlite object $ will correspond to jquery.

anyway, I'm going to include such function .noConflict() that's a good idea

sorry for the delay, and thanks for the feedback!!

Fire-Brand commented 9 years ago

Hi @jgermade,

so maybe i just had some difficulties with the show() and hide() functions, because with jquery the animation was like a slide-left animation, you think it has anything to do with that?

jgermade commented 9 years ago

jqlite .hide() and .show() only add/remove 'display: none' value in style

IMO jQuery had included animations (based in js) when css3 didn't exist. but now css3 animations (uses hardware acceleration) are really better in performance than js

by this reason and in order to keep a smaller file, animations are intended to be implemented with css3 by adding/removing classes

maybe it can be interesting develop a library to provide animations based on dinamic css3 this library can be compatible with jqlite and jQuery (like jq-plugin)

Fire-Brand commented 9 years ago

That's sound cool.

In regards to the new noConflict() method, is it now possible to change the $ on jqlite to somthing else to avoid conflicts with jQuery when someone adds my code to theirs? like $jq ? and how should i best implement it?

jgermade commented 8 years ago

Hi @Fire-Brand

in the last version of jqlite (v0.0.27), .noConflict() has being simplified, the way of use is like jQuery.noConflict()

<script src="other_lib.js"></script>
<script src="jqlite.js"></script>
<script>
// .noConflict() returns a pointer to the global jqlite object
$jq = $.noConflict();
</script>

jqlite is defined as a global object unless angular or an umd library is present

in any case, you can avoid using .noConflict() by placing jquery (or zepto, etc) before jqlite

<script src="jquery.js"></script>
<script src="jqlite.js"></script>
<script>
// your can create an alias for jqlite if you need
$jq = jqlite;
</script>

jqlite does not override '$' variable if is already defined

Fire-Brand commented 8 years ago

Cool, but what if i can't control whether jqlite is called before or after jQuery ?

jgermade commented 8 years ago

You can do following (after all scripts):

<script>
$jq = jqlite;
$ = jQuery;
</script>
jgermade commented 8 years ago

are you using any build library like grunt or gulp to inject scripts?

Fire-Brand commented 8 years ago

Myself no, but other people who uses my component may....

jgermade commented 8 years ago

OK!

maybe this works for you:

(function ($, $jq) {

   // inside this closure $ is always jQuery and $jq is always jqlite

})(jQuery, jqlite);
jgermade commented 8 years ago

this seems to be resolved