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

  • Chris Coyier’s Favorite CodePen Demos

    David asked me if I'd be up for a guest post picking out some of my favorite Pens from CodePen. A daunting task! There are so many! I managed to pick a few though that have blown me away over the past few months. If you...

  • Create a CSS Flipping Animation

    CSS animations are a lot of fun; the beauty of them is that through many simple properties, you can create anything from an elegant fade in to a WTF-Pixar-would-be-proud effect. One CSS effect somewhere in between is the CSS flip effect, whereby there's...

Incredible Demos

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

  • Open Files from Command Line on OS X

    I'm as much of a fan of application UIs as anyone else but I'm finding myself working more and more from the command line lately.  Much of that is becoming obsessed with media manipulation but I'm forcing myself to use less UIs so that I...

  • Get Stock Quotes From Command Line

    When I conned my way into my first professional programming gig, I didn't really think much about money -- just that I was getting my foot in the door.  But as my career has gone on, I've been more aware of money, investing, and retirement.  I've recently...

  • Geolocation API

    One interesting aspect of web development is geolocation; where is your user viewing your website from? You can base your language locale on that data or show certain products in your store based on the user's location. Let's examine how you can...

  • Create an Image Preview from a Video

    Visuals are everything when it comes to media.  When I'm trying to decide whether to watch a video on Netflix, it would be awesome to see a trailer of some kind, but alas that isn't available.  When I'm looking to download a video on my computer,...

  • New:  Webdesigner News!

    A new and exciting website has recently been launched for web designers and developers. You likely spend hours every morning browsing through hundreds of posts on your RSS feeds, hoping to stumble across relevant stories. Webdesigner News was built to provide web designers and developers with...