Hacker Newsnew | past | comments | ask | show | jobs | submit | lyricaljoke's commentslogin

My very similar pet peeve is about websites that use `onclick` handlers and similar to implement navigation. Just use a damn anchor tag, which gets you correct link behavior for free:

* works with middle click for new tab

* integrates with accessibility devices

* works with right click + open in new window or similar options

* etc. etc. etc.

If it's notionally navigation, don't use javascript soup: use a link.


I've seen an increase in people doing this sort of thing over the past few years. I imagine it has something to do with frameworks and ignorance or apathy, but the old fashioned way almost always provides the best UX.

To anyone reading who has tried to get fancy with a substitute for the <a> tag, I wish you mild discomfort and inconvenience.


Could it be that the devs who write that code are not allowed to touch the CSS so they implement the visual functionality they want in their framework instead of telling the design team their intent?


There could be any number of weird constraints that would lead a developer who knows better to do such a thing in a specific situation, but someone designed (or failed to intentionally design) the system in question.

That person should sit alone in a room with no distractions and think about what they did.


No, it is because a significant subset of React developers do not know how to write HTML.


What's scary is that with proliferation of LLM-assisted code editors and vibe coding, and considering the training material for these models, this is only going to get worse and worse.


These people clearly don't care for mild discomfort and inconvenience already...


Yup. I think a lot of the devs that started with React jumped straight into the "fun" stuff without learning some of the "boring" fundamentals.

And those devs set the wrong patterns and standards for others following hot behind them. The only time I can remember needing to dress a div up like a button was when an accordion trigger was just a giant button and anything passed in would be rendered inside, but I needed an action to the right of the trigger title. But those happen super rarely. You can't just pass in a button as it was invalid html to have nested buttons obviously. Yes, I know I could probably use css to absolutely position it or something but that takes it out of the flow and starts hacking about it in another way.


This reminds me of Microsoft's website checker in Office 365.

Click a link with left-mouse, and it'll intercept the page with their safety checker (that doesn't work half of the time) before forwarding you.

But middle click? No safety for you.


Shush! That's a feature to avoid the 10-second mandatory wait on intranet links that their safety checker cannot possibly reach. :)


Also, get rid of JS based scrolling. I scroll a lot with pressing the middle mouse button. Too many sites break that.


Sites that bind the arrow keys so I can't use them to scroll with.


oh, 100% yes! The job project i joined somewhat recently is a moderately-complex React web app, and none of the navigation elements are actual links. Everything is done by onClick handling, even thought many things are, conceptually, just links. I have no idea why this kind of thing is so widespread on the web front-end world.


We've reached the point, years ago even, where image hosting sites will not show you an image without JavaScript, even. Just use a damn img tag.


If they link to the image directly, it makes it easier for users to share that link directly. We cannot have that, so instead we get a web page using exabytes of JS to show the image and a bunch of ads.


I wonder why browsers don't intercept JS-triggered navigation (or history.push) events that happen with a click handler on the stack — where it can be determined from the event data of that click handler that the user additionally used the middle mouse button or was holding cmd/ctrl at the time — and rewrite them into navigation-in-new-tab. (Ideally, without making the caller aware that anything different happened than what it was expecting.)

It might not be what the developer of the site/app intended; but it's exactly the semantics the user is expressing their desire to trigger. So why not do what the user wants? Browsers are user agents, not developer agents, after all.

(Before you say "that sounds like a layering violation" — well, yes it is, but that particular layering violation already exists to support most browsers' JS engines' "suppress popup-window / new-tab navigation if the stack of the navigating call doesn't contain a click event" logic. The code ugliness was already bought and paid for; we may as well reap as much benefit from it as we can!)


> it's exactly the semantics the user is expressing their desire to trigger.

That’s not necessarily true. You could imagine writing perhaps a video game or something where this control is intended to have a different meaning. For this reason, I don’t think this is a liberty that browser developers can take.


