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'!

Recent Features

  • By
    Designing for Simplicity

    Before we get started, it's worth me spending a brief moment introducing myself to you. My name is Mark (or @integralist if Twitter happens to be your communication tool of choice) and I currently work for BBC News in London England as a principal engineer/tech...

  • By
    Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

Incredible Demos

  • By
    Redacted Font

    Back when I created client websites, one of the many things that frustrated me was the initial design handoff.  It would always go like this: Work hard to incorporate client's ideas, dream up awesome design. Create said design, using Lorem Ipsum text Send initial design concept to the client...

  • By
    PHP IMDB Scraper

    It's been quite a while since I've written a PHP grabber and the itch finally got to me. This time the victim is the International Movie Database, otherwise known as IMDB. IMDB has info on every movie ever made (or so it seems). Their...

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!