Javascript: array.indexOf() fix for IE8 and below

Just a quick note on how to deal with another one of the IE/Javascript deficiencies that make our lives so much easier(!) – IE from versions 8 backwards doesn’t support the indexOf() function for arrays, e.g.

var myArray = ['Apple','Banana','Orange'];
alert(myArray.indexOf('Orange'));  //alerts '2', but not in IE <=8

Thankfully, there are easy ways to fix this:

  1. the JQuery $.inArray() function, e.g.
    alert($.inArray('Orange',myArray);
  2. Defining the indexOf function (before you call it!) if it doesn’t exist – taken from MDN
    if (!Array.prototype.indexOf) {
      Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
        'use strict';
        if (this == null) {
          throw new TypeError();
        }
        var n, k, t = Object(this),
            len = t.length >>> 0;
    
        if (len === 0) {
          return -1;
        }
        n = 0;
        if (arguments.length > 1) {
          n = Number(arguments[1]);
          if (n != n) { // shortcut for verifying if it's NaN
            n = 0;
          } else if (n != 0 && n != Infinity && n != -Infinity) {
            n = (n > 0 || -1) * Math.floor(Math.abs(n));
          }
        }
        if (n >= len) {
          return -1;
        }
        for (k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); k < len; k++) {
          if (k in t && t[k] === searchElement) {
            return k;
          }
        }
        return -1;
      };
    }

Preventing IE from caching Ajax requests

We are increasingly using AJAX (Asynchronous JavaScript and XML) to deliver content on our pages, but often have problems due to Internet Explorer, every web developers favourite browser, caching AJAX requests. This means that the results presented are not updated when a new request is made to the same URL, even if the data has changed.

This is annoying, but does not go against the HTTP specification, which states that GET requests are cacheable, whereas POST results are not. AJAX requests seem to generally default to GET (JQuery certainly does), so IE caches them.

Therefore, the solution is to make sure that AJAX requests use POST rather than GET. In jQuery, you can do this by setting:

type: 'POST'

For Prototype, you can set:

method: 'get'

In the jQuery.ajax() method, there is also a ‘cache’ setting, which is true by default, but can be set to false, which prevents caching. It does this by appending a TIMESTAMP to the URL, so that each request is made to a different URL, so a cached result cannot be returned. If not using jQuery, an alternative to ensuring that your request is a POST request rather a GET request is to add a ‘cache-busting’ parameter, e.g. a timestamp, to the end of the request URL, e.g.:

var cacheBuster = new Date().getTime();  //Get timestamp
var url  = 'http://www.example.com/getdata?cb=' + cacheBuster;  //Add timestamp to URL

CSS – display: inline-block in IE7

I was having some problems with getting the layout of the buttons for the JQuery Tools Scrollable Navigator plugin to work in IE7 for CSlide, e.g. https://learntech.imsu.ox.ac.uk/cslide/collections/index/87.

After a bit of searching I found this: http://fourwhitefeet.com/2009/02/css-display-inline-block-in-ie7/, so thanks to Cathy at http://fourwhitefeet.com.

It turns out that, in IE7, display: inline-block only works on inline elements, and I was trying to use it on divs. The trick is to wrap the content of these elements in an element that is natively displayed inline, e.g. span. For my purpose, I could just replace my divs with spans (they probably shouldn”t have been divs in the first place, but I’d mutilated the examples for Scrollable to gte where I was). It should also work by just adding spans around the content that you want to be ‘inline-block’, but inside the ‘block’ element, e.g.

<div><span style="display: inline-block">My Content</span></div>