Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Bling – the $ of jQuery without the jQuery (gist.github.com)
215 points by kolodny on June 15, 2015 | hide | past | favorite | 135 comments


Yes, 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.


You 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)


Zepto 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.


I tried "Flot" charts library with zepto as a smaller replacement for JQuery, but it was incompatible with JQuery and uses a weird code style that is incompatible/slow with Firefox (and Zepto devs refuse to fix their code). In the end I replaced the few Jquery dependencies in Flot by hand. It's a shame that Flot still requires Jquery, it's a good charts library.

The primary problem is that the zepto.Z function overrides dom.__proto__, which prevents many JIT optimizations. Overriding an object's __proto__ property is strongly discouraged and will be deprecated in ES6 --Firefox bug 947048


Um, isn't the point of Zepto a modular jQuery that may not support 100% of what jQuery does but it tries to at about the same speed (or better)?


I think modern jQuery is already modular (or semi-modular) and you can download a build of it that contains the features you want.

But honestly, if you load jQuery from a big-time CDN, chances are your users already have it cached and don't need to load anything.


The subtitle of the article is "Because you want the $ of jQuery without the jQuery". With such an ambiguous statement, I think we can afford ceronman the benefit of the doubt.

Furthermore, I don't think he's making up a strawman at all now matter how you look at it. He agreed with the article. You CAN re-implement jQuery in 10 lines of code if all you want is 0.1% the functionality of jQuery. That's what the article said and it is true. It's not an argument against any perceived strawman.

The next paragraph was praise for jQuery and the final paragraph said it's fine to not use jQuery and added an opinion about what "these kinds of posts seem like". Where's the strawman?


> The subtitle of the article is "Because you want the $ of jQuery without the jQuery". With such an ambiguous statement, I think we can afford ceronman the benefit of the doubt.

Headlines are supposed to be ambiguous, in the sense that they are much shorter than the content they accompany (and thus there are fewer possible headlines than there are possible articles). You're expected to read the content.


I 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.


I wrote this thing because I wanted the classic jQuery API goodness for 1) grabbing elements and 2) binding events. Yes, obviously this gist doesn't cover the feature set of jQuery; and in my brief readme, I hope I didn't convey something different.

We will always need jQuery. We need a well maintained library that addresses browser inconsistencies and provides a better API. (Don't expect my gist to be maintained like jQuery is. :) I wrote a doc a year ago documenting all the bugs jQuery fixes for you (linked elsewhere in this thread). The jQuery team is talented and I respect their dedication and work greatly. I'm also interested in a conversation about what developers want most from their browser JS stdlib. Because whatever a developer's answer is, shouldn't they be able to get a custom build of that?


Hey dude, first of all, thanks for all the stuff over the years. Second, this is really great. This is exactly what I was looking for this afternoon. I need to select some elements and bind an event, nothing more. You rock!


Why did you choose those two functions? There are already small NPM modules like dom-events for attaching and triggering events, and qwery, or sizzle for querying selectors.


> If you don't use all the features, nowadays you can just create a custom build with the stuff you want.

Yes, that's precisely the author's point, except that you might not even need to make custom jQuery builds. You might be able to just use these few lines.

> 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.

There is absolutely no implication of mockery, and anyone who knows anything about Paul Irish knows how laughable that accusation is.


For what it's worth I agree with you; in the end for better or worse jquery is a very good default in that it contains tonnes of debugged code that is tested by literally millions of people in production. It should probably be broken up further but I think they are doing that.

Whenever I've decided I know best and used Zepto or something else it introduces weird bugs and then someone decides we need to support IE8 because their Dad still uses it...


wow, storm in a tea cup much? He clearly mentions implementing '$', and nothing else ...


`$` is the point of entry to almost everything jquery provides, so he's not implementing jquery's `$` since the gist does not come even remotely close to jquery's featureset. He's implementing a completely different function with the same name.

If behaviour is considered irrelevant, here's my one-line implementation of $:

    var $;


But the post isn't claiming to provide everything that Jquery provides just replacing the "$" function. The "$" does two things in jQuery.

1. Its the DOM selection function. This is what he's replacing. This is the real "functionality" of the $ function. The main bit missing is that it won't create a new element if you pass in a string.

Return a collection of matched elements either found in the DOM based on passed argument(s) or created by passing an HTML string.

2. Its a Namespace for all the rest of Jquery. This is NOT what Paul's replacing but is kind of ancillary and really just good housekeeping for a js lib.


3. It also provides a DOMContentLoaded handler.

$(function(){console.log('DOMContentLoaded')})


If 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.


It's not even a project, it's a GitHub Gist. Talk about a lot of fuss being made over nothing.


Sure, 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 $.


If you're still relying on the global namespace you should stop. When I require('jquery') I'll name it what ever I damn well please, and you better get used to that because ES6 modules are here.


I 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.


This 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).


