10 ms·
Bling – the $ of jQuery without the jQuery
- pluma 11y agoThis does three things: 1. Alias document.querySelectorAll to $. 2. Alias node.on to node.addEventListener. 3. Make NodeList a sub-type of Array (so you can use forEach etc on node lists as you would on arrays). The $ of jQuery also does a few other things, e.g. create HTML elements from text ($('<div class="foo"/>') creates a div element with CSS class "foo") and wrap elements in a node list ($(document.body) creates a node list containing document.body).
- pimterry 11y ago4. Add NodeList.on, which adds the event listener to all nodes in the list
- notNow 11y agowrap elements in a node list This is not correct. You may say that it wraps or outputs elements in a node list like object but it is not the real deal. If you examine the emitted jQuery objects using instanceof or any other method, you'd see that they are not related to NodeList in any way. They're just generic objects of Object type.
- pluma 11y agoTrue, jQuery doesn't use the native NodeList for various reasons, but since QSA returns a NodeList, that'd be the equivalent for this "substitute".
- masklinn 11y ago> jQuery doesn't use the native NodeList for various reasons Those reasons being: * because it's garbage * because native objects shouldn't (and may not necessarily be) extended * because static nodelists didn't even exist back when jquery was created * because you can't create a nodelist in userland code
- pluma 11y agoAlso (and probably most importantly): * because NodeList instances are host objects and host objects often behaved in unexpected ways in older browsers and IE If you want to have a look at host object weirdness, try using `console.log` as if it were a function when using the F12 developer tools in IE8. Surprise: it can be invoked like a function, but it doesn't have any of the methods you'd expect a function to have (e.g. apply, call, let alone bind). Another host object quirk was that they were often read-only (which is why "thin" AJAX libraries can't manipulate the native XHR objects directly if they want to support IE8). "Who cares about IE8?" you ask? Surprisingly some sectors of certain industries still do (civil service in Germany, for example). If your market overlaps with those groups, you'll be thankful most of us were at least able to skip IE7 after IE6 finally died (I'm not sure whether we'll be as lucky with IE9 when IE8 finally bites the dust).
- vortico 11y agoThis is all I personally ever need. function $(q) { return document.querySelector(q) }
- zodiakzz 11y agoI prefer:- function $(q, parent) { return (parent || document).querySelector(q); }
- egeozcan 11y agoI'd also wrap it in a `[].slice.call`: function $(q, parent) { parent = parent || document; return [].slice.call(parent.querySelectorAll(q)); }
- marcoms 11y agoAlso see ES2015's Array.from() Array.from(<NodeList or other iterable>) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- bodhi 11y agoIf we're golfing, $ = document.querySelector.bind(document); would be sufficient? ;)
- eloisant 11y agoI don't really know what to think about that. On one hand it may be a nice way to show to people that what they use in jQuery can be written in a few lines of pure JS. On the other hand it encourages people who could use pure JS (because they only use a small portion of jQuery) to stick with some non-standard helper syntax.
- andybak 11y ago> to stick with some non-standard helper syntax. Or in other words - replacing an ugly, verbose API with a widely recognised alternate syntax!
- anton-107 11y agoYes "document.querySelectorAll(selector)" is a bit verbose, but jQuery API is no better, do you know what would "$(selector)" actually do? You can't - it depends on what "selector" is.
- yakshaving_jgt 11y ago> "document.querySelectorAll(selector)" is a bit verbose Right. 35 characters. > "…but jQuery API is no better" Your jQuery example is 11 characters. I can’t believe you’re using verbosity as a measurement, while at the same time claiming 35 and 11 are the same. Does. Not. Compute.
- anton-107 11y agoSorry for confusion, what i meant was: yes DOM API is a bit verbose, but jQuery is exactly the opposite in a bad sense: it's using too few words to express too many different things.
- Akkuma 11y agojQuery uses CSS selectors, which is fairly clear if you have a general understanding of them.
- omegote 11y agoTries to play it cool by wrecking jQuery? Check. No semicolons? Check. Put together by Paul Irish? Check. Yep, this submission is Hipster 1.0 Certified.
- VeejayRampay 11y ago1) Paul Irish is a former jQuery team member and he has blog entries about how much he's learned from reading jQuery's source code, not sure exactly how he's "wrecking jQuery". 2) Semicolons are still in debate amongst the JS community, I don't think there's a consensus on whether they're needed or not and it seems to boil down to personal preferences. 3) This reeks of ad hominem, how exactly is Paul Irish "hipster"? Strikes me as someone who's done a lot of work to make the web a better place for all of us, fine with me.
- jbrooksuk 11y agoFWIW John Resig himself originally wrote jQuery without semi-colons but it caused all sorts of issues very quickly!
- riquito 11y ago> 2) Semicolons are still in debate amongst the JS community, I don't think there's a consensus on whether they're needed or not and it seems to boil down to personal preferences. They are needed. This var func = function(x) { console.log(x); }; func; (42); is different from this var func = function(x) { console.log(x); } func (42)
- bakabaka9 11y agoThey aren't needed at all. Semicolons in JS are optional. Knowledge about how ASI works, on the other hand, is mandatory.
- mootothemax 11y agoThey aren't needed at all. Semicolons in JS are optional. Which becomes really annoying if you just want to quickly concatenate a few files together. Sure, it's something that you can fix yourself; I'd consider it a common courtesy to include at least one, though.
- nickysielicki 11y agoI use jquery because I use bootstrap and it requires it for some features I use. I wish that someone would write a drop-in javascript replacement for jquery in the context of bootstrap.
- Kiro 11y ago> [].slice.call( document.querySelectorAll('.foo'), function(){ When do you need to do that?
- renekooi 11y agoquerySelectorAll returns a NodeList instead of a real array, so you can't call things like `.forEach` on the result. `[].slice.call(x)` turns x into an array, so that becomes [].slice.call(document.querySelectorAll(...)).forEach(function () {}) Because a lot of array methods are "generic", i.e. operate on array-like objects instead of just arrays, that can be "compacted" to [].forEach.call(document.querySelectorAll(...), function () {}) but neither are very nice.
- egeozcan 11y agoProbably meant to be [].slice.call(document.querySelectorAll('.foo')).forEach(... It "casts" the NodeList which is "Array-like" to a proper Array, which has forEach, map and other useful methods in its prototype.
- ceronman 11y agoYes, you can re-implement jQuery in 10 lines of code... if you only support 0.1% of the functionality of jQuery. jQuery was a game changer for web client side development. Thousands of work hours have been spent on it. It had a specially important role of dealing with all the inconsistencies between browsers. If you don't use all the features, nowadays you can just create a custom build with the stuff you want. If you don't need jQuery, maybe because you only care about modern browsers, or you use another library or you don't mind a bit of extra boilerplate for DOM manipulation, that's perfectly fine. But these kind of posts seem like mockery on the developers of a library that has provided extreme value for thousands for developers over many years.
- VeejayRampay 11y agoI would agree with your comment, but the author is not claiming to be reimplementing jQuery in 10 lines of code. He's merely providing a way to benefit from the syntactic sugar ($) to avoid using the verbose vanilla JS API (document.querySelectorAll) and solve the issue of NodeList not supporting the functionality available on Arrays (forEach, map, etc), which doesn't make any sense in the first place.
- inglor 11y agoYou are arguing against a strawman - no one is claiming otherwise. All paul_irish wanted to show is that people often use jQuery without realizing that most of what they do is also possible with the current browser APIs. jQuery does a ton more (animation, ajax etc) - the point was not to "rewrite jQuery in 10 lines" (that's Zepto)
- nolok 11y agoZepto is more of a "provide the jquery interface you're used to" (and that people often find easier, probably by habit) for modern browsers without all the added compatibility in jquery. I don't like the way they present themselves (or at least did in the early days) but I believe they have a place.
- frik 11y ago
- goyote8 11y agoCan someone explain the new trend to not use jQuery?
- rogem002 11y agoIMO jQuery is one more thing the end user has to download and process, the more stuff we can strip out while keeping the same user experience is a good thing. Though I think most the people moving away from jQuery are doing it because the browsers have become more consistent in how they run JS.
- anton-107 11y agoI've always seen jQuery as an additional layer to handle browsers' API inconsistencies. If browsers you need to support have consistent APIs now - there is no reason left for adding this layer to new projects anymore.
- VeejayRampay 11y agoIt's a general trend in programming that we've seen forever. Once a successful monolith/monopoly is established and once it becomes all-encompassing (and maybe too far-reaching), people tend to want to be able to cherry-pick the different bits without having to rely on the whole. It's not a mark of disrespect to the fantastic work of the people who created jQuery in the first place, but merely a sign that jQuery is not godly anymore, people want to appropriate it and make it their own, have it cater to their needs and use cases. I think that's a good thing.
- aethr 11y agoA lot of developers originally used jQuery as a cross-browser compatibility library when that was still a major concern. Along the way, jQuery has added tons of extra helper functions and wrappers (ie, .ajax(), .post(), event binding helpers, etc). This has been amazing for web development, but it's also been such a major pillar of web development that a lot of front end developers don't actually know what's happening under the hood when they use jQuery. jQuery as a library has now become huge, and a lot of projects probably don't use the full feature set. With modern browser support converging and older browsers being edged out of the usage stats, there's not as much need for the cross-browser portions of the library anymore. Enough so that newer versions of jQuery have dropped support for those browsers as well. So if you can cut down your cold cache loading times by not including the full jQuery library, that's probably a win (especially on mobile). You can do this by using a custom build of jQuery, but I guess some developers are taking this opportunity to go "back to their roots" and see how Javascript has changed since jQuery became a de-facto include in every project. I think there's a lot more maturity in the language these days, and by using native JS methods there's probably opportunities there for browser optimisations that aren't available using helper methods written in JS that accomplish the same functional goals. But I'm not a browser devevloper or a JavaScript expert, just a long time web developer who remembers the times before jQuery was in every project. If it's a crutch, it's one I will remember fondly.
- inglor 11y agoNote that work is being done to give `NodeList`s the `Symbol.iterator` property so in new browsers it's trivial to use the native DOM with `for(let x of nodeList)` loops making our lives easier. This will make our lives easier :)
- notNow 11y agoBut I must say that I don't really like the list comprehensions syntax in JS.It leaves a lot to be desired.
- XCSme 11y agoWell, the thing with jQuery is that if you use a CDN to get it from, then it is a very high chance that the client already has the library cached, so the bandwidth problem is actually not that much of a problem now.
- jrochkind1 11y agoSome people have doubted that, based on so many versions of JQuery and multiple CDN's too. I'm not sure it's ever been demonstrated to be true.
- LocalPCGuy 11y agoIt's probably better for most sites to minimize the number of DOM lookups by combining jQuery with the rest of your vendor code in a vendors.js (or similar) file. The chance for a cache hit is very low (and getting lower with the trend away from jQuery). That said, test the 2 approaches and see which works better for your site.
- mattdlondon 11y agoShameless self promotion for something I threw together ages ago and may be implemented in a better way these days. https://github.com/matt1/doc.js https://github.com/matt1/doc.js So it uses "doc" instead of "$" but feel free to fork :-)
- vsaiz 11y agofunny! I had the same idea a few months ago, 1 extra feature: .off binding to removeEventListener ;) https://gist.github.com/vectorsize/feda8ac1ebc889c33b6f https://gist.github.com/vectorsize/feda8ac1ebc889c33b6f not as tested as yours…
- yakshaving_jgt 11y agoLet’s replace non-standard JavaScript syntax-sugar with more non-standard JavaScript syntax-sugar. Except we don’t like that the first non-standard thing is so terse so let’s improve it with a more verbose notation. We don’t want it to be too verbose though, so let’s drop the semicolons. This is definitely progress. I’m quite convinced that the users of our applications will feel the difference, and they’ll love us for it. Wow.
- yakshaving_jgt 11y ago“jQuery is not need anymore with modern browsers.” Bull. Shit. This document proves why, and is written by the same guy that is now pushing this “you don’t want jQuery!” stuff. https://docs.google.com/document/d/1LPaPA30bLUB_publLIMF0RlhdnPx_ePXm7oW02iiT6o/edit# https://docs.google.com/document/d/1LPaPA30bLUB_publLIMF0Rlh...
- johnwards 11y agoSo he isn't pushing anything, both things can be valid. You don't "need" jQuery, but you might not-not need jQuery unless you do something about those bugs. yell.com mobile site removed jQuery from their codebase, and used that list during the process. Looking at each bug, does it affect them, yes/no. If yes, code around it. I'm a jQuery fan, but sometimes you might not need jQuery, but sometimes you might not-not need jQuery
- BinaryIdiot 11y ago>> “jQuery is not need anymore with modern browsers.” > Bull. Shit. Depends on the target environment(s). If you only want to support evergreen browsers then there is no reason you need jQuery; you're going to have the native DOM APIs and you don't care about compatability. jQuery's big win is two fold, in my opinion. One it has awesome, chain-able syntax and two (most important) it has awesome backwards compatibility with terrible browsers. If you don't need two then is one worth bringing in another dependency? Maybe or maybe not.
- yakshaving_jgt 11y ago> If you only want to support evergreen browsers then there is no reason you need jQuery False. Read the first sentence of the document I linked to. “…developers should be aware that ditching libraries, like jQuery, can easily require large amounts of research on their end to avoid bugs (even in modern browsers).” Bear in mind it’s Paul Irish who wrote that.
- BinaryIdiot 11y ago> False > Read the first sentence of the document I linked to. Oh I did. Look through many of the bugs they outline; many are incredibly minor and inconsequential unless you're doing things related (or semi related) to supporting older browsers. > Bear in mind it’s Paul Irish who wrote that. Yup; I don't see his posts being quite in conflict like many here seem to think. Plus his opinion has probably evolved overtime anyway (he wrote that document a year and a half ago).
- shekel 11y agoMy worry about using this is you'd better be damn sure you never actually use jQuery or libraries that integrate with jQuery if you're going to use it. I think this is a cool demonstration of the difference between some of the "convenience" functions of jQuery many are familiar with and the MEAT of jQuery which is the functionality and cross-browser issue smoothing.
- joesb 11y agoNice. So where is my $.text(), $.css(), $.html(), $.val(), $.first(), $closest(), etc.?
- izolate 11y agoWith bling.js: .text: $('.selector')[0].textContent .css $('.selector')[0].style .html: $('.selector')[0].innerHTML .val: $('.selector')[0].value .first: $('.selector')[0] .closest: n/a
- joesb 11y agojQuery's $.text/html() set the text of all matched nodes, not just the first one. I can use key-value object to assign multiple css property, and it can set the style on all matched nodes. If there are no matched elements, Bling's $()[0].xxx = value" will raise exception.
- izolate 11y agoThat's the thing, Bling.js also makes it easy to set the text/css on all nodes: $('.foo').forEach(el => el.textContent = 'bar') $('.foo').forEach(el => el.style.top = '0px')
- nateabele 11y agoHere's an idea for a jQuery replacement: a website that allows you to select what browsers/versions you want to support, then it generates you a polyfill. Then aliases `$` as a selector function.
- addicted44 11y agoIf you are using $ signs all over your code, they'd better refer to jquery and nothing else. jQuery has, for better or worse, become such an integral part of web development, the $ namespace is pretty much owned by it at this point. If you do want to use it for not-jquery, it should be something that is drastically different so someone new trying to patch a bug on prod doesn't run around in circles wondering why their code that should be working is not. The bling.js project by repurposing $ into something that looks like it might be jquery but isn't, is just a bad idea.
- allendoerfer 11y agoI think so, too. The "on" alias is great, so it might as well create an alias like "qsa", "query", or "find" on Node, that searches within its children, and on window, that searches within the whole document. I wonder, why that is not done more, after all it is one of the benefits of prototype based inheritance, that you do not have to subclass to change the interface.
- untog 11y agoIt's not even a project, it's a GitHub Gist. Talk about a lot of fuss being made over nothing.
- wwweston 11y agoSure, this is just an illustration. I hear Eric Meyer's normalization css was too -- more intended as a to-do list of elements you might want to consider reseting than something to include and then override. But then a lot of people ran with the idea of leveling all margins and padding with a global override to start with and then overriding that override (usually inadequately). Of course, the horse is out of the barn on the personal $ library front, so maybe Irish doesn't have to worry about inadvertently influencing people badly. There already was a no-library/micro-library trend 4-5 years ago where lots of people would write their own tiny jQuery-like DOM utilities, and I've worked on a few projects where someone used jQuery-like idioms for their partial reimplementation (I call them "nayQuery"). Even the better ones are a pain where they subvert expectations. And of course, when someone later decides to add jQuery to the project (makes sense, jQuery does more and has an ecosystem around it), now you're using $ for the custom library and jQuery for jQuery, which is disorienting. I've written my own version of what Irish presents here -- it's a useful exercise, I appreciate his contribution (helps me think about some different ways to approach it), and sometimes it's even concretely useful when you're getting started on a small project with a limited browser target where the rest of the codebase is going to be smaller than jQuery itself. But when I write something like this, I always name it differently than $.
- awalGarg 11y agoI wrote a similar small dom module[0] which also fits in a gist with docs and tests :P --shameless-self-plug [0] https://gist.github.com/awalGarg/8a0e18c6fe87456d885f https://gist.github.com/awalGarg/8a0e18c6fe87456d885f
- EugeneOZ 11y agoWhen some part of jQuery can be replaced by native APIs so easy, it only shows how good jQuery was designed.
- etjossem 11y agoIf you quite literally want "what jQuery uses to select things" and nothing else, you're really looking for Sizzle. http://sizzlejs.com/ http://sizzlejs.com/
- paulirish 11y agoThese days it's not Sizzle, which is mostly support for non-qSA browsers and support for custom pseudo-selectors. jQuery's modern element selection is https://github.com/jquery/jquery/blob/master/src/selector-native.js https://github.com/jquery/jquery/blob/master/src/selector-na...
- etjossem 11y agoNice, thanks for the update.
- fleitz 11y agojQuery the useful parts.
- franciscop 11y agoThen you have the "" of jQuery: http://www.francisco.io/fun-extending-native-javascript-string http://www.francisco.io/fun-extending-native-javascript-stri...