Saturday, July 19, 2008

AdBlockCheck

As mentioned in this post, AdBlock Plus did its job and blocked the AdSense and QuickAds code that was placed on this blog. The incident reminded me how it is easy to forget that AdBlock is installed because it works so well. It also got me thinking about ways to politely remind people that the ads on this blog are being blocked. Why remind readers? When I remember to, I disable AdBlock on sites that I frequent in order to support those sites. I’m betting others out there feel the same way and that, like me, they tend to forget that ads on a site are being blocked.

Let’s be clear: I have no issue with people blocking ads; the ads are not something the viewer is interested in so why waste the bandwidth and annoy the readers that don’t want them? Hell, I run AdBlock and Squid with content filtering on my home network.

Side note: It’s perplexing to me why spammers are against some form of a spam “no-call” list (see: now defunct Blue Frog project by Blue Securities), which would save them time and money by not wasting resources sending spam to addresses that would never generate revenue. It might even let spammers keep their open relays and ISP accounts alive longer since it’s likely fewer people would spend the time to complain or report them.

Problem Definition

There needs to be a way to remind people that they have ad blocking software running and ask that if they enjoy the content to please allow ads to display on this site. Whatever means this is accomplished through, the requirements are:

  1. Determine that ads are being blocked
  2. Remind the user that they are blocking ads on the site
  3. Only target people who are interested in the content
  4. Humanize the site/content (remind readers that a person sits behind these pages)
  5. Not be intrusive or annoying
  6. Not be blockable by ad blocking software
  7. Not obscure or prevent access to the content in any way

Side note: I consider obscuring or making the content inaccessible a very bad idea. I typically open a large set of pages in tabs before going to and leaving from work so that I have something to read on the train. There’s nothing more frustrating than running into a tab with the “Server Not Found” message. 90% of the time this is due to scripts that periodically reload the page or redirect to a “please subscribe!” page after a delay; something that fails when the computer is off-line. I’ve even had it occur while I was reading the page on the train. Please, if you have a site, try to be aware of the different ways in which your viewers may consume your content! Not everyone is online all the time or has a high-speed connection to download your heavy (but oh so beautiful!) pages.

The Solution

Determining if a browser is running ad blocking software is the easiest part. AdSense and QuickAds work by including a JavaScript library in a page. When this library gets loaded it inserts <iframe> tags wherever ads are supposed to show. Ad blocking software typically works by looking at the URLs the browser intends to load and cancels those URLs that match a filter. When an ad blocker sees the library URL for AdSense or QuickAds it prevents the loading of the library, which means that the <iframe> tags for ads will never get inserted into the page.

Checking for the existence of the <iframe> tags will let us know if the ads on a page have been blocked. The <iframe> tag for AdSense looks like this:

<iframe name="google_ads_frame" ...>

QuickAds looks very similar:

<iframe id="scribefire_ad_frame" ...>

Thanks to jQuery this <iframe> check is very simple:

if (($("iframe[name = 'google_ads_frame']").length > 0)
  &&
  ($("iframe[id = 'scribefire_ad_frame']").length > 0)) {
  return;
}

Requirement #1: Complete!

For messaging the user I settled on a modal dialog box. After much searching I could not find a jQuery plugin that had the aesthetics and behavior I was looking for. Casting a wider net, I did find a nice looking set of dialogs but the accompanying JavaScript left something to be desired. Here’s an example of the slick looking originals:

Starting with this dialog box design, I set about rewriting the behavior using jQuery and then wrapped it all up into a jQuery plugin (jquery.modaldialog.js), which has been registered in the jQuery plugin respository. The CSS was also redone so that the dialog width can be configured, the height will adjust to the content inside it, and the background mask and dialog will appear on-screen no matter where the page has been scrolled to. An optional close button was added to the bottom of the dialog body (with plans to add a more complete set of OK/Cancel/Yes/No button options and event hooks in the near future). This takes care of requirement #7 and most of #2.

To complete requirement #2 (remind the user), we need to have a message to display. Thanks to the nice jQuery plugin we now have, this is another simple task:

$.modaldialog.prompt(
  "<p>You've been on this page for a while now so you're either reading the post or maybe just off peeing or getting something to drink.</p>" +
    "<p>I also noticed you're blocking ads. Don't worry, I use AdBlock Plus too! But I do enable ads for sites I like (when I remember to).</p>" +
    "<p>This is just a personal request that if you like what you're reading, please consider allowing ads for this website. At the very least subscribe to the RSS feed!</p>" +
    "<p>Thanks,<br/><img src='http://static.transisted.com/img/chris_sig_sm.gif' style='margin-top:6px; margin-bottom:2px; vertical-align:bottom;' /> (Chris)</p>" +
    "<p><i>ps - You won't see this message again...</i></p>"
  , { title: 'A Friendly Reminder' }
);

Here’s what the final product looks like:

By signing my name at the bottom and including my signature I’m hoping to associate this content in the reader’s minds with a real, live person. I am, after all a real, thinking thing just as you, the reader, are (well, I assume; leave some comments or feedback to help convince me!). We can check off requirement #4 as well now.

Now that there is something to show to the readers, some rules are needed to determine when to show it. To start off simple, I’ve set this message on a timer so that it shows after 1’10”. This is long enough that it should only hit people who are actually reading the content. The timer delay is a one-liner thanks to jQuery:

$().ready(function () { setTimeout("checkAdBlocking()", 70 * 1000); });

Down goes requirement #3 (only target those interested in the content)! It also happens to address part of requirement #5 (don’t be intrusive or annoying). The other part is the setting of a cookie so that readers don’t get pounded with this message every time they read an article. Instead, they see the message only one a week/month/year, depending ont he cookie expiration date. jQuery has a cookie plugin (jquery.cookie.js) that makes quick work of getting and setting cookies. Setting the cookie is done like so:

$.cookie('adblock', '1', { expires: 30, path: '/', domain: '.transisted.com' });

Checking for the cookie is just as easy:

if ($.cookie('adblock'))
  return;

Now to wrap this all up into a set of JavaScript functions:

function showAdBlockMsg () {
  $.modaldialog.prompt(
    "<p>You've been on this page for a while now so you're either reading the post or maybe just off peeing or getting something to drink.</p>" +
      "<p>I also noticed you're blocking ads. Don't worry, I use AdBlock Plus too! But I do enable ads for sites I like (when I remember to).</p>" +
      "<p>This is just a personal request that if you like what you're reading, please consider allowing ads for this website. At the very least subscribe to the RSS feed!</p>" +
      "<p>Thanks,<br/><img src='http://static.transisted.com/img/chris_sig_sm.gif' style='margin-top:6px; margin-bottom:2px; vertical-align:bottom;' /> (Chris)</p>" +
      "<p><i>ps - You won't see this message again...</i></p>"
    , { title: 'A Friendly Reminder' }
    );
}
function checkAdBlocking () {
  if ($.cookie('adblock'))
    return;

  if (($("iframe[name = 'google_ads_frame']").length > 0)
    &&
    ($("iframe[id = 'scribefire_ad_frame']").length > 0)) {
    return;
  }

  showAdBlockMsg();

  $.cookie('adblock', '1', { expires: 7, path: '/', domain: '.transisted.com' });
}
$().ready(function () { setTimeout("checkAdBlocking()", 70 * 1000); });

End Result

To see the live dialog, click here

Example #1: Error dialog

Example #2: Warning dialog

Example #3: Success dialog

Example #4: Prompt dialog

2 comments:

CARL said...

See essay writing. Ad blocking software typically works by looking at the URLs the browser intends to load and cancels those URLs that match a filter. When an ad blocker sees the library URL for AdSense or QuickAds it prevents the loading of the library, which means that the tags for ads will never get inserted into the page.

Romano Capasso said...

Thank you for your excellent work , but the plug in doesn't work with Internet Explorer. There is some patch?

Bye bye