4. Add NodeList.on, which adds the event listener to all nodes in the list


Without the eminently useful support for delegation.



wrap 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.


True, jQuery doesn't use the native NodeList for various reasons, but since QSA returns a NodeList, that'd be the equivalent for this "substitute".


> 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


Also (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).


“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_publLIMF0Rlh...


So 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


>> “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.


> 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.


> 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).


This is all I personally ever need.

  function $(q) { return document.querySelector(q) }


I prefer:-

  function $(q, parent) { return (parent || document).querySelector(q); }


I'd also wrap it in a `[].slice.call`:

    function $(q, parent) {
        parent = parent || document;
        return [].slice.call(parent.querySelectorAll(q));
    }


Also see ES2015's Array.from()

    Array.from(<NodeList or other iterable>)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...


If we're golfing,

    $ = document.querySelector.bind(document);
would be sufficient? ;)


(var | let | const) $ = ::document.querySelector;

with experimental ES7 syntax :D https://github.com/zenparsing/es-function-bind


Huh, my joke actually turned into me learning something, thanks!


Hehe, You're welcome – I do take golfing very serious ;)


Can someone explain the new trend to not use jQuery?


A 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.


  > jQuery as a library has now become huge

  > So if you can cut down your cold cache loading times by not
  > including the full jQuery library, that's probably a win
jQuery 1.11.3 is 38.4 KB when minified and gzipped.

jQuery 2.1.4 is 34.1 KB when minified and gzipped.

I'm all for eliminating unnecessary bloat, but it's not as if a jQuery download is a huge amount of data to fetch. While jQuery is not a framework, most front-end JS frameworks are the same size or bigger and don't receive as much attention for being bloated.

If you can get by without jQuery, or if you have a very large number of mobile users and first-load performance is mission-critical for your application, or if you have a large percentage of users from countries with slow or intermittent internet connections, then sure, avoiding jQuery makes sense as a priority. But for most applications, jQuery is a smaller download than a single medium-resolution highly optimized image, and it can be cached forever.


Loading over 30 Kb of minified/gzipped Javascript over a 3G connection on a mobile phone is very problematic, as the bandwidth is poor, the CPU capacity for decompressing and parsing is poorer than on the desktop, so the latency can many times be measured in seconds, therefore loading over 30 Kb of stuff that you don't need gets to be a tough pill to swallow. Also the argument of caching is often brought up, but in my tests this can be very non-deterministic, as mobile phones are pretty aggressive in their used storage. JQuery is supposed to be cached, yet in our A/B testing the load times and consequently the conversion rates improved greatly after we dropped JQuery.

Your comparison with "a single medium-resolution highly optimized image" doesn't hold for mobile phones. On mobile phones users expect latency when loading images, but not when loading the UI. Another problem is that JQuery is not the only commonly used library. You add Underscore, you add Angular, or whatever libraries du-jour we have and pretty soon we are talking about 100 Kb of stuff or even more that is rarely used as a whole.