Vivaldi recently took liberty to "restore" a scrollbar to the body tag of my app even though I had intentionally moved it to an inner div. It royally effed up my app with no workaround.

Their intentions were good, but.. you don't know what devs are going to do. As long as they're following spec, let them. Users can vote with their wallet or eyeballs.

NB: I don't want to throw too much shade at Vivaldi. I reported it. They fixed it. Still my fav browser


Keep in mind that this check+logic would only come into play within the call to `history.push` or the `window.location.href` setter.

It's not "add a browser-default click event listener that shims in special behavior" (which wouldn't be able to catch the JS navigation in the first place, since that would be occurring in its own, separate click event listener.)

It's instead "when I-the-browser have been called by page JS to do something navigation-like through the native `location` or `history` APIs, first check if the current call stack has a event-listener call triggered by a browser-delivered click event in its ancestry. If it does, check further whether the click was a "special" [middle-mouse-button / shift / ctrl-or-cmd / alt] click. If it was, then cause some other side-effect depending on the "special" modifier [i.e. open the target URL in a new tab, or new window, or download it] while silently failing to actually navigate this tab. Otherwise, proceed with the original semantics of the native `location` / `history` API call that was made."

If your game isn't specifically trying to have middle-clicking / ctrl/cmd-clicking navigate the tab, then this check+logic would never fire.

---

That being said, in theory, if you bound a listener to `auxclick` and told it to `e.preventDefault()`, that should maybe tell the browser you're doing something special and different where the middle-mouse button isn't just "the left mouse button with extra flags set", and therefore that navigation triggered via the middle mouse button shouldn't be seen as "navigation triggered via the left mouse button with extra flags set."

I say in theory because web developers would probably use that to prevent people from opening their site/app in multiple tabs at once. And the whole point here is that people should be able to do this whether web developers like it or not.

--

Also, a tangent:

Web developers may have what are, to them, good reasons for preventing the user from opening their page/app in multiple tabs.

For instance, each instance of a page/app on their site might open its own persistent websocket connection to their backend, and so having O(N) tabs open to their site means O(N) websocket connections. And if many users do that, their backend falls over.

Or each instance of the page/app thinks it has exclusive ownership of a local IndexedDB, and so might try to migrate the data in a non-atomic way at any time; where if other instances of the page/app are also running and accessing the same DB, they might blow up, or do the same thing and corrupt the DB.

(I've seen both of these in practice. In fact, I believe Reddit [in its new design] does the former; at around ~100 open Reddit tabs, they all crash! [I think it has something to do with their chat system.])

IMHO, any webpage that can't stand being open multiple times simultaneously is badly architected. Such pages have been "coddled" too long by browser vendors, by allowing devs to mostly disable the user's ability to easily open links as tabs. We should stop coddling these pages.

If we give users back the ability to easily open tabs on modern websites, we'll see the owners of these sites finally [probably begrudgingly] fix the problems that cause them to want to disable opening things in tabs in the first place.


I tend to open most links with a right click and then the first menu option: "Open link in new tab", and done so fast enough that I have not actually read the menu. But when the "link" is not a link but just an image, I have then instead clicked on "Open image in new tab".

This has especially been annoying when I have happened to use DuckDuckGo's image search instead of Google's or Bing's and instead of having opened ten tabs with links, I have ten tabs with a thumbnail in each ...


In case you want to save a few seconds of your life, you can also middle click or ctrl click instead of right clicking + left clicking on the menu.


...Except on websites that override this to make those links open in the current tab, or just silently fail.

On the modern web, the menu is more reliable.


You forget the most important part. When you inevitably screw up and break things it is nearly impossible to create enough garbage html to stop the anchor from doing its job.

Click handlers however may stop working if there is even the smallest typo or error far away from the code.

It won't just be that one link. Everything stops working everywhere on the site.


Yes! If it's clickable, it should either be a button or a link.


there are plenty of other vanilla html elements that are clickable. <details>, <input type=[button|checkbox|radio|file|etc]>, <label>, <select>, etc


True although the built-in click behavior is sufficient on these, ie you should not need to add onclick. Which should be for <button> and <a>


when i was doing .net programming way back in the day asp.net handled each navigation with a javascript event and it broke all that stuff. this was right before ruby on rails existed so maybe it’s better now.


This was specific to Web Forms, a now-deprecated framework that did a lot of implicit state management that necessitated POSTing to the server with an encrypted client-side state called the ViewState.

Its modern replacement ASP .NET MVC works much more like traditional web frameworks.


I actually found that particular response to be quite disappointing. It should give pause to those advocating removal of XSLT that these three totally disparate use cases could already be gracefully handled by a single technology which is:

* side effect free (a pure data to data transformation)

* stable, from a spec perspective, for decades

* completely client-side

Isn't this basically an A+ report card for any attempt at making a powerful general tool? The fact that the suggested solution in the absence of XSLT is to toil away at implementing application-specific solutions forever really feels like working toward the wrong direction.


Many of the responses to this comment imply that this is something fundamentally different than perfect pitch and give it some different name ("pseudo absolute pitch", "perfect relative pitch", etc.). While I concede that most people think of perfect pitch as something that is instilled in some way in early childhood rather than achievable through practice, I guess I would ask those commenters... why do you think the latter is fundamentally different, or is using some separate mechanism?

There are many skills which are much easier to instill in early childhood and are simply harder to master if approached in adulthood -- language learning, certain athletic skills, and more -- but we would never consider any of these impossible to achieve through study. Sure, maybe the maximum achievable skill level is less than what could have been possible if study began in early childhood, but we would not say that it is impossible for adults to achieve a level of mastery, or that those who gained a skill through serious practice must be using some separate mechanism than those who learned it in early life.

I contend that it is the same with absolute pitch. After all, there is not even a perfect level of absolute pitch mastery! In layman's terms, "perfect pitch" is usually understood to mean that a person can immediately name a pitch when played -- on a 12-tone western music scale. But some people people with perfect pitch have better precision than that and can estimate quarter tones, etc. If a note is played that's 20 cents sharper than Ab, and person #1 says "that's an Ab" while person #2 says "that's a note a touch sharper than Ab", most people consider neither statement to disqualify them from having absolute pitch. But there is a difference. Moreover, no person on Earth can name a pitch down to, say, a couple decimals of absolute frequency value. Doesn't this imply that the skill exists as achievable points on a spectrum, not as a flat binary?


In fact, there is an interesting historical anecdote about polish-american pianistic prodigy Josef Hofmann related to absolute pitch:

"Josef startled musicians by the accuracy of his ear. Once, at the Metropolitan Opera, he heard a tuning fork supposed to be at 440-A. Josef said it was a shade sharp, and it was."

This is incredibly impressive for two reasons:

- It shows absolute pitch is not necessarily limited solely to semitone identification

- A pure tone from a tuning fork doesn't have any of the characteristic overtones, timbre, etc. that you'd get from an instrument to help identify the sound


- It shows absolute pitch is not necessarily limited solely to semitone identification

Why would it be? There's nothing fundamental about a semitone. It's an arbitrary division that varies across different musical systems.


I'm not saying that it is but MOST people when they think of perfect pitch - they think in terms of note identification (e.g. semitones), A, A#, etc.

My point was more about how everyone's ability falls along a "Hz Range Level".


I imagine the gold standard of perfect pitch would be identifying exactly how many cents sharp or flat a given sound is--you could tune a piano by ear if you had that.


You can tune a piano by ear by listening to the beating. You need one note to be tuned according to a given reference but that reference doesn't have to be 440 hz


I personally do believe that there is something fundamentally different about perfect pitch perception, and think of it more like discussions around aphantasia or maybe synesthesia. I followed along with this guy's research years ago on his quest to understand and obtain perfect pitch [0] and was pretty obsessed myself. I had a number of friends with perfect pitch and would do random experiments and quiz them ("ooh, you're drunk, can you tell what note this is?" etc).

From that link:

> For the same reason, absolute listeners do not perceive pitch "height". They do not perceive pitches as "higher" or "lower" or physically "next to" each other. As musicians, of course, absolute listeners learn that, metaphorically, pitches are "higher" and "lower" than each other, because they can see these relationships on a page of sheet music. They also learn that, theoretically, "distance" between notes exists, because you can count the semitones that separate them, and you can see the "distance" between keys on an instrument. But, to an absolute listener, neither "height" nor "distance" has any direct perceptual reality.

> For example, when a non-absolute listener hears a guitar slide, we literally hear something moving down. But an absolute listener's experience is nearer to the color-changing rectangle above. They hear a series of discrete pitches, changing—not moving—from one to another. Although they know the sound has "descended" from their knowledge of the musical scale, the sound does not give them a literal experience of downward movement as it does to non-absolute listeners.

The link has a gif of a box moving through the color spectrum which helps understand the point.

[0] http://www.aruffo.com/eartraining/


> While I concede that most people think of perfect pitch as something that is instilled in some way in early childhood rather than achievable through practice, I guess I would ask those commenters... why do you think the latter is fundamentally different, or is using some separate mechanism?

As soon as having learned some relative pitch, it becomes very difficult to train absolute pitch. One single note a day. For the second note the brain will switch to relative mode, and there's no progress on absolute. Forcing the ear/brain to run in absolute mode seems possible, but is difficult consistently enough to practice absolute.

Source: Experimenting with my own ability (or lack thereof).


Judging by the non-C scales, obviously it just loves Mixolydian mode :)


"A good ear" and grasp of music theory go hand in hand. Strongly disagree that the latter is limited to classical music. The best musicians in jazz and pop music absolutely know how to incorporate the circle of fifths, types of cadences, Roman numeral harmony, etc., in their playing. That's... music theory! While there are musicians who can make it without that, they are the exception, not the rule.


Indeed, "theory" is not an all-or-nothing affair. There's a level of "theory" that's just learning why certain intervals are harmonious in the 12 tone system, and the names of things. I certainly learned those things, but if asked whether I know "theory," my answer is no. Virtually everything I know about harmony in jazz is due to hearing and recognizing recurring patterns.

In my case, I've gotten through 40 years of performing with jazz groups, so in some sense I'm doing OK, but I also know that I struggle with ultra-modern jazz harmonies. This came into pretty sharp relief when I played with some musicians who were composing all of their own tunes. I reach the end of my mental map, and then I have to fake it, or improvise directly from the melody.

But I agree that "ear" and perception of harmonic structure are closely related. It's hard to describe, and might make a psychologist cringe, but a musician develops a "mental ear." And I wouldn't recommend my approach to a young player. Most people want to become proficient in fewer than 40 years. ;-) There are things I can't do. I can't compose or arrange anything worth playing. Without exception, every musician I've played with who could compose or arrange decent jazz material has a music degree.


This is a bit like saying that all the best speakers know a lot of grammar. Maybe they do, but that’s not why they are able to put together complete sentences, let alone why they are able to move an audience with a speech.


Some of the best Jazz pianists started out as classical pianists. Friedrich Gulda for instance, and Keith Jarrett.


On the contrary; it's quite possible to design automated tests that operate on release artifacts. This is true not only at the integration level (testing the external interfaces of the artifact in a black-box manner), but also at a more granular level; e.g., running lower-level unit tests in your code's dependency structure.

It's true that not all tests which are possible to run in debug configuration can also be run on a release artifact; e.g. if there are test-only interfaces that are compiled out in the release configuration.

I think maybe the source of the confusion in this conversation is perhaps the kind of artifact being tested? For example, if I were developing ffmpeg, to choose an arbitrary example, I would absolutely have tests which operate on the production artifact -- the binary compiled in release mode -- which only exercise public interfaces of the tool; e.g. a test which transcodes file A to file B and asserts correctness in some way. This kind of test should be absolutely achievable both in dev builds as well as when testing the deliverable artifact.


I develop multi-platform C and C++ code (intermingled with some python for testing and automation), and my experience has been that while MSYS + Git Bash works, I run into 'rough edges' on that side much more frequently than on the WSL side.


The exemptions were very imperfect. Even if musicians and certain types of performers were exempted, this legislation has had an enormous effect on theater organizations, for example, especially at the semi-professional / community level. It's typical for these orgs, which have very limited budget, to hire actors and the creative team (set designers, lighting designers, sound etc.) as 1099 workers. The money is simply not there to be able to pay everybody at an hourly rate for the amount of time that's actual spent on these projects, and the outcome has been that many theater companies are unsure whether they can continue to operate at all. Unless the thinking has changed recently and my understanding is out of date, this is a situation that continues to be worrying to both theater artists and directors of theater orgs.


I call it “crying wolf in reverse”

Isn't that just normal "crying wolf"?


Or, arguably, the C++ equivalent is just the destructor. 'Defer' and 'ScopeExit' are interesting, but I'm not sure if I see the advantage over widely understood first-class language features. If you don't want to write a class just to get cleanup logic at scope exit, consider using std::unique_ptr with a custom deleter -- this construct is for managing resources in a general sense, not necessarily just memory allocation.


> arguably, the C++ equivalent is just the destructor

You'd have to define an empty class with a destructor, then instantiate the class at the appropriate place in your code. The point of Boost.ScopeExit is to handle that boilerplate for you.

> I'm not sure if I see the advantage over widely understood first-class language features

The advantage is simply reduced boilerplate. You're right that it's 'less standard' and more likely to baffle the reader, if they're not already familiar with ScopeExit.

> consider using std::unique_ptr with a custom deleter -- this construct is for managing resources in a general sense, not necessarily just memory allocation

This strikes me as hijacking a memory-management facility, using it for a different purpose than its intent. That's bad for readability. I'd prefer either ScopeExit or the dummy object pattern I described.


>You'd have to define an empty class with a destructor, then instantiate the class at the appropriate place in your code. The point of Boost.ScopeExit is to handle that boilerplate for you.

I would argue that every time you want to execute something on scope exit, that essentially models a resource or lock of some kind. Which means the constructor wouldn't be empty (it would acquire the resource), and writing the class wouldn't really be "boilerplate", it would be clean design.

>This strikes me as hijacking a memory-management facility, using it for a different purpose than its intent. That's bad for readability. I'd prefer either ScopeExit or the dummy object pattern I described.

I think it is much better for readability, because it usually models the thing you want to do much more precisely. Although it is a shame that only unique_ptr is standard and not unique_handle, but you could write that yourself relatively quickly. This case doesn't just model that you want to execute something at the end of a scope, but that you have a handle to a resource that you can std::move around and that will get destroyed at the appropriate time (if you model your data correctly).


> essentially models a resource or lock of some kind

I agree that proper RAII is generally the way to go. I think of ScopeExit as being for those situations where you have to deal with C-style code. One way is to wrap the C-style code in C++ and leverage C++'s RAII. The alternative is to write C-style code yourself, but you can still use ScopeExit to ensure you didn't miss any edge-cases where cleanup is necessary (multiple points of return, exceptions, etc).

In this way, ScopeExit is for 'C++ as a better C' programming.

> This case doesn't just model that you want to execute something at the end of a scope, but that you have a handle to a resource that you can std::move around and that will get destroyed at the appropriate time

This is going far further down the C++ rabbit-hole than what we started with, though. If I just want to be sure that I didn't miss any places where I need to call free (or similar) in my C-style code, ScopeExit is just the thing.


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

Search: