nooshu - Matt Hobbs' Web Development Blog

Kneeling on the shoulders of giants

Category: HTML

A Hypertext Markup Language post all versions from HTML 4, XHTML and HTML5.

Remote Loading HTML5 Elements with jQuery

I ran into a rather annoying problem a few months ago while developing my travel blog; the problem of course was involving Internet Explorer. I’m used to working with WordPress as I use it all the time, but I wanted to get away from the standard pagination you find on a blog. So I decided to use jQuery 1.6.4 to pull in articles from other pages (blogname.com/page/2, blogname.com/page/3 etc). Now this is all fairly simple using the handy jQuery .load() method; point it to a URL, pull in the page, pick the bits you need and reinsert into the page. Simple! Unfortunately once I got a prototype working in ‘good’ browsers, IE8 and below was having non of it!

After a little head scratching to work out what was failing, I worked out it was because I was using HTML5 elements such as ‘article’, ‘header’ and ‘footer’. There was no problem displaying them on the page, as I’d used Remy Sharps excellent HTML5 Shiv script. It only failed when trying to pull in these ‘new’ elements via Ajax.

Note: Before you read on you’ll be happy to hear that this issue no longer occurs in jQuery 1.7.0. Horray!

If you can’t upgrade, for whatever reason, I hashed together a little work-around for browsers IE8 and below, so read on. I admit the work around isn’t pretty, but it works. I tried for a few hours to get IE8- to recognise the ‘new’ elements after an Ajax request, but to no avail. Eventually I had to wrap the HTML5 tags in a div using conditionals:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--[if lt IE 9]><div id="ieHackContainer"><![endif]-->

<article id="html5Content">
    <header>
        <h2>H2 wrapped in a header element</h2>
    </header>
    <!-- Other HTML here... -->
    <footer>
        <p>This is the footer element</p>
    </footer>
</article>

<!--[if lt IE 9]></div><![endif]-->

The div is added for browsers IE8 and below, you can then use it as a hook to pull in the elements inside the div. I was hoping that wrapping the HTML5 elements in a standard div would be the end of it, I’m afraid not. The .load() method still didn’t work, IE just ignored the elements it didn’t recognise. I used jQuerys much more customisable .ajax() method to fix the issue in IE6, 7 and 8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//IE8- work around to load HTML5 elements into a page
$("#loadHTML5LinkOld").click(function(){
        $.ajax({
                url: "page_to_load.html",
                cache: false,
                success: function(html){
                        var HTML;
                        //Clear before load
                        $("#html5LoadHolder").empty();
                       
                        //IE: Look for the hacky wrapper before insertion
                        HTML = $(html).filter("div#ieHackContainer").html();
                       
                        //If HTML var is empty assume using newer browsers
                        if(!HTML){
                                HTML = $(html).filter("#html5Content").html();
                        }
                       
                        //Append to page
                        $("#html5LoadHolder").append(HTML);
                }
        });
       
        return false;
});

This method works in all browsers I’ve tested in as I’ve added a fall back (or should that be forward?) for newer browsers. The solution isn’t ideal (I really hate the conditional comments), but older versions of IE aren’t going away any time soon, and it works. Maybe there’s a more obvious solution that I missed? Leave a comment if there is, I’d love to know!

You can see a working example here. The page I’m loading from is here and the JavaScript in full here.

The Sieve of Eratosthenes

I recently read Prime Obsession by John Derbyshire; a book all about prime numbers and one of the worlds greatest Mathematicians: Bernhard Riemann. The books main focus is on the Riemann Hypothesis which states that:

The real part of any non-trivial zero of the Riemann zeta function is 1/2.

I’d love to say that after reading the book I understand the Maths behind it but alas I do not. That’s not surprising though as it’s a problem that has yet to be solved, 159 years after Riemann paper on “On the Number of Primes Less Than a Given Magnitude”. It doesn’t look like it’s going to be solved any time soon either! If you’re interested it’s one of the Clay Mathematics Institutes Millennium Prize Problems in which you can earn yourself US$1,000,000.

While reading Prime Obsession it mentioned an interesting method for finding prime numbers called “Sieve of Eratosthenes” (pronounced air-a-TAWS-the-nEEss). Eratosthenes was a librarian at the great library of Alexandria around 230 B.C.E. It’s quite obvious how the method works once you know it, and easy to see why it’s called a sieve. The method goes like this:

  1. Write a list of numbers in which you wish to identify the primes, say 2 – 100 (exclude 1 as it isn’t required)
  2. Take the first number 2. Leaving 2 intact, remove every second number.
  3. Move onto the next number 3. Leave 3 intact and remove every third number
  4. Take the next number 5. Leave 5 intact and take away every fifth number
  5. Repeat until you get to the end of your list

The end result is the set of prime numbers up to your given number. Essentially all you are doing is removing any number that is divisible by the 1st, 2nd… Nth number. Clever stuff!

As a little side project I decided to implement this method using JavaScript, displaying the result in the browser. You can view the demo here. For fun I created two implementations, one relying heavily on the DOM, the other only using arrays. As you’d expect the DOM method is slow; looping through large tables multiple times doesn’t make for a quick execution time. The second method using a single JavaScript array is much quicker. I’ve added a stats panel to the right hand side of the page so it’s possible to compare results from both methods over different input values.

I’ve added a limit to the number you can enter into the input box (5000), I don’t want anyone blaming me for crashing their browser by entering 10 million! :) Feel free to copy the demo if you want to see what happens at higher values.

Sieve of Eratosthenes using JavaScript

The sieve in action showing prime numbers up to 500.

Thanks goes to John Resig for his very handy Array Remove method.It made removing non-primes from the numbers array very simple indeed.

Prime Obsession is a superb book but a word of warning, it contains a lot of higher level Mathematics, so may not be to everyone’s taste. It certainly made my brain hurt at times; not always what you need on that 8am commute to work! View the demo.

Monitoring a value change on an input element

For a recent project I ran into a slight issue with the jQuery change event. It’s not an issue with jQuery, but I was quite surprised when it didn’t work as I expected. I’d set up a selection of form inputs that a user could change; once changed various calculations would be made and the values outputted to a second set of disabled input elements (demo). The inputs are disabled as they are to be calculated rather than entered manually.

I’d attached the jQuery change event to the output elements like so:

1
2
3
$("#outputs").find("input:text").bind("change", function(){
    $(this).highlightFade('red');
});

So the plan was, once an input value had been changed using the jQuery().val() method the change event would fire and it would quickly colour in and out the element (using highlightFade) to notify the user that it’s value had changed. Unfortunately the change event wasn’t firing, so I had to find another way to monitor the output elements.

What I ended up doing was using an array to hold the previous values of the input elements then checking to see if they had changed in the calculation. If changed then fire the event:

1
2
3
4
5
6
7
8
9
10
11
12
13
//Array to store the old values
var oldValues = [];        
   
//Push these values into an array which is checked on calculation
$("#valueOutput input:text").each(function(i){
   var thisValue = $(this).val();
   //If the old value is different to the new, change the colour
   if(oldValues[i] !== thisValue){
       $(this).highlightFade('red');
   }
   //Push the new value into the array
   oldValues[i] = thisValue;
});

It’s quite hard to explain exactly what’s happening so I’ve put together a small demo. Try changing one of the top input fields then tab (or click out) of the input element to recalculate. Is there an easier (or better) way to do this? Comment below.

Experimenting with Webkit form speech input

It’s been a few weeks now since I attended a Web Gaming event hosted by Mozilla and I’ve not yet had chance to write about one of the coolest features that was demonstrated: Speech input in forms. Now I must admit, I had no idea this was even possible; so it was quite a surprise when I saw the demonstration. With a few extra attributes added to a standard input box you can enable speech input:

1
<input name="speech" id="speech" type="text" x-webkit-speech speech error onwebkitspeechchange="dosomething.coolhere(true);" />

It really is that simple! You may notice the “x-webkit-speech” attribute so will have guessed it currently only works in Webkit; and as far as I’m aware only in very recent versions of Google Chrome (note: “The Input Speech API will now be available by default on Chrome’s dev-channel”). The Speech API seems very new and is still a draft, so it will be a while before it’s fully adopted by other browser vendors.

Demo of the new HTML5 Speech API

A quick demonstration of the Speech API in action.

To demonstrate the speech input I’ve put together a very simple festive demo that queries the Flickr API looking for images related to a value entered. So if you have a microphone and the dev channel of Chrome, why not give it a try. Chrome records the input of the microphone before sending it off to an external server to be processed, where a value is then sent back to the browser. At first I thought it was all processed inside the browser but I guess that’s a little to much to expect! It isn’t 100% accurate and the demo accepts Googles first guess so you may get a few strange results. The server returns multiple guesses which a user can select from, but this hasn’t been added (to my demo at least).

Since the API is very new it took a little trial and error to work out how to detect if the Speech API was available in the browser; but with a little help from Paul Irish I managed to crack it:

1
2
3
4
5
function speechcapable(){
    var elem = document.createElement('input');
    var support = 'onwebkitspeechchange' in elem || 'speech' in elem;
    return support;
}

This function will return true if the API is available. It’s worth noting that since it’s very new this function is likely to break in the future as the properties always seem to be changing. It works at the moment, so get thinking about what this brilliant new API can be used for! It’s a big plus for accessibility if used correctly and I can also see some cool applications in web gaming too. View the demo.

Three.js images using the HTML5 File API

Anyone who’s read my latest blog posts will know that I’m a big fan of Mr doobs Three.js JavaScript 3D engine, so I won’t bang on about it any more than I have to. For my latest experiment I decided to mix the HTML5 File API, Three.js and a few images (demo here).

mr doob Three.js with the File API

Mr Doob and a little kitten sitting in a 3D tree.

The File API allows a user to upload a file (an image in this experiment) to a web application simply by dragging it onto a designated “droparea”. Once dropped, you can manipulate the data any way you like. The API is able to handle multiple files natively, so just select all the files and drop them onto the area. No need for Flash uploaders or multiple browse boxes. Of course not all browsers support it (IE) and there are a few inconsistencies in the specification; but they will work themselves out over time.

So what does the experiment actually do? Well it allows a user to drag an image onto their browser window which is then “uploaded”; the data is then passed to a canvas element and then this data is passed to Three.js to be plotted in 3D space. The X and Z-axis is plotted in the usual manner to represent the default 2D image using particles; the fun bit comes when you add the Y-axis. This is calculated by taking an average of the RGB values (greyscale) and plotting it accordingly. When using an image of a human face it’s amazing how accurate the 3D plot looks.

Due to the amount of data involved it is recommended that you use small thumbnail images when you try the demo, as larger images equal a larger number of particles. This is an initial version so I’m going to work on a way of dealing with larger images. This will probably mean ignoring a certain number of pixels when looping through the image data. Looking forward, since it can be done with a static image I see no reason why it can’t be done with a video, but that’s a project for another day!

Update: I’ve updated the demo slightly; as Mr.doob pointed out people may have tried to drag directly onto the render area which didn’t work. So now it does :)

Currently on page 1 of 612345Last »