Of course, my use-case is about having really simple interfaces augmented by Javascript and meant for mobile phones. Well, for complex interfaces I think bringing in JQuery as a dependency may be worth it, but then again, I then start thinking that JQuery is not enough. It's because I want more, I want a virtual DOM that's saner by design, I want to work with immutability, I want much better performance without unpredictable behavior (like what you get with Angular) and I want to only pay for the features I use. JQuery is incompatible with React and is incompatible with Google Closure in advanced mode.


While I tend to agree in some respects, mainly in application memory inside the browser in mobile (RAM is still relatively small 2-4GB on many phones), the actual compute power is pretty capable on even modest smart phones for the past year+ (given a roughly 2 year turnover on phones for most), it's less an issue.

I also agree that jQuery isn't the end of what gets added... once you add a few additional libraries it gets very big, very quickly... I'm working on a project now that is loading about 19 jQuery plugins in addition to jQuery, as well as a handful of both bootstrap and jQuery-UI extensions, and the payload of a relatively simple page is coming in over 2MB (even if most of that caches, it's really big for a first hit).

People tend to start with a kitchen sink, then add not only the rest of the kitchen, but the barn as well without a thought or consideration to the final result, and the payload that goes with it.


It sounds like you've done the work to validate the fact that 30Kb is too much for your use case.

However, let's be clear here: most people who complain about the size of jQuery are doing so without any basis whatsoever. And even if people are measuring, they may not be measuring the right things. If not using jQuery causes you to reduce your Ajax usage, and reload entire pages as a result instead of only reloading the content, the end result is a slower site.


I totally agree and I exposed my use-case - really simple interfaces augmented by Javascript and served to mobile phones, so JQuery was basically unneeded, taking it out improved latency and thus it improved conversions. But of course, most people don't measure and most people need the features in JQuery to work reliably and to behave well cross-browser, in which case 30 Kb cached by a CDN is a steal.


> I'm all for eliminating unnecessary bloat, but it's not as if a jQuery download is a huge amount of data to fetch. While jQuery is not a framework, most front-end JS frameworks are the same size or bigger and don't receive as much attention for being bloated.

Remember size isn't as much of an issue when it's less than 100kb (though 3G or less networks that will still be painful). The biggest issue is yet another file for the browser to fetch. Synchronously or asynchronously the browser will still open another connection to the server to grab the file which results in further latency before your application really starts up.


I thought the biggest issue is once that file is downloaded it has to be unpacked, parsed, and executed in the browser that at the same time is trying to decode JPEGs and reflow the layout. It's why pages take 20 seconds or more to load.

Less javascript means less cycles burned executing boilerplate framework factories means faster page loading means longer battery life means you can keep that two year old phone that's not quite so fast instead of throwing it in the trash.

jQuery causes global warming. (tongue-in-cheek of course, but not entirely)


> The biggest issue is yet another file for the browser to fetch.

There's no reason you can't concatenate jQuery with the rest of your JS.


> There's no reason you can't concatenate jQuery with the rest of your JS.

True and most applications should really do this. In reality I've seen far too many production system still including sometimes over 50+ files.


For comparison, the site I work on serves up thousands of content images. I just did a quick scan across our media directory with a bash script, and the average image size was 78.0 KB


This explains it pretty well. I always have to argue with other developers to not break IE8. The comeback is always that it represents less than 1% of our sales, I argue that the 1% of sales is still more than their salaries.

As much as I'd love to stop keeping track of IE8 bugs, for a lot of sites this isn't possible. And, IMHO, this cavalier attitude is what causes many websites now to work "best" (read: only) in Chrome. It's true that a lot of sites (I'm thinking Webapps) don't need jQuery at all, and a lot of sites can get away with just using Sizzle, but 28kB is a small price to pay for the utility functions, cleaner AJAX API, event binding registry, etc. If you don't need them, by all means don't use it.


The "back to their roots" thing inspired this useful reference website: http://standardjavascript.info


I would add that a lot of the time, your browser-set is very small. For mobile apps, many of which use web views for at least some functionality, you're writing to one or two versions of WebKit only.


It'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.


In very basic terms - one of the biggest boons of jQuery were patching over browser incompatibilities. The tradeoff was an extra library being downloaded and a small performance trade-off (in certain scenarios).

In 2015 most browsers are in much better shape than they were in, say, 2007. A lot of people are mostly targeting users who use up-to-date, standards compliant browsers. They are also often targeting people who use mobiles, which are (for a couple of reasons) much more sensitive to poor JS performance than desktops, and also see a more tangible benefit from small page sizes.

Another advantage to jQuery was making complex JS operations very simple. Modern JavaScript has actually made life much easier[1], meaning that it's often only a little more work to use vanilla Javascript.

[1]: http://youmightnotneedjquery.com/


IMO 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.


I'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.


New trend? It was a new trend in 2011. Jquery isn't needed anymore with HTML5 browsers, all the useful API have been added with native speed advantage. If you still have to support IE8 than Jquery is great.


My 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.


I 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.


> to stick with some non-standard helper syntax.

Or in other words - replacing an ugly, verbose API with a widely recognised alternate syntax!


Yes "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.


> "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.


Sorry 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.


jQuery uses CSS selectors, which is fairly clear if you have a general understanding of them.


So does querySelectorAll, that's not the issue with jQuery API.

The problem is that "jQuery" function, aliased as "$" has 9 signatures (doing 9 different things, depending on which arguments you send to it), while querySelectorAll does only one thing


Well, 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.


It'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.


Some 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.


> [].slice.call( document.querySelectorAll('.foo'), function(){

When do you need to do that?


querySelectorAll 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.


Probably 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.


Here'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.


Shameless 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

So it uses "doc" instead of "$" but feel free to fork :-)


When some part of jQuery can be replaced by native APIs so easy, it only shows how good jQuery was designed.


I 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


funny! I had the same idea a few months ago, 1 extra feature: .off binding to removeEventListener ;)

https://gist.github.com/vectorsize/feda8ac1ebc889c33b6f

not as tested as yours…



Note 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 :)


But I must say that I don't really like the list comprehensions syntax in JS.It leaves a lot to be desired.


If you quite literally want "what jQuery uses to select things" and nothing else, you're really looking for Sizzle.

http://sizzlejs.com/


These 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-na...


Nice, thanks for the update.


I 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.


There's zepto.js, which is supposed to be a drop-in replacement for jQuery. Not sure how it fares wrt Bootstrap, though.


It is easy enough to just write a shim. Google "bootstrap zepto shim" to get you started.


Zepto?


Nice. So where is my $.text(), $.css(), $.html(), $.val(), $.first(), $closest(), etc.?


With bling.js:

    .text: $('.selector')[0].textContent
    .css $('.selector')[0].style
    .html: $('.selector')[0].innerHTML
    .val: $('.selector')[0].value
    .first: $('.selector')[0]
    .closest: n/a


jQuery'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.


That'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')


Tries 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.


This is the kind of shallow dismissal that we need less of on HN. Please don't post like this. I'm sure there's a thoughtful way to make your point, and that would be welcome.

https://news.ycombinator.com/newsguidelines.html


1) 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.


> 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)


You're right that your (very contrived) examples are different. But if anybody on my team writes code like this, it doesn't pass code review.


Sure, those examples are quite contrived. Here's one that's not:

  console.log("woof")
  (function() { console.log("foo") })()
Without semi-colons, that blows up (with a super unhelpful error message, to boot). Sure, if you understand ASI in JS, then you'll figure out the problem very quickly. But if you just always use semi-colons, then ASI is one fewer thing to have to worry about.


Alternatively:

    console.log("woof")
    void function() { console.log("foo") }()
There really is only one ASI rule you need to remember [0] in practice: don't begin a new line with ( or [ if it's intended to be a new statement.

On this topic, it could so easily have been different; I found this interesting from Brendan Eich [1]:

> I wish I had made newlines more significant in JS back in those ten days in May, 1995. Then instead of ASI, we would be cursing the need to use infix operators at the ends of continued lines, or perhaps or brute-force parentheses, to force continuation onto a successive line. But that ship sailed almost 17 years ago.

