Something seems fundamentally wrong here. If I middle-click or ctrl-click on a link, the browser shouldn't allow the site to interfere with that, accidentally or otherwise. Those shortcuts represent part of browser chrome, just like the shortcuts for the URL bar, the search bar, and the back button.
It's not that pushState() apps interfere with middle-clicking on links, it's that they have no real links to middle-click on. Common practice is to have a <div> or <span> (or maybe <a> without an href) styled to look like a link/button, then onclick run some code that performs a task and changes the URL with pushState(). This article suggests making your pushState() "links" actual links to the desired URL, then overriding the unmodified click case to run the desired code rather than fetch a new page from the server.
I understood that much, and sure, if you try to construct browser links from scratch then their behavior won't match the behavior of real browser links. However, if you really do have an <a> tag, then you should only have the ability to override the "unmodified click case".
I read the article as simply suggesting that developers create real, genuine <a>-tag links in their modern pushState-using web apps. Doubtful that there are enough people specifically overriding middle-clicking on links to warrant a blog post.
For example (and not to call anyone out), there's this demo (warning: will fill your history): http://bodytag.org/rollstate/
Looking at its source, it uses real <a> tags for its pushState() links, but with href="#". If you click on "contact", then middle-click "about", a new tab will open to "/rollstate/contact" (which 404s, another pushState() no-no).
i assume this is much like the js-driven crap that's been around for over a decade now where the mouseover text looks real but the actual href is "javascript:void(0)" or something?
Some of your points are quite valid, but I must disagree progressive enhancement & unobtrusive JS are “dead” or should be.
> - you can make significantly better UX without them
This is the biggest place where you’re wrong, as the examples of right-clicking or middle-clicking a “div with JavaScript” plainly illustrate.
Now obviously complicated web apps can’t work 100% or sometimes even 10% without JavaScript, but when reasonably possible, using progressive enhancement & unobtrusive JS will increase your compatibility across UAs, search engines, and other agents, and will avoid cases where your site seems broken in some crucial way.
Not to mention users with accessibility needs will do much better interacting with your `<a>` tags than scripted `<div>`s. Have we forgotten about them again, already?
Edited to add: Biggest tips w.r.t. accessibility: (a) Spend an hour using a screenreader and no mouse — e.g. VoiceOver, which comes with your Mac and works just fine in Safari. (b) Using semantic tags & progressive enhancement means your code will make the most sense to the screenreader — e.g. you will be able to tab onto your button/link because you actually defined it as one — and it will be described fairly accurately. Your "clickable" <span> is plainly going to be trickier for a screenreader… (c) Read up on WAI-ARIA, which lets you define roles for certain elements (like "notification" or "button"). If you want to make your AJAX work well for those with accessibility needs, this becomes fairly important as it can also help you manage focus and direct user attention.
Certainly, there's the right way and the wrong way, but don't throw the baby out with the bathwater. It's still early days for pushstate apps, and they have yet to get their "Rails moment". Middle-clicking problems and the like are inevitable. (Do you remember sites used sessions to remember where you clicked, so tabs didnt work at all? This too shall pass).
You say progressive enhancement helps you out in all these cases, but I just see opinion, and very little evidence. So all I have to offer you in rebuttal is the same - I believe the opposite.
I agree about accessibility. I frankly don't know what to do there. On the one hand, I hate the idea that I might be excluding somebody. On the other hand, I tend to implement things lazily, so if I'm never asked for a feature, I probably won't do it.
Please don't put words in my mouth, and please don't immediately assume the very worst interpretation of what I say.
For example, when I said "there is business value to usable apps", I actually didn't imply "there is no business value to casting a wider not". To say nothing of your "quick buck" comment.
It's dishonest to play tricks like this, so I would ask you to rewrite your comment as if your target audience was an intelligent human being looking for an intelligent discussion.
"there is business value to usable apps" didn't fit into the tone of your post, so I hope you can forgive a bit of unintentional creative interpretation (one word). I made no attempt to play tricks.
The rest of the post was simply a point-by-point dissection. None of your other points are valid. The only somewhat valid argument I hear against proper browser compatibility is "we don't have time", which is usually a self-inflicted wound.
Stable web pages that gracefully degrade are fully possible, even today. I wrote a unit test that degrades in IE 5 this week.
Really, it seems like a middle-click should just be a sent as a regular click event to Javascript, but with all document.href edits and window.open calls redirected to act on a new tab.
Middle-clicking is taken directly by the browser. Cmd-clicking can be overridden by click handlers. Both left- and right-clicking can be overridden, so that is at least consistent.
I agree with your sentiment in general but I think this is a case where Javascript's control is justified. What if you had a game in which ctrl-click moved a group of units?
Then don't use an <a> tag, and you can capture more types of events. :) But when a page uses a link, the browser should ensure that it behaves like a link, including the ability to determine whether that link opens in the same tab/window or a different tab/window.
Or, more generally, you could request additional permissions from the browser; see the recent specifications for mouse capture and gamepad use.
Your post brings up a great point, and I hate it when I can't open links in new windows (Harvest invoice/estimate list, I'm looking at you!). But I wonder if there's a way to handle it in a more abstract fashion -- in the sense that you let the browser tell you if a link is to be opened in a new window/tab, as opposed to hardcoding various keyboard buttons.
For example, does your technique handle middle-clicks (clicking on the middle mouse button, which is equivalent to shift-clicking)?
On a Mac, middle-click is not exactly the same as Cmd-clicking. Middle-click can't be overridden, Cmd-click can. On my site, middle clicking works fine, but I have to put in a hack to make Cmd-click work.
raised my eyebrows. Yes, it makes sense. But the `rel` attribute is not to be used lightly and values are not to be invented on a whim, because eventually the value can be defined for all sites, not just yours.
Without thoroughly researching it, it looks like `rel=internal` is not standardized. That means you should not use it!
Instead, consider:
<a href="/page" data-push-state="push">Foo</a>
and
jQuery('a[data-push-state=push]')
The data-* attributes are explicitly defined as open for your own invention and use.
Great suggestion, thanks! I just updated the blog post with. I'll be happy to link to your site/twitter at the end of the post if you give me that information :)
The author is very right. The links on my site (https://circleci.com) don't work if you middle-click them. Some kind StackOverflow users found the problem, which appears to be the click handler in Sammy.JS.
A lot more info about this is in the question, an the links from it, including history, Mozilla accessibility discussion, and code samples:
I'd argue the majority of the time hashbangs should be used over pushstate. Until HTML5 is the norm (>99%, so basically never) there isn't much reason to use pushstate. I know this is not what this article is about so I'm not going to go into detail.
Wow, I feel really stupid. I had no idea that the browser let JS override the default on regular <a>'s with onclick handlers with modifier keys.
No wonder so many gdamn sites get it wrong. Nothing infuriates me more than whichever lightbox implementation always sieves control of my ctrl+clicks and then doesn't allow me to view the picture in a larger size. Infuriating.