Many web pages force the link to open in a new window (or a new tab, collectively referred to as a new window below). Some people find this approach convenient, as it preserves the original page. But I don’t like this approach. Because I use Firefox, if I open a web page in a new window or tab, I can’t use the touchpad to swipe back to the previous page. Today, I’ll share with you the method to force the link to open in the current window or web page.
Before we share the method, let’s see what are the ways to make the browser open tabs in a new window.
The easiest way is to add the
target="_blank" attribute to all hyperlinks
<a>. This is also the most common way.
target to every
<a> tag is a bit wasteful, inconvenient to modify, and increases the size of the HTML file. One optimization is to add a
target attribute to the
<base> tag. Modifying the
<base> tag will affect all relative links. This means that this method only works for internal links.
The easiest thing is to assign
onclick callback function to each
<a> tag and call
window.open(url, '_blank') in the function to open the new page.
A slightly more optimized solution would be to register a
click' event handler for
document, extract the
href attribute of the
<a> tag based on the
target of the event, and then call the
open() function to open the new page. This solution requires the click event to
bubble to the
document node to work.
All of the above is done by changing the behavior of the
<a> tag to open a new page, and the
href attribute of the
<a> tag is the target link. However, some content platforms do not write the target URL to the
href attribute, but write the URL as a link shaped like
https://example.com?target=real-url. When users click on it, they will jump to an intermediate page first and then click twice to jump to the target page, which is very inconvenient.
I wanted a unified way to deal with several of these types of issues. The first thing I did was to use a Chrome plugin called Death To _blank. This plugin does a very simple job of removing the
target attribute from the
a tag. But it didn’t cover the remaining cases. Then I migrated to Firefox and couldn’t find a similar extension. I ended up using Tampermonkey script to achieve the full functionality.
The script framework is as follows.
@run-at document-end means that the script is run after the page is loaded, and
@match *://*/* means that the script is executed for all pages.
Then comes the real processing logic. The first step is to clear the
target attribute of the
Not all pages will have
<base> tags, so you need to determine that.
The next step is to clean up the
target attribute on each
<a> tag. But there may be a lot of hyperlinks on the page, and only a few of them will actually be clicked, or not opened at all. It would be a waste to iterate through all the links and clean up the
target attribute right away. For this reason, I use a delayed processing approach. Simply put, we listen to the
mousedown event of the
document and determine if the current node is an
<a> tag when the event is triggered. Some web pages embed images, in-line code and other tags in the
<a> tag, so the
target of the
mousedown event is not necessarily the
<a> tag. For this reason, we have to iterate through the parent nodes of the current node to see if there is an
The complete check logic is as follows.
If only the
target property is set, we can just clear it.
onclick callback is set or if the
document listens for all
<a> clicks, we can clear the callback and disable the
Be careful though, some pages may use
<a> as a button, usually its
href will be
#, so you need to skip this. There are also a few pages that do intercept
For those links with intermediate page jumps, we need to extract the target link and update the
Combine all functions to get the complete code.