> ...My two cents: be careful not to use ASI as if it gave JS significant newlines...

[0] this is technically a lie because everybody needs learn the other one whether they use semicolons or not: don't put a linebreak after the "return" keyword :) [1] https://brendaneich.com/2012/04/the-infernal-semicolon/


void blows up on Safari.


>There really is only one ASI rule you need to remember [0] in practice: don't begin a new line with ( or [ if it's intended to be a new statement.

Here's an even easier and clearer one: finish every statement with a semicolon.


  function hello() {
    var x = 0;
    return
    {
      x: x,
      y: y
    };
  };
Just putting semicolons where you think it can work won't help you. If you write javascript, you must know what the asi does. So semicolons or no semicolons is completely irrelevant.


This is precisely why I hate optional syntax, regardless of which way your preferences fall on this particular one.


Mindlessly inserting unnecessary syntax instead of learning the damn language. Hacker News should be proud of its lusers.


I don't have a photographic memory. If "learning the language" means rote memorization of an inconsistent set of rules for how the fucking code is parsed, then you're goddamn right I'd rather mindlessly insert a character that obviates that.


A very simple rule - if line starts with '[' or '(', put semicolon before. Thats it.

Personally, if all is encapsulated inside self executing function, i put one semicolon before and one after it.


What about this?

    function v(x) {
     return
       x;
    }
    
    v("yeah");
returns undefined


What about it? Yes, it returns undefined. Has nothing to do with semicolons. You can add semicolon to every line of your example, or remove each and every one and still it returns undefined.


He's putting it in comparison to the previous example https://news.ycombinator.com/item?id=9718410

Newline matters / doesn't matter, the same with the semicolons.


They aren't needed at all. Semicolons in JS are optional.

Knowledge about how ASI works, on the other hand, is mandatory.


> They aren't needed at all. Semicolons in JS are optional.

So they're not really optional. What they are is necessary and if omitted the engine attempts to put them in automatically. The rules for automatic semicolon insertion are in section 7.9 of the ECMAScript 5 standard (http://www.ecma-international.org/publications/files/ECMA-ST...).

This means you're omitting something that is required by the engine but not necessarily required in the syntax which boils down to you losing control of where semicolons end up possibly making your code do something you did not intend because you either misunderstood the rules of automatic semicolon insertion or there was a bug in the syntax parser being used.


You're only "losing control" if you don't know how ASI works, which is well-defined in the ECMAScript standard.

Bad programmers that can't understand ASI will be also confused by the floating point semantics, promises and other basic concepts — there are many ways of "making your code do something you did not intend" in JS, but that's no excuse for bashing language features.

Fact check: ASI is a fully legitimate part of the language (as in, it's in standard, it's documented, and supported across the board), so demonizing it is every bit as silly as e.g. deprecating C macros.

Learning the language helps with the the issues you outlined, while magical thinking (uguuu, semicolons good, no semicolons bad, uguuu) for the most part doesn't.


> Bad programmers that can't understand ASI will be also confused by the floating point semantics, promises and other basic concepts — there are many ways of "making your code do something you did not intend" in JS, but that's no excuse for bashing language features.

This is a terrible attitude. There is no reason you may not understand every case in which a semi colon is automatically inserted but can still understand floating point, promises and other things. Automatic semicolon insertion isn't really a "basic concept"; it's a convenience for those who elide them and nothing more (the ECMAScript 5 standard even states this).

> Fact check: ASI is a fully legitimate part of the language (as in, it's in standard, it's documented, and supported across the board), so demonizing it is every bit as silly as e.g. deprecating C macros.

I'm not "demonizing" it but if you look at the standard the engine still requires semicolons it just fills them in for you if you miss them. This is vastly different than your deprecation of C macros example. Yes it's documented but it's non-obvious unless you've literally looked it up to learn it. I'm also not sure why you insisted on letting me know it's a "fully legitimate part of the language (as in, it's in standard, it's documented, and supported across the board" when I linked to the standard and stated exactly where to look for its definition...

> Learning the language helps with the the issues you outlined, while magical thinking (uguuu, semicolons good, no semicolons bad, uguuu) for the most part doesn't.

Sigh. Automatic semicolon insertion is only documented. There are no errors or warnings or other information. Many developers, who understand more advanced topics, may not even know about it. The language does nothing to help with this. It's far better to be more explicit than assuming everyone who looks at your code understands the full ECMAScript 5 standard.


It's the same reason that, yes, you can put "var x" in an if-block, but it's bad practice because it misleads the reader (even one who knows that Javascript is function scoped) into thinking that x is block-scoped.


I'm almost embarrassed to say it took me way to long to realize JavaScript wasn't block scoped.


Same here! It's probably the norm, honestly.

Javascript never should've had C-like syntax if it was to have the feature set it does. Its syntax descends from a tradition of languages that have none of its actual features. Most other C-like languages have block scope[0]. So the syntax PLUS the terrible, awful, no-good very bad name lead you to believe it's more-or-less dynamic Java, when nothing could be further from the truth.

[0] ...and require declaration before usage, and have sensible 'this' semantics, and are class-based, and have function parameters that are more than just syntactic sugar, and have ACTUAL arrays, and...


They 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.


In the worst case, you can do something along the lines of

    [file1, file2, file3].join(';\n')
albeit if you're using any kind of post-processing tool, like UglifyJS or Google's Closure compiler, then everything just works, as these tools actually parse JavaScript. There's usually no need to explicitly concatenate the code prior to minification or other processing.


FWIW John Resig himself originally wrote jQuery without semi-colons but it caused all sorts of issues very quickly!


>> Tries to play it cool by wrecking jQuery?

> not sure exactly how he's "wrecking jQuery"

The grandparent is misguided, but I believe they mean using '$' as the QSA. The grandparent probably uses script tags and globals in which case there would be a conflict if a script tag library requires window.$.

JS modules should var $ = require('jquery') (or equivalent) and then use the $ in their local scope if they need jquery.


IIRC, there is a jQuery global object available.. you can assign it to a local variable inside in iife, which is the appropriate way to use jQuery when writing a module...

    (function(window,$){
      //module code goes here
    }(this.self || this, jQuery));
In this way, you are keeping jQuery itself and your implicit scope assigned to localized variables.

If you are writing a modern module (not necessarily jQuery based), then following node/cjs conventions is probably best. If you use this convention with such a plugin, said module should probably return the jQuery object that has been modified, and extra care should be taken that all plugins are using compatible/same instance of jQuery.


What modules? You mean CommonJS or was it AMD or ECMAScript 6? Still a straw man IMHO :-)


CommonJS, since npm (which is mainly commonjs) is a few hundred/thousand times larger than the whatever else.


Actually semicolons are necessary. For example, try writing a rather simple script wrapped and stored in a Chrome bookmarklet without inserting semicolons and see your 100% working script crumbles under the weight of all those unexpected exceptions.


How is he hipster? Oh, he is. This very snippet shows how regrettably hipster the web development scene has become. It's all trend-driven. And particularly Paul, as popular as he is, should be real carefuly about his opinions, because he's a trend-setter. The moment he says jQuery is useful (like here https://docs.google.com/document/d/1LPaPA30bLUB_publLIMF0Rlh...) many developers will think likewise. The moment he spits this utter crap despising jQuery, many developers will, again, adopt the same opinion without hesitation.


You're not backing your comments with anything. "Oh this is hipster because I say so", hehe, alright dude


jQuery was and still remains useful... Were you missing a "/s" from the end of your statement?


I'm using standard [1] for style. I love semicolons too, but am giving it a go without them here. TBH, it feels kinda weird, and I'll probably end up on semi-standard [2] in the end.

[1] https://github.com/feross/standard [2] https://github.com/Flet/semistandard


jQuery the useful parts.


Let’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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: