O'Reilly

MooTools 1.2 OpenLinks Plugin

By on  

I often incorporate tools into my customers' websites that allow them to have some control over the content on their website. When doing so, I offer some tips to my clients to help them keep their website in good shape. One of the tips I tell my customer is "whenever you create links to PDFs, Excel XLS', Word DOCs, or JPG/GIF/PNG images, make the link open in a new window." Unfortunately, my customers don't always follow this guideline.

In an effort to correct their mistakes, I've created a MooTools class that analyzes links on the page and adds a target attribute when necessary.

The Usage

window.addEvent('domready', function() {
var olinks = new OpenLinks(['doc','pdf','xls','jpg','gif','png'],1,'_that_window','no-target');
});

The class takes four arguments:

  • file_extensions: an array of file extensions you would like to open in a new/specified window. Add file extensions without the '.' and lower-cased.
  • override_targets: boolean, representing whether you want an anchor's "target" attribute to be overidden
  • target: string, defaults to "_blank" if none provided
  • no_class: if you don't want a link's target attribute set, add your custom class to those links.

As you can see in the code example above, I want the following file extensions to open in a window named "_that_window": Word DOCs, PDFs, XLS files, JPGs, GIFs, and PNGs. Links with the class no-target are not modified, even if the file extension is a match.

The Moo JavaScript

var OpenLinks = new Class({
//initialization
initialize: function(file_extensions,override_targets,target,no_class) {

//analyze all anchors
$$('a').each(function(el) {

//check each href for case-insensitive file extensions
var str = el.get('href');
var ext = str.substring(str.lastIndexOf('.') + 1,str.length)
if(file_extensions.contains(ext.toLowerCase()) && ((override_targets || !el.get('target')) && !el.hasClass(no_class + '')))
{
el.setProperty('target',target ? target : '_blank');
}
});
}
});

The Flow

For every link in the document, I extract the file extension. If the link's file extension is in the array of marked file extensions...and the link's target can be overridden or the link doesn't have a target set...and the link doesn't have the specified class...the link is then modified. It's that simple!

Click here to view an example of the class in use.

Click here to download the class in an external .js file.

Note

I'd initially built the class to use more specific CSS selectors:

a[href$='.pdf'], a[href$='.jpg'], a[href$='.doc']//...

The problem with doing this is that the above method doesn't allow for case-insensitiveness. For example, "pdf" would match but "PDF" would not.

Update

MooTools dev digitarald caught wind of my class and coded the following JavaScript to make the class' code a bit shorter:

// a lovely fast case-insensitive regexp build from file extensions
var rex = new RegExp('\\.(?:' + file_extensions.join('|') + ')$', 'i');
 
// href und target sind native properties for links, no get() needed
// no_class is now a required parameter
target = target || '_blank';
 
$$('a[href]:not(.' + no_class + ')').each(function(el) {
  if ((force || !el.target) && rex.test(el.href)) el.target = target;
});

Thank you dig'!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

  • Animated 3D Flipping Menu with CSS

    CSS animations aren't just for basic fades or sliding elements anymore -- CSS animations are capable of much more.  I've showed you how you can create an exploding logo (applied with JavaScript, but all animation is CSS), an animated Photo Stack, a sweet...

  • 5 HTML5 APIs You Didn’t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

Incredible Demos

  • Firefox Marketplace Animated Buttons

    The Firefox Marketplace is an incredibly attractive, easy to use hub that promises to make finding and promoting awesome HTML5-powered web applications easy and convenient. While I don't work directly on the Marketplace, I am privy to the codebase (and so...

  • Element Position Swapping Using MooTools 1.2

    We all know that MooTools 1.2 can do some pretty awesome animations. What if we want to quickly make two element swap positions without a lot of fuss? Now you can by implementing a MooTools swap() method. MooTools 1.2 Implementation MooTools 1.2 Usage To call the swap...

Discussion

  1. Garrick

    Wouldn’t it be better to addEvent instead of adding a target attribute?

    Your method is just like adding the target attribute inline, which is not standards compliant.

    So you could do something like this instead:

    el.addEvent('click', function(e){
    (new Event(e)).stop();
    //plugin your own code in the open function.
    window.open();
    });
    
  2. @Garrick: I did things this way because people don’t always click on links. Inserting a target attribute makes the browser handle these links as they would had they been properly targeted.

  3. This is one of those cases where I struggle with “well, it validates, because I’m assigning the invalid stuff via JS”. Target’s been deprecated for awhile… so I shy away from using it, simply because there must have been SOME reason it’s frowned upon..

  4. @Andrea: Thank you for sharing!

  5. I personally never open links in new windows, ever. Jakob Nielsen agrees, with the exception of rich internet apps that demand a full, new browser window (and which omit standard browser controls like the back button). Otherwise, opening links in new windows should be at the option of the user.

    That being said, I appreciate that we sometimes must compromise for a client and your solution certainly is clean and to the point.

    Which particulars of your code are specific to MooTools 1.2? I’m going to write a series of articles comparing differences to the MooTools codebase between v1.11 and 1.2, and am curious if you’re using any 1.2-specific functionality in this code.

    Here’s the first article I wrote, which contains a brief overview of the additions/changes in MooTools 1.2:

    http://www.thetruetribe.com/2008/06/whats-new-in-mootools-12.php

  6. @Jonah: One of my biggest web pet peeves is when a PDF, DOC, or XLS file is not opened in a new window. You end up being done with the document, close the program, and realize you just closed your browser and all the tabs you had open. That inspired me to create this class.

  7. I see your point– it’s natural to hit the “x” to close a document when you’re finished with it, and can accidentally close the page you were on.

    After reading up on Jakob Nielsen’s alert box, it appears he agrees with you as well:

    http://www.useit.com/alertbox/open_new_windows.html

    Here’s what Jakob has to say about it:

    “Because users frequently close document windows, the best guidelines for linking to non-Web documents are:

    1. Open non-Web documents in a new browser window.
    2. Warn users in advance that a new window will appear.
    3. Remove the browser chrome (such as the Back button) from the new window.
    4. Best of all, prevent the browser from opening the document in the first place. Instead offer users the choice to save the file on their harddisk or to open it in its native application…”

    I think this is best for the majority of users, and power users can just override the browser’s new window functionality.

    Incidentally, to override target=”” links opening in a new window in Firefox, you can tweak the browser.link.open_newwindow setting in about:config — setting it to 1 opens target=”” links in the current tab, setting it to 2 opens them in a new window and 3 opens in a new tab (default).

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...