While Cash doesn't implement every feature that jQuery provides, everything that it implements should be compatible with jQuery, but there are some minor differences to be aware of and they are listed in this document.
Boolean attributes are: checked
, selected
, async
, autofocus
, autoplay
, controls
, defer
, disabled
, hidden
, ismap
, loop
, multiple
, open
, readonly
, required
, scoped
.
jQuery handles boolean attributes specially, potentially setting a different value than the one you passed it and updating the corresponding properties as well.
Cash just handles them like any other attribute instead.
jQuery supports relative CSS values.
$('#foo').css ( 'padding-left', '+=10' );
Cash doesn't support this.
jQuery's $.fn.data
function caches retrieved values, and doesn't refresh them when they are updated outside of jQuery (e.g. via the dataset
API), this makes jQuery's $.fn.data
function unusable with libraries like React.
Cash doesn't implement such caching functionality and doesn't have this problem, the retrieved values are always fresh.
Also values set via Cash's $.fn.data
function are stored as JSON values in data-*
attributes set on the DOM nodes, so for instance calling $('#foo').data ( 'test', 123 )
will add the data-test="123"
attribute to the #foo
node, as a concequence of this values that are not JSON-serializable are not supported.
jQuery supports handling data on plain objects.
$({}).data ( 'foo', 123 );
Cash doesn't support this.
Hidden elements
If you're trying to retrieve the width/height of an hidden element jQuery will briefly try to render it in order to compute it's dimension, this is unreliable and should be avoided.
Cash doesn't implement such functionality.
If you need this anyway you'll have to show/hide the element on your own:
// jQuery
$('#foo').width ();
// Cash
$('#foo').show ();
$('#foo').width ();
$('#foo').hide ();
A negative width/height gets automatically converted to 0
by jQuery, both when setting it via $.fn.width|height
or $.fn.css
.
Cash discourages you from setting a negative width/height, if you want this to work like jQuery you'll have to convert negative values to 0
on your own:
// jQuery
$('#foo').width ( myWidth );
$('#foo').css ( width, myWidth );
$('#foo').css ({ width: myWidth });
// Cash
myWidth = Math.max ( 0, parseFloat ( myWidth ) );
$('#foo').width ( myWidth );
$('#foo').css ( width, myWidth );
$('#foo').css ({ width: myWidth });
jQuery ignores any transform
applied to the element when computing its dimensions.
Cash doesn't.
You may try reading untransformed dimensions with the $.fn.css
method instead.
Cash's event system relies heavily on the browser's underlying event system so there are some differences when comparing it with jQuery's.
jQuery provides some custom event methods.
event.isDefaultPrevented ();
event.isPropagationStopped ();
event.isImmediatePropagationStopped ();
event.originalEvent;
Cash doesn't provide them, as it simply passes along the raw event object instead.
event.defaultPrevented;
event.cancelBubble;
// No way of knowing if `stopImmediatePropagation` was called
event;
In Cash when using event delegation calling event.stopPropagation
or returning false
stops the propagation from the target element, not the delegate element.
There's no perfect workaround for this unfortunately, but in most practical cases you could call event.stopImmediatePropagation
instead.
// jQuery
$('#foo').on ( 'click', '.bar', event => false ); // First function called
$('#foo').on ( 'click', '.bar', event => {} ); // Second function called
$('#foo').on ( 'click', event => {} ); // Function never called
$('.bar').trigger ( 'click' );
// Cash
$('#foo').on ( 'click', '.bar', event => false ); // First function called
$('#foo').on ( 'click', '.bar', event => {} ); // Second function called
$('#foo').on ( 'click', event => {} ); // Third function called
$('.bar').trigger ( 'click' );
// Cash + "stopImmediatePropagation"
$('#foo').on ( 'click', '.bar', event => { // First function called
event.stopImmediatePropagation ();
});
$('#foo').on ( 'click', '.bar', event => {} ); // Function never called
$('#foo').on ( 'click', event => {} ); // Function never called
$('.bar').trigger ( 'click' );
jQuery supports passing multiple data arguments to your event handlers by providing an array of data arguments to $.fn.trigger
.
Cash doesn't support this, whatever you provide as a data argument will be passed through as is, even if it's an array.
jQuery supports handling events on plain objects.
$({}).on ( 'foo', () => {} );
Cash doesn't support this.
jQuery supports inserting plain text using different methods ($.fn.after
, $.fn.append
etc.).
$('.foo').append ( 'something' );
Cash doesn't support that because it instead supports receiving a selector as an argument, and that can be ambigous when also supporting plain text.
$('.foo').append ( '.foo' ); // Is that a target or do we actually wanto to append ".foo"?
In Cash you should generally wrap your plain texts in a <span>
element, or create a textNode
node manually.
$('.foo').append ( '<span>something</span>' );
$('.foo').append ( document.createTextNode ( 'something' ) );
jQuery smooths over many details and attempts to correctly parse malformed HTML.
$('<div/><hr/><code/><b/>').length // => 4
Cash on the other hand for the most part just lets the browser handle your HTML directly, so it behaves more strictly and you should be more careful about the HTML strings you're passing to it.
$('<div/><hr/><code/><b/>').length // => 1
jQuery implements many custom selectors, like :hidden
.
Cash only supports selectors the browser recognizes as valid, everything else will throw an error.
Some CSS operators are binary, they operate on something before and after them: >
, ~
, +
.
jQuery allows you to use them at the beginning of your selectors inside $.fn.find
, in a unary fashion.
Cash only supports selectors the browser recognizes as valid, so you can't just use > .bar
like you sometimes can with jQuery.
If you only target modern browsers you could use the :scope
CSS pseudo-class.
// jQuery
$('#foo').find ( '> .bar' );
$('#foo').find ( '~ .bar' );
$('#foo').find ( '+ .bar' );
// Cash
$('#foo').children ( '.bar' );
$('#foo').nextAll ( '.bar' );
$('#foo').next ( '.bar' );
// Cash + ":scope"
$('#foo').find ( ':scope > .bar' );
$('#foo').find ( ':scope ~ .bar' );
$('#foo').find ( ':scope + .bar' );
jQuery's $.unique
function only works with DOM nodes.
Cash's $.unique
function works with any kind of value.
Other general differences to be aware of.
jQuery handles specially disconnected nodes, iframes and SVGs, smoothing over many rough corners and just making their APIs "work".
Cash doesn't smooth over as many rough corners (yet?), so you should test more carefully the portions of your code that deal with those kind of objects.
jQuery accepts in many methods a function that returns a value, other than just the value itself.
$('#foo').attr ( 'bar', () => Math.random () );
Cash doesn't support this.
Elements inside Cash and jQuery collections may be sorted differently.
Did you find another difference between jQuery and Cash during your migration? Please add that to this page so that future migrations will be smoother for others.