mbQuery is a significantly lighter (less overhead, lighter on resources, 10kb for weight) version of jQuery which only implements the more often used features. Its API is a mimic of jQuery’s, but simply not complete. That means any code written in mbQuery is also perfectly valid code for jQuery (with jQuery simply having more features on top of the ones available in mbQuery). You can start out programming in mbQuery (only need 10kb worth of code) and then if you later realize you need a jQuery feature that mbQuery doesn’t have you can literally remove the script tag pulling in mbQuery and bring in jQuery instead and your code will still function. And it’s MIT licensed for anyone to use.


Download mbQuery


Why Make mbQuery?

I prefer vanilla JS for most things. However, I’m a pragmatist. There are things for which jQuery coding is amazingly efficient (e.g. manipulating/querying the DOM and simple animation). But usually I only need jQuery functionality in a few places, and it’s usually only a very small set of jQuery’s full abilities that I actually use. Because of this I find it hard to justify including a code package with as much overhead and size as jQuery (many later versions are approaching 100kb). I realized that a small library purpose-built to do similar things to jQuery but that only has the 5% of the features that do 95% of the work would be extremely useful.

On top of that I realized that that library could be built to mimic jQuery’s API completely (in what functionalities it does make use of) and therefore it would take practically zero learning curve (other than knowing which jQuery stuff was/wasn’t available in the new library) and you could literally flip right over to having the page use jQuery if halfway through the project you realized you needed some more advanced features. You wouldn’t even have to re-code your project. Just import the jQuery file instead of that library and get back to coding...all your previous code will work the same.

And thus, mbQuery was born. It’s kinda like having your cake and eating it too. Start off with a nice tiny library, but without tieing yourself to it in case you need the full juggernaut that is jQuery later.

What are the differences?

The only API difference (as opposed to API omissions) is the usage of the variable name mbQuery instead of jQuery. So if you use the actual name instead of $ then you’ll have to do a find-and-replace of mbQuery->jQuery should you switch over. But that’s it.

Other than that the difference is simply omission. For example, since mbQuery handles it’s events a little simpler internally it’s able to have the .detach() function for removing nodes, but not the .remove() function (since the .detach() function doesn’t require removing of all events from the nodes being removed). Not only omissions of functions themselves, but also some removal of abilities from some functions. For example in jQuery’s .text() function you can use a function for an argument instead of the text you want to set, adding some complex abilities. 99% of people don’t do this, and it adds weight. Therefore mbQuery’s .text() function cannot accept a function. Just use it in the traditional way of getting/setting a string of text. Other differences are in properties available for use. For example in mbQuery the $.ajax() function can only do a return dataType of 'text' or 'json', because that’s simpler, cuts weight, and is what most people use anyway. mbQuery is also IE9+ only, like the modern versions of jQuery.

So what features are in mbQuery?

I was able to fit a surprising amount of functionality into mbQuery for its size. As for specifics on what it can do read up on that below:

- Document Ready Shortcuts -

$(document).ready(function(){ }); - Works as normal. Can also use mbQuery(document).ready(function($){ }); for playing nice with other libraries that use $, just like jQuery can.

$().ready(function(){ }); - Also works as normal...and also not recommended just like jQuery doesn’t recommend it.

$(function(){ }); - This jQuery-like shortcut to the document ready also works just like jQuery.

- Querying -

mbQuery() or $() - Both work the same, much like jQuery except obviously it’s a bad idea to steal the jQuery name when the library isn’t actually jQuery. Therefore it uses mbQuery instead.

$("#selector .of some.sort") - Can take a String selector and match elements like jQuery. Does not have the added query abilities jQuery does, basically what works in a normal querySelectorAll call will work here.

$(document) - Can form the mbQuery object from a single element.

$([element1, element2, element3]) - Can form the mbQuery object directly from an Array of elements. Note that it must be an actual Array, not just an Array-like object.

$('HTMLString') - Can parse an HTML string into the actual HTML elements that the mbQuery object represents. Side note: pretty much anywhere where an argument that is a string could be considered a selector OR an HTML string, mbQuery determines if it’s intended to be an HTML string by whether or not the first character is “<".

$($anotherMbQueryObject) - Redundant and not recommended, but can form mbQuery objects from another mbQuery object like jQuery can from another jQuery object.

- mbQuery Static Functions / Properties -

mbQuery.noConflict() - Gives up control of $ like jQuery does, setting it to whatever it was before mbQuery took it over. Does not take the optional argument that jQuery can. Does still return the mbQuery object like jQuery does.

$.ajax(url, [settings]) - Loads an external file and can send it data like the jQuery ajax function except not as versatile, omitting many lesser used features. For example, requires the jQuery optional format (url, [settings]) instead of allowing the optional 1 argument object format that includes a url property. Will always be async:true no matter what you do. Allows the following properties to be set on the settings object:
- type: “POST” or “GET” or others.
- data: The object representing variables to send.
- headers: Object representing custom headers to set.
- dataType: The return format, though only works with “text” or “json", not the other ones jQuery allows.
- success: The callback function for success (though only utilizes the 1st ’data’ argument, not the other ones jQuery can send).
- error: The callback function for an error (doesn’t send any arguments like the jQuery version does).
- async:true - You can include this for readability purposes, but true is the only usable value and it will be the default anyway.

$.get(url, [successFunc], [data], [dataType]) - Shorthand for $.ajax call with “GET". Only takes the format (url, [successFunc], [data], [dataType]), not the other ways jQuery can take it.

$.post(url, [successFunc], [data], [dataType]) - Same as the $.get above except with “POST".

$.parseHTML(htmlString) - A simpler version of the jQuery equivalent which only takes the 1st argument possible in the jQuery version. Returns an Array of DOM elements like the jQuery version.

$.fx.off - false by default, can be set to true to essentially make all animation times zero, which is beneficial for turning of animation in environments that can’t handle them as well.

$.fx.interval - Gives the ability to set a number (in milliseconds) for the interval at which animations update. Unlike jQuery in mbQuery you must set this property before you actually use any animations.

- mbQuery Object Functions -

.get([index]) - Used to access the elements within the mbQuery object like is done in jQuery. Returns an Array of all if the argument is omitted.

.toArray() - Returns an Array of all matched elements. Basically the same as calling .get() with no args...not sure why jQuery needs it, but added almost no weight to add, so I did.

.eq(index) - Used to access the elements within the mbQuery object like is done in jQuery, but return them as another mbQuery object to work with. Can use negative index to get by an amount back from the end. If the index is out of bounds will return an empty mbQuery like jQuery does.

.find(selector) - Allows you to find elements within the elements represented by the mbQuery object using a selector string. Note that this does NOT allow anything other than a selector string (whereas jQuery has a few other things you’re allowed to pass its find function).

.children([selector]) - Returns an mbQuery object representing all direct children of each element within the original mbQuery object. If a selector string is given (it’s optional) then it will only return elements from that list that match the selector. Note that this is direct children only, i.e. one level deep. This operates just like the jQuery function.

.parent([selector]) - Returns an mbQuery object representing the parent elements of the current mbQuery object. If a selector string argument is given it filters by only elements that match that selector. Operates just like jQuery

.next([selector]) and .prev([selector]) - Gives an mbQuery object representing the element after/before each element in the original mbQuery object. If a selector string argument is given it filters by only elements that match that selector. Operates just like the jQuery counterparts.

.filter(selector) - Returns a new mbQuery object representing only the elements from the original that match the given selector. Unlike jQuery this function only takes a selector string, not the other possible arguments jQuery takes.

.not(selector) - Returns a new mbQuery object representing only the elements from the original that do not match the given selector. Unlike jQuery this function only takes a selector string, not the other possible arguments jQuery takes.

.is(content) - Gives a Boolean (true or false) for whether any of the elements in the mbQuery object match the content argument (which can either be a selector string or an actual element). Unlike jQuery only takes the selector string or an element (jQuery can take a few more things as an argument).

.html([htmlString]) - Like jQuery use the argument to set the inner HTML to your string, and omit it to get the current inner HTML string. Unlike jQuery cannot take a function as the argument.

.text([string]) - Like jQuery use the argument to set the element’s text to your string, and omit it to get the current text value. Unlike jQuery cannot take a function as the argument.

.append(content) and .prepend(content) - Inserts content at the beginning/end of the element much like jQuery’s append/prepend except for one thing. You can only give 1 argument (whereas in jQuery you can include as many arguments as you want. Other than those restrictions it operates like the jQuery versions. The argument can be an HTML string, an actual element, an Array of elements, or another mbQuery object.

.after(content) and .before(content) - Just like mbQuery’s .append() and .prepend() (above) except insert after and before the elements instead of appending/prepending inside them.

.add(obj) - Makes a new mbQuery object representing the elements in this mbQuery object as well as the elements added via the argument. Operates like the jQuery version except only takes 1 argument, not multiple. That 1 argument can be an HTML string, a selector string, an actual element, or another mbQuery object. Will not modify the originals.

.clone() - Makes a new mbQuery object with cloned elements just like jQuery does. Only does not allow the optional arguments that jQuery does, acts like jQuery version called without any args.

.detach() - Removes the elements from the page. Cannot take the optional arguments like jQuery can, just gets used plain.

.remove() - Not usable. However, extremely common so I’m putting it in the docs just to tell you to use .detach() instead. That is equivalent except .detach() removes the elements without affecting their listeners and such like .remove() does. mbQuery doesn’t have the tracking needed to do that in the same way jQuery does so uses .detach() instead.

.css(prop, [value]) - Gets/sets CSS properties like the jQuery css function, except doesn’t allow an array for prop (just give 1) and doesn’t allow a function for the value. Otherwise it’s the same, just use prop to get the css value. Use prop and value to set a value. Use an Object for prop with a bunch of prop:value pairs to set multiple at once. Doesn’t attempt to get calculated values or anything, just works with the style object.

.hide() and .show() - Literally just hides and shows the elements like if you called the jQuery functions. These CAN take the arguments for animating in/out, but since that is part of animation that is documented with the other animation functions lower on this page.

.data(dataName, [dataVal]) - Used for getting or setting data attached to the HTML elements like in jQuery. Just dataName will return its value, dataName and dataVal will set the value. Can also take an Object of name:value pairs for setting multiple attributes at once. Does not allow dataVal to be a function like jQuery does. Does not allow calling with no arguments like jQuery does.

.removeData(dataName) - Used to remove data attached to elements, like jQuery.

.prop(propName, [propVal]) - Used for getting or setting properties on the HTML elements like in jQuery. Just propName will return its value, propName and propVal will set the value. Can also take an Object of name:value pairs for setting multiple attributes at once. Does not allow propVal to be a function like jQuery does.

.removeProp(propName) - Used to remove an attribute from elements, like jQuery.

.attr(attName, [attVal]) - Used for getting or setting attributes like in jQuery. Just attName will return its value, attName and attVal will set the value. Can also take an Object of name:value pairs for setting multiple attributes at once. Does not allow attVal to be a function like jQuery does.

.removeAttr(attName) - Used to remove an attribute from elements, like jQuery.

.val([setVal]) - For getting and setting the values of form elements like the jQuery counterpart. Without the argument it will get the value, with the argument it will set it. Does not allow the argument to be a function like jQuery does.

.hasClass(class) - Gives a true or false for whether any of the object’s elements have the supplied class.

.addClass(class) - Adds the given class to any of its elements that don’t already have it.

.removeClass(class) - Removes the given class from any of its elements that have it.

.on(type, handler) and .off(type, handler) - For handling events like the jQuery counterparts. Operate much simpler, with just the standard (type,handler) arguments. The handler function will receive an event object like jQuery, except that it’s the actual native event object instead of an abstraction of it (will have the same properties/methods).

.trigger(type) - For triggering events manually. Operates much more simply than jQuery, literally just dispatches an event on all elements in the object of the type specified and bubbling and cancelable. Usage-wise it is the same, but only takes the one argument.

.each(callback) - Loops through the mbQuery object’s elements calling the callback function once for each. The callback function receives an index argument, and has its this keyword set to the element. Returning false at any time will break the loop. Operates just like the jQuery version. Note that this is the .each() function, not the $.each() function, which is completely different and not included in mbQuery because it’s just an abstraction of normal looping through normal JS Arrays/Objects.

- Properties -

.length - gives the amount of elements in the mbQuery object just like jQuery does.

.ismbQuery - if for some reason you need to differentiate when in your code your page is running mbQuery instead of jQuery this property will return true on any mbQuery object (and presumably undefined on any other, including jQuery). Expect it to be undefined when it’s jQuery instead of mbQuery and it won’t break the idea of mbQuery code still working if you import jQuery instead.

- Animation -

All mbQuery animation functions depend on the MBTweener library (only 7kb) being present for mbQuery to utilize. This does NOT need to be present in general for mbQuery to work, only for these animation functions to work.

One noticeable divergence is that the tracking/queueing of animations is done on the mbQuery object itself. That means you can’t just instantiate 2 different mbQuery objects and expect them to share a queue (i.e. $('.class').animate(...); $('.class').animate(...); the second is not going to queue after the first like it would in jQuery, it’s just gonna screw stuff up) so the standard in mbQuery is to always store your mbQuery objects (i.e. var obj = $('.class'); obj.animate(...); obj.animate(...);). This is the proper practice in jQuery, the difference is that jQuery tolerates it if you don’t follow that practice and mbQuery doesn’t. Again, mbQuery is for simpler work, so just get 1 mbQuery object for a given set of stuff you want to animate and keep all your calls to animation functions happening on that specific mbQuery object so that it tracks the queue correctly.

However, this still follows the guiding principle of mbQuery: all proper mbQuery written code will still work in jQuery, even if not all working jQuery code will work for mbQuery. jQuery is still the big brother, mbQuery is just a whole lot lighter in size and resources.

mbQuery has both of the jQuery included ease types (’swing’ and ’linear’), but since it uses MBTweener to handle the animating it also will allow you to use many others: ’easeInSine’, ’easeOutSine’, ’easeInOutSine’ (same as ’swing’), ’easeInExpo’, ’easeOutExpo’, ’easeInOutExpo’, ’easeInElastic’, ’easeOutElastic’, ’easeInOutElastic’, ’easeInCircular’, ’easeOutCircular’, ’easeInOutCircular’, ’easeInBack’, ’easeOutBack’, ’easeInOutBack’, ’easeInBounce’, ’easeOutBounce’, ’easeInOutBounce’, ’easeInCubic’, ’easeOutCubic’, ’easeInOutCubic’. However jQuery does not include those, so if you use them you are breaking the “all mbQuery works in jQuery” principle. However, I allow them to exist and be usable because plenty of jQuery plugins exist to add those easing functions. So just be aware that if you use them and you then switch to jQuery you’ll then need a jQuery plugin to add those easing functions.

mbQuery does also have .slideUp() and .slideDown() functions but I do not document them here because I do not consider them “like jQuery” enough to be an advertised feature. If you want to go into the source and figure out their API/use them then you’re welcome to, but don’t complain about their differences from jQuery, because you’ve been warned. They do follow the same general principle of “things slide closed, things slide open” though, and they do basically take the same arguments.

'+=50' type stuff is also a no go, just give your end desired value. And for durations/time you can’t use 'slow' and such like jQuery, just give the number in milliseconds.

tl;dr: mbQuery animation functions are a lot less forgiving of poor practices (make sure to store your mbQuery instances in a variable), and are missing a few jQuery features. But otherwise are pretty capable for their size/weight, and work like jQuery.

.animate(props, [time=400], [easeOrOnDone='swing'], [onDone]) - API just like jQuery except does not allow the ’1 argument object to set them all’ concept. Takes up to 4 arguments (only the first one, the properties to change, being mandatory), with the third one being a shapeshifter (it can be the onDone function or the easing string, in which case the fourth one could then optionally be the onDone function). To be clear, the acceptable argument formats are: $mbObj.animate({top:'10px'}); or $mbObj.animate({top:'10px'}, 1000); or $mbObj.animate({top:'10px'}, 1000, onDoneCallback); or $mbObj.animate({top:'10px'}, 1000, 'linear', onDoneCallback); Chaining calls to make a queue of animations to run works fine.

.stop([clearQ=false], [toEnd=false]) - Basically the same thing as jQuery. Stops the currently running animation, and optionally clears the queue and/or goes to the end of the currently running animation depending on the arguments you send.

.delay(time) - The same thing as jQuery. Adds to the queue a delay that will happen before the next animation. Give it the time of the delay in milliseconds.

.fadeIn([time=400], [easeOrOnDone='swing'], [onDone]) and .fadeOut([time=400], [easeOrOnDone='swing'], [onDone]) - Same thing as jQuery. Shortcut for the .animate() function for fading in/out.

.fadeTo(time, opac, [easeOrOnDone='swing'], [onDone]) - Same thing as jQuery. Shortcut for the .animate() function for fading to a certain opacity. I don’t know why they didn’t just put the opac as the first argument so that the time can remain optional and you can just go .fadeTo(0.5) or whatever...but jQuery doesn’t do it that way, so neither did I. That means both the first two arguments are mandatory.

.hide(time, [easeOrOnDone='swing'], [onDone]) and .show(time, [easeOrOnDone='swing'], [onDone]) - Same thing as fadeOut and fadeIn except actually hides the element completely (via it’s display CSS going to ’none’ when hidden) once faded out. The arguments are optional, but if you don’t include any then it just hides/shows in a non-animated way, which does NOT require the MBTweener library to be present. That is why the no-argument versions of these are documented above in the normal non-animated docs.

- Overcoming mbQuery vs. jQuery Naming -

Obviously I don’t want to name the variable jQuery, because it’s not jQuery. Normally that would be fine because you’re using $ most the time, so you can switch back and forth between using mbQuery and jQuery just by choosing which one to import, and the code will be the same either way. But what about when that’s not true? Such as when the $ isn’t trusted and you would normally explicitly use the name jQuery such as jQuery( ... ); or (function($){ $( ... ); })(jQuery); ? Well, that’s actually easily solved with the statement window.jQuery||window.mbQuery. That will simply return whatever one is available, and default to jQuery if both are available. For example:

var qry = window.jQuery||window.mbQuery;

or the much cleaner IIFE statement version:

    // can safely use $ in here since is a local param to the IIFE

or with a DOM ready event:

    // can safely use $ in here since is a local param in the ready function

Current version is 1.0.3 (out of beta mode now). Let me know about any bugs found.