A friend of mine using JaS said that he sometimes had the scenario that he wanted to load all the images but then preload a certain tag, hence initially hiding all the pictures that doesn’t match that criteria. I though it was a simple task so I created an add-on script for those interested.
After doing some extensive testing, due to some error reports that the overlay layer didn’t cover all parts of the web page if it had a scroll, I’ve now updated the script to take that into consideration as well. A positive effect of this is that, during a slideshow, it will automatically adapt the overlay size if the user resizes the web browser window or scrolls within it.
Also, one of the biggest upsides to this is that I’ve eliminated the need to add CSS specifically for Internet Explorer to handle overflow scenarios. The CSS code below has been updated accordingly.
So, I sincerely ask of you to download the example package (ZIP file link) to get this important fix, or if you already have your own custom CSS, to re-download the JaS JavaScript file and simply replace your current one.
Looking at nice features like Lightbox JS and what my friends at Particletree did with Lightbox Gone Wild!, I found it to be a given to add this functionality to JaS – JavaScript Slides. Now the image view, as well as the slideshow feature, supports it in different combinations.
Remember something called Geek Meet? People with a sincere interest in web development, always up for learning more and hanging out with like-minded? Well, fret no more! It’s time again! π
For those of you using the very flexible AJAX-S for slideshows, I have now created a little add-on script to hide the footer and only showing it when moving your mouse pointer over it.
Event handling in JavaScript has been an issue for many web developers, and countless of people have made their stab of solving it. When I wrote my post AJAX, JavaScript and accessibility some commenters were asking for a follow-up post explaining event handling in JavaScript. My idea here is to give you a basic background and to also tell you about a new and interesting solution.
Yesterday I went to visit some fellow consultants at their assignment for a sub company/department of one of Sweden’s largest banks. We had a talk about AJAX in general and different ways of how to implement it, and one of them opened his web browser to navigate to some AJAX-based web sites.
Something interesting followed next that really baffled me. Most web sites he went to had empty white patches where no content showed up, and some web pages even went completely blank. We knew for sure that JavaScript was enabled in his web browser of choice (IE, but still almost a real web browser… ;-)) so that couldn’t be the problem.
Then, naturally, we had to go test my ASK script to see what was going on. The version that we got there was the fallback version that works without JavaScript, but instead with regular links reloading the entire web page, meaning that no JavaScript events were applied.
After some digging, we found out that the JavaScript file was completely blank! The reason for this, apparently, is that the proxy server they had to go through to access internet totally cleansed any JavaScript file that contained this text:
new ActiveXObject
So much for object detection and every other approach we recommend to web developers. Not a single line of code was left behind in the file. And the problem is that it won’t throw an error or show the content of a noscript tag either; everything just stops working.
My initial reaction was that if they have such a tight security environment doing that, I really don’t want to care to cater to them. But as my boiling blood got calmer (kind of an exaggeration), I realized that this company was too big to ignore the fact that all their users got shut out.
Also, if they have a situation like this, it’s likely that many other large companies have a similar solution.
Conclusion: if you want to develop AJAX apps, make sure that it works without JavaScript as well, apply all the scripts in an unobtrusive fashion. I’m just glad that ASK passed the test with its accessible groundwork and then building AJAX functionality on top of that (Actually, the Google Analytics code of the ASK page did in fact throw an error when we tested it, but I think it was just a consequence of the proxy server doing it’s job…).
I guess most of you, one time or another, has had the need to find out what style was actually rendered on an element. The easiest way to do this is through the style property followed by the specific value you’re looking for:
var intPosLeft = document.getElementById("left").style.left;
However, this only works if the CSS has been applied inline on the element. As we all (or at least most of us) have realized, having inline styles isn’t a very good and efficient approach. So then we move all our CSS to an external file and suddenly the style property return no values when checking it.
What the hell happened?
The style property is reserved for inline styles (ridiculous, if you ask me), so you need to find another way to do it. Of course, then, there’s one standard way and one Microsoft way.
I have put together a function named getStyle (yes, the name is supposed to be funny) to solve this issue for you:
I’ve updated one line for IE per zcorpan’s suggestion. The previous code worked fine as well, it’s just a matter of personal preference when it comes to code syntax.
The first parameter is an object reference to the element you want to check, the second is the CSS name of the property you want to know the rendered value for.
Interesting to know is that specific values will return a value even if it was applied by shorthand in the CSS. For example, this will work just fine:
/* Element CSS*/
div#container{
font: 2em/2.25em Verdana, Geneva, Arial, Helvetica, sans-serif;
}
var elementFontSize = getStyle(document.getElementById("container"), "font-size");
An other interesting thing is that Firefox, Opera and Safari will returned the actual pixels of a font size applied with em, while IE only return the value in em.
Web browser compatibility
This script has been tested to work in the following web browsers:
IE 5.5+
Firefox
Safari
Opera 8.5
The reason that it doesn’t work in IE 5.0 is having a function in the replace method as a second parameter. You might want to put this in a try...catch clause if you expect any users with that version, like this:
try{
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
catch(e){
// Used to prevent an error in IE 5.0
}
This article is co-written with Anne van Kesteren, W3C Member and contributor to the WHATWG and Opera specifications, R&D and QA person.
When developing a web page, DOM methods are generally the way to go when dynamically altering elements’ attributes and performing other operations. But what about adding content to a web page in the most efficient manner, both code- and performance wise? We claim that innerHTML is unmatched by any DOM methods available and that it is in most, if not all, situations the best option.
People seem to have this feeling that innerHTML is evil. Instead of one line of innerHTML you would use about twenty lines with calls to the DOM. Every such line making one change. However, innerHTML is actually not that bad. The web browser pretty much parses it much like it parses the original page and builds some DOM nodes out of it which are then inserted at the requested location. Some mutation events are dispatched for the few who care and all is fine.
When it comes to having greater scalability in a web page, especially in AJAX scenarios, innerHTML offers unmatched flexibility. There has also been benchmark tests verifying that innerHTML is more efficient compared to using DOM methods.
The fact that it is not in a standard is simply because nobody got around to it. If you read the mailing list of the W3C Web API’s Working Group you can see that Opera, Mozilla and Apple want it to be standardized and we bet Microsoft would like the same thing. New entrants in the web browser market are probably interested as well given that it has to be supported anyway. That it’s not in a standard is probably its biggest problem, apart from the name which doesn’t really scale well. On the other hand, people complain a lot about document.write() as well which is part of DOM Level 2 HTML.
So, go on! Start, or continue, to use the best tool available for the job!
I’ve done a very minor change to the event handling to cover up for a bug in IE’s garbage collector (something I hear will be addressed automatically in IE 7). In 99,9% of the cases you won’t notice any difference, but if you use it in a very advanced web site/web application it might make things better and less resource intensive.
Updated October 25th 2007
I get a number of e-mails asking how to start the slideshow as soon as the page is loaded. Add this code to the end of the jas.js to make it happen:
(The setTimeout is to avoid a content parsing bug in Internet Explorer)
Pretty much everyone wants to display and show images to other people, right? So many use Flickr for it, and while I think it’s a great idea and that it has got some wonderful features, my main gripe is that if I present images, I want to do it in my own web site.
People who do it themselves, on the other hand, always think Flash is necessary just to have fading and a nice little slideshow. Not true.
Therefore, I created JaS – JavaScript Slides. It is a highly customizable JavaScript library for easily turning your images into a collection viewable as a slideshow, and with fading effects, if desired. It also supports automatic thumbnail creation and tagging of images, so the viewers can find the exact images they’re looking for.
Humbly described, it’s like your own little mini-Flickr that you can use wherever you want to, and skin and brand it the way you feel appropriate. It’s also a way to showcase the independence and separation of the interaction and the design of a web page.
With the advent of mass-hype for building AJAX solutions, I find it necessary to shed some light of AJAX and JavaScript implementations and how they relate to and affect accessibility, and to explain how they can both co-exist; that one doesn’t exclude the other.
What is a progressive enhancement/unobtrusive JavaScript approach?
First, a good JavaScript approach is about implementing JavaScript in an unobtrusive way. Basically, what this means is avoiding some basic bad implementations:
No more inline event handlers in HTML elements, meaning that code like this should never be used:
<div onclick="doSomethingAnnoying()">A div</div>)
Definitely never ever use javascript: links, like this:
No inline JavaScript blocks in your web pages at all.
How should I do it then?
Common things to think about are:
Have all your JavaScript in external files, for better accessibility and performance (since JavaScript files are cached by the web browser and only needs to be retrieved once), and then also apply events to elements from there.
Only apply JavaScript event handlers to elements that already have built-in functionality for communicating, like links and submit buttons.
Make sure the web site functions without JavaScript. JavaScript is supposed to be used to spice things up based on already existing functionality, not to be the corner stone that the web site is totally depending on.
Give me a good example
Sure! For instance, say you want to apply a certain JavaScript event to some links in your web page that shows an information layer (e.g. a div that is initially hidden). How do you do it?
Use the window.onload event, which is triggered when the web page is fully loaded, to then apply your events to desired elements. There are many different ways of doing this and how to handle events, so here’s a simple example:
The result is that web browsers that have JavaScript activated and that support the document.getElementById and document.getElementsByTagName methods will cancel the links navigation to the my-details.php page and instead show an information layer directly in the page. For those who don’t match that criteria, it will simply redirect them to the my-details page. Offering something extra for those with JavaScript enabled but still degrading nicely and being fully functional to others.
Let’s break the script down, what happened?
window.onload = applyEvents;
First I tell the window to call a function when it’s onload event is triggered, i.e. the page is fully loaded. Notice: no parentheses after the function name, in that case it would’ve been called instantaneously.
In the applyEvents function, the first line is this:
What it does is using an approach called object detection to see if the document object supports the two methods we want to use: document.getElementById and document.getElementsByTagName (these two are widely supported by most web browsers, don’t worry).
var arrAllLinks = document.getElementsByTagName("a");
Gets a collection of all link elements in the page (could be done in a more effective manner with the getElementsByClassName script).
Loops through the collection of links to find the ones with a certain class name. Note the usage of the variable oLink to avoid doing several checks in the array, and that it is also declared outside the loop. All for performance reasons.
Applies the onclick event to the matching link/-s and cancels their default behavior. The check for oEvent in the event handling is the standard way of event handling, while event is for Internet Explorer’s flawed and proprietary event handling. Now a click will instead show the information layer element.
What about AJAX, it said so in the title?
With the good practices and examples I’ve given above, it’s pretty much all about using the same knowledge when doing something AJAX-based. With my AJAX library, ASK, it was my attention to implement it in that manner, and also cater to well-known usability problems like back buttons that work, impossible to bookmark a specific state of an AJAX-based page etc, at the same time. I definitely urge you to take a look at it and play around with it.
Something to think of is that when it comes to screen readers is that they might support the JavaScript you use but won’t notify the user that something has been updated in the page. For more on this discussion, please read Derek’s Javascript and Accessibility (yes, I saw the name of his post after I initially posted this one… π ).
As soon as the word accessibility is mentioned very strong feelings and opinions come into motion and the discussions go on all night. Therefore, I felt the need to take a shot at explaining my view on accessibility.
To me, it is all about making web sites accessible to people with disabilities and at the same time to people using different operating systems, web browsers and devices. I’m sure that the general notion when the term accessibility initially was coined that it was to focus on, and cater to, people with special needs that don’t have all the prerequisites as everyone else. A very noble initiative and a corner stone if we ever want the web to be taken seriously.
But when making a web site accessible to people with disabilities, why wouldn’t we at the same time make it accessible to people who aren’t using Windows and Internet Explorer? It’s a mindset and an attitude that go hand-in-hand for me. Surely, everyone wants to reach an audience as wide as possible, right?
A thing that bothers me, though, is when accessibility advocates proclaim that we have to stay away from using JavaScript, Flash et al, all in the name of making it accessibility. Accessibility and using JavaScript, for example, aren’t mutually exclusive. It’s all about progressive enhancement. Build a common ground and then implement enriching features in an unobtrusive way that doesn’t rule out accessibility.
So, let’s stop bickering about what we read into the word accessibility, and instead start focusing on reaching as many people as possible with this wonderful medium called the Internet!
This morning, when I read the headline technical article in Computer Sweden , I got upset, tired and saddened. Basically, the article is calling Swedish companies out of date just because they aren’t using AJAX for their web sites. It also somehow manages to convey the notion that AJAX = Web 2.0.
First, AJAX is not Web 2.0. A Web 2.0 company/solution might use AJAX, and that’s it. Using AJAX doesn’t automatically make it Web 2.0. Period.
Second, calling AJAX modern is just ignorant. The technical possibilities have been around for years, the only thing that’s “new” is the acronym and the hype.
Third, even if it were a modern approach, why would everyone benefit from it? The web is already filled to the brim with unmotivated AJAX solutions; web sites that have sacrificed accessibility and usability just to be doing the latest thing. Now this magazine, probably the technical magazine/paper with the highest amount of readers and vastest reach in Sweden, helps to spread the word that everything has to be AJAX-based, which will, without a doubt, lead to a lot of web developers out there start doing it right away, and managers will run to their employees proclaiming that they just can’t miss this.
The article is written by a reporter who, last week, published an article stating that web sites would have to be re-written for IE 7. Sure, if it were amateurs doing the job the first time around… So, needless to say, his track record reveals that maybe he hasn’t gotten a technical expertise. Which is fine, but then please do the proper research before publishing such pieces. With such a job, there’s a responsibility that goes with it.
One company that is mentioned and quoted in the article is hitta.se , who proudly announces that their AJAX-based preloading maps are so much better than their competitor Eniro’s are. Ok, let’s take a swift look at hitta.se and see for ourselves:
With JavaScript disabled, no maps are shown at all (compared to Eniro’s that at least show up initially, but then the navigation of the map doesn’t work).
The code is riddled with inline styles and inline scripts, completely forsaking the professional approach of having this in separate layers.
The word semantics doesn’t seem to have gotten through at all to the web developers; the state of the HTML code is appalling.
So, where does this leave us? They’re proud to be using the “new” technology AJAX, while totally forsaking everything else when it comes to good practice, accessibility, usability and proper web interface developing. If you implement such a simple thing as a map on a web page, and especially for such a popular service on the web, your responsibility is to make sure it isn’t dependant on JavaScript.
Does this mean that AJAX has to be inaccessible then? Absolutely not, it’s all about doing it the correct way. Also, I don’t have a problem with AJAX itself; on the contrary, I agree that used in a proper context, it can make using a web site a lot more interesting, useful and fast to use. But it should never be used at the cost of excluding users or normal web browsing behavior such as using the forward and back buttons in the web browser, bookmarking, reloading etc (this is all something I wanted to address with ASK – AJAX Source Kit).
Do I have a beef with hitta.se? Not at all, I just get tired when people make statements and say that they’re so much more in the loop than other companies, and then it’s obvious that they haven’t done their job correctly. In fact, I know the people behind specifying the concept, and I think it’s great! It’s just sad that the web developers implementing it didn’t have the skills to match it.
Conclusively, I’d advise hitta.se to make their next statement when you’ve done your job right. Till then, do your homework…
Denny brought to my attention that the history and the links didn’t work flawlessly if you have the same target element for several ASK links. Therefore, I’ve now added a paremeter to the object constructor, this.useSameTargetForSeveralCalls = false; that should be set to true if you want to use the same target element for several ASK links. However, the default value is false to avoid adding links to the history if they have different target elements, and also to save performance.
Updated September 29th 2006
I’ve updated a more fail-safe way to use the XMLHTTP ActiveX object in IE, and also added proper fallbacks if the first one fails.
Also, a very minor change has been done to the event handling to cover up for a bug in IE’s garbage collector (something I hear will be addressed automatically in IE 7). In 99,9% of the cases you won’t notice any difference, but if you use it in a very advanced web site/web application it might make things better and less resource intensive.
I have always liked the approach of updating certain content on-the-fly in a web page without the need of reloading the entire content. This approach has been around for years and has fairly recently been nicknamed AJAX.
The thing with AJAX is that it needs JavaScript to work and a direct consequence surrounding its hype is that a lot of web sites have implemented it without catering to common usability and accessibility factors. This is something that has saddened me, and therefore I developed ASK – AJAX Source KIT to address that while at the same time offer a light-weight library to implement AJAX functionality without having to worry about web browser differences.
The basic idea of it is to implement AJAX without sacrificing those factors and at the same time do it in an unobtrusive way, meaning that there’s no need for any event handlers or extra elements in the HTML code. All that is needed is to include the ASK JavaScript file, assign certain class names to the elements one wants to apply the ASK functionality to, and then implement accessible as well as AJAX-enhanced versions of the content that shall be retrieved dynamically.
My ASK concept was featured in the February issue of Treehouse Magazine, where you can find a more in-depth explanation of the code and about the choices I made during its developing phase.
My humble hope is that by seeing this, more web developers will understand what it takes to take a considerate approach to AJAX while using it to offer end users a richer experience. Please try it out and don’t hesitate to post any questions here that you might have.
I am very proud to announce that my latest code concept, ASK, is the feature code article Easy Ajax with ASK, in the February issue of Treehouse Magazine.
I was actually asked back in Mid-November to contribute, but unfortunately I had too much things going on then, so I didn’t feel I would have the time and the focus necessary to produce something worthy of being in Treehouse. We talked back and forth and postponed it until now, but finally, here it is! π
Part of me is humbly very appreciative of being asked, no less by the extraordinary people of Particletree producing Treehouse, and whose impact on the web developing scene has been tremendous; I think there are few web developers out there, at least of the blog-reading kind, that have never heard of them.
Another part of me thinks I rightly deserve this; during the last seven years I’ve put a vast amount of time into web developing and into learning and trying to become a better and more considerate web developer. To work that hard for something and to get this kind of recognition warms my heart and sends me the message that it was all worth it, it wasn’t a struggle in vain.
Tomorrow I will write a release post offering you the source code and a demo of ASK for you to try out and give me feedback about. However, that post will only be a short introduction, if you want a longer technical explanation as well as getting to know why I made the different choices I did, I strongly recommend to get a hold of the Treehouse Magazine issue (plus the fact that you will then have a day up on everyone else, since a link to the demo is in the article).
Also, nevertheless, if you’re not even slightly interested in ASK, I still recommend picking it up, because, as every issue of this magazine, it’s fascinating.
PS. Yes, apparently I’m being a little narcissistic today. Please let me just have this one, I promise I’ll be back to normal soon… π DS.
The IE team has made a very wise decision to natively support XMLHttpRequest in IE 7. XMLHTTPRequest is the foundation of any AJAX usage, and I for one applaud the move to make it available without the demand for using ActiveXObject.
Using object detection, one can easily make your code backwards compatible as well:
var oXMLHttp;
if(typeof XMLHttpRequest != "undefined"){
/* Code for:
IE 7
Firefox, Mozilla etc
Safari
Opera
*/
oXMLHttp = new XMLHttpRequest();
}
else if(typeof window.ActiveXObject != "undefined"){
/*
Code for:
IE 5
IE 6
*/
oXMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
Apparently Opera’s claim to support document.all in conjunction with not mimicking it exactly like IE led to some problems in Opera 9. Thanks to Ash Searle who tipped me about this and also explained what the problem was. The code below and the JavaScript file to download are updated.
Since we all have to face a new hard tough week now, I thought I’d brighten your day by giving you some code that might be useful.
Ever run into a situation where you want to get an array of all elements with a specific attribute? Or even want elements with a certain value for that chosen attribute, as well? That’s not a problem anymore; let me present getElementsByAttribute.
/*
Copyright Robert Nyman, http://www.robertnyman.com
Free to use if this text is included
*/
function getElementsByAttribute(oElm, strTagName, strAttributeName, strAttributeValue){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
var oAttributeValue = (typeof strAttributeValue != "undefined")? new RegExp("(^|\\s)" + strAttributeValue + "(\\s|$)") : null;
var oCurrent;
var oAttribute;
for(var i=0; i<arrElements.length; i++){
oCurrent = arrElements[i];
oAttribute = oCurrent.getAttribute && oCurrent.getAttribute(strAttributeName);
if(typeof oAttribute == "string" && oAttribute.length > 0){
if(typeof strAttributeValue == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))){
arrReturnElements.push(oCurrent);
}
}
}
return arrReturnElements;
}
The parameters are:
oElm
Mandatory. This is element in whose children you will look for the attribute.
strTagName
Mandatory. This is the name of the HTML elements you want to look in. Use wildcard (*) if you want to look in all elements.
strAttributeName
Mandatory. The name of the attribute you’re looking for.
strAttributeValue
Optional. If you want the attribute you’re looking for to have a certain value as well.
And these are a couple of examples how it can be called:
Yesterday when I was testing an AJAX script in an application I’m working on, I wanted to use the abort() method of the XmlHttpRequest object to cancel current outstanding data transfers (if this is all Greek to you, don’t worry, one day I will write more about AJAX).
IE unexpectedly threw errors when I was trying to use that method, and it did as well when I tried to use object detection to check for it. Weird. So I resorted to use typeof to check what it returned, and to my amazement it returned “unknown”! To my knowledge, the only valid and possible values in JavaScript to get when using the typeof operator are these:
number
string
boolean
object
function
undefined
So is this is an IE bug? Or some freaky ActiveXObject hocus pocus? Please let me know if you have any idea!
Code to test with:
// Note! This code will only work in Internet Explorer
if(typeof window.ActiveXObject != "undefined"){
oXMLHTTPRequest = new ActiveXObject("Msxml2.XMLHTTP");
alert(typeof oXMLHTTPRequest.abort);
}
First, just for you to understand where I’m coming from, let me tell you that I love JavaScript. It has given me, and continues to give, immense pleasure when it comes to web developing and I’ve been writing JavaScripts extensively since ’99, doing everything from minor validations and other checks to things like animations, Flash fallbacks and a Web OS.
So, let me move on to the topic of JavaScript animations. Faruk recently launched his web site, and more specifically presented the project he and Tim Hofman have been working on:the FACE project. To simplify, it’s a way of adding animation and visual effects to a web page through JavaScript and CSS. While I have no major objection when it comes to the code itself, I’m not really so sure about the concept.
Animations through JavaScript doesn’t really give the lean smooth experience technologies like Flash or manipulating vector graphics in any other way can, and using filters is, at least in IE, infamous for slowing the web browser down and draining the memory. While I like the idea of not being dependant on any plug-in to create an effect, I think Flash is spread widely enough to not be a problem.
Another perspective is that I, as a user, have a way to choose what kind of web site I want to visit. If I want a web site that is visually a rich experience, and maybe with sound as well, I visit a Flash-based web site, who normally offer a non-Flash version of it as well. But if I visit a “normal” web site, I really like that things aren’t moving around, blinking and flashing, and generally stealing my attention from the content.
This paragraph is probably going to sound a bit harsh, but the only reason I’m writing it is because I went through the same kind of evolution myself. While being very talented otherwise, Faruk is fairly new to JavaScript, and he’s now doing exactly what I did when I reached that level: creating animations. So, what I wonder is if he and Tim create this because they can, or because there’s a user base out there asking for it?
In general, I think adding interactivity to web pages through JavaScript is the right way to go, but then I think approaches like AJAX and its likes are fundamentally more interesting than animations. However, this is merely my humble opinion. I might be totally off-key here and people out there really long for this.
So, tell me what you think? Are JavaScript animations just the new animated GIFs, or are they the future?
Last week I bought the November issue of Treehouse magazine, coming from the people of Particletree, and I have to say it was the best spent three bucks in a long time! I instantly had to read it from cover to cover.
It starts off with two very interesting things: An addEvent article by Ryan Campbell explaining the need for such a function and the difference between the different solutions out there, and then goes straight into an interview with Peter-Paul Koch. Peter-Paul has had a tremendous impact on the web developing community, and especially the JavaScript part. However, I’ve never gotten the chance to meet him in person, and I’ve only gotten one e-mail reply from him (this was a number of years ago). So, Peter-Paul, if you read this, let’s make sure we meet. Who knows, I might even have something good to say too! π
The magazine goes on with some other interesting interviews and articles, where I really liked the Dead Poets Society feeling I got from the interview with, amongst many other things, teacher Lisa McMillan. Alex McClung also had an interesting article about writing accessible HTML code in his piece Understanding Section 508 (although he manages to call the alt attribute for alt tag once… :-)).
Basically, a very recommended read altogether. I think the magazine will appeal to people of all kinds of experience and interest working with the web. Go read now!
The demo and the zip file are updated with a small fix to avoid generating invalid nodes while still offering the possibility to use custom HTML in any page, and the ability to display escaped code for presentations.
Updated the drop down to support pressing the spacebar and enter keys when it has got focus, to navigate directly to that certain page.
Important update!
By popular request, AJAX-S now supports XHTML code in the XML file as well. No escaping, no nothing, just write as you usually do! I think now that it is a real contender to Eric Meyer’s S5!
For some reason unknown to me, the XSLT files failed to work in some Mozilla web browsers on some computers when they had an .xslt extension. I’ve changed the zip file so it now points to XSLT files with an .xml extension. If you’ve downloaded a previous version that didn’t work, please try the new one. Big thanks to Karl and especially Henrik Box for doing some extensive testing for me (Henrik wants to meet the girls behind girlspoke as a thanks… :-))!
Release 2!
After listening to the feedback I got, I’ve now done some major updates to AJAX-S. It now supports incremental rendering, non-JavaScript users and also offers a printable version. Go check the updated demo.
Changed the JavaScript detect for support for the XSLTProcessor object so it asks users that lack that support if they want to go to the printable page instead.
Added check to scroll the current incremental step into view if it wasn’t visible.
Updated with a different look for active increment, past increment and coming increment, and a setting if one wants the first or last increment to be selected when backing from an upcoming page.
Updated with a different look for active increment, past increment and coming increment, and a setting if one wants the first or last increment to be selected when backing from an upcoming page.
Updated with a fix for two glitches in the keyboard navigation.
Add-on available as of September 7th, 2006
An add-on for AJAX-S has been developed, to automatically show/hide the footer of the slides.
I’ve been thinking about creating an AJAX-based slideshow for a while, and today it happened! Today I wrote my first line of code in this project (probably not the last one), but for the moment I feel very content with the results. The code is probably not perfect, but I’m going more for the concept here. The tweaking options are endless.
The idea came to me because I wanted a lightweight slideshow based on HTML, CSS and JavaScript, but I also wanted to separate the data of each page from the actual code that presents it. Therefore, I decided to move the data into an XML file and then use AJAX to retrieve it. The name AJAX-S is short for AJAX-Slides (or Asynchronous JavaScript and XML Slides, if you want to).
Naturally, one of my inspirations for creating a HTML-based slideshow are from Eric Meyer and his S5. However, I wanted to take it one notch further, to make it more flexible and also usable for people with no HTML knowledge whatsoever. Another motivating factor was to just transform the data for the current page, as opposed to creating all the HTML needed for all the pages when the page is initially loaded. A leaner end user experience, basically.
It only works in IE 6 and Mozilla-based web browsers as of now. This is because of the need to do on the fly transformations on the client, which means the necessary support for ActiveXObject or XSLTProcessor has to be there. I think Opera 9 will support XSLTProcessor and probably some upcoming version of Safari too, so more widespread support in the future is very likely.
A freaky thing, which I hope is only a very unimportant detail, is that when I run it here at my host provider, I have to use the xml instead of the xslt one. However, most likely a hosting issue only.
But enough of that now. Download AJAX-S or view the demo of AJAX-S. Please let me know what you think, and if there’s any major error in the code. Not a requirement at all, but if you use it and like it, I would appreciate getting credit for it. π
Updated again, Tuesday, November 8th, 2005
Switched from using word boundaries to checking for spaces and/or start/end of string. Also, see my comment about this.
Once again updated Tuesday, November 8th, 2005
I forgot a break; statement in the advanced version. Nothing that would break it, but bad performance-wise.
Updated Tuesday, November 8th, 2005
This is getting ridicilous now. Changed name of the linked JavaScript file to getElementsByClassName.js.
Updated July 14th 2006
As Wilfred and Sander correctly pointed out, there is a way to make the script more efficient in IE 5.x when using the wildcard character to call it. The code in this post and the downloadable file have been updated accordingly.
Updated May 11th 2007
It’s been a while since I took a look at this, and with speed comparisons and all, I have revised so it should be just a tad faster. The new script is just below and added to the downloadable JavaScript file as well.
One of the major differences is that tag name and containing element are optional, and if not supplied, will default to * respectively document. This means that the order of the parameters are also changed, so className to look for is the first one, followed by tag and then elm. However, for best performance, I recommend sending in all three parameters as closely specified as possible.
Updated May 30th 2007
The revised version in the file was ok, but the published version in the post just below missed a couple of \. This has now been adressed.
Revised version May 11th 2007
function getElementsByClassName(className, tag, elm){
var testClass = new RegExp("(^|\\s)" + className + "(\\s|$)");
var tag = tag || "*";
var elm = elm || document;
var elements = (tag == "*" && elm.all)? elm.all : elm.getElementsByTagName(tag);
var returnElements = [];
var current;
var length = elements.length;
for(var i=0; i<length; i++){
current = elements[i];
if(testClass.test(current.className)){
returnElements.push(current);
}
}
return returnElements;
}
Good JavaScript usage on the Internet is based on making it unobtrusive, meaning that web pages aren’t dependant on it to work and that that the HTML code shouldn’t be riddled with inline event handlers and JavaScripts. Using javascript: is forbidden, stop that!
What you do is to apply the events to desired elements from an external JavaScript file, normally performed when the page has loaded. For instance, if you want to apply a certain event to some a elements, you loop through the a elements in the page and then apply the events accordingly, e.g. if the element has a certain class name.
Last week, I felt the need to have a script that accessed all elements in a web page with a certain class name and returned them as an array to work with. I wrote my function, but ran into problems when it came to distinguishing class names that contained a hyphen (-). Then I remembered that Jonathan Snookwrote a function a while ago, so I went to his web page to see if I’d missed something. Interestingly enough, it was very similar to mine, and when I tested his it didn’t work either.
So, since Jonathan and I talk on and off, I contacted him about this over MSN. Jonathan, being the cool and helpful guy that he is, immediately took the time to discuss this with me. I coded away, told him what happened as I went along, and we brainstormed about how we could solve it. After some work, we came up with something that seems to work really fine, supporting class names with hyphens and multiple class names on the same element. It is actually very similar to Jonathan’s original function but with an escape fix and some performance add-ons.
Let me present The Ultimate getElementsByClassName:
/*
Written by Jonathan Snook, http://www.snook.ca/jonathan
Add-ons by Robert Nyman, http://www.robertnyman.com
*/
function getElementsByClassName(oElm, strTagName, strClassName){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
strClassName = strClassName.replace(/\-/g, "\\-");
var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
var oElement;
for(var i=0; i<arrElements.length; i++){
oElement = arrElements[i];
if(oRegExp.test(oElement.className)){
arrReturnElements.push(oElement);
}
}
return (arrReturnElements)
}
Some ways to call it
To get all a elements in the document with a “info-links” class.
The first line in the function is to cover-up for a flaw in IE 5 where one can’t use the wildcard selector * to get all elements. The rest is basically about setting up a regular expression with the class name we’re looking for, where we escape hyphens and then match that to the class names of the elements where we’re looking for it.
Please try it out. Our hope is that it will help you develop unobtrusive JavaScripts and that it will make it easier for you to maintain your web sites. Any problems with the function, please let us know.
Go crazy now! π
Updateded! Since Anne asked for support to look for multiple class names in the same call, I’ve revised the function. The above function is intact and supports multiple class names if they’re entered in that order on the element. If they’re not, you should use the below function. Kudos to Curtis for inspiration.
I’m sitting here; just sipping some nice red wine and eating chocolate, celebrating that the last seven days are over now. I’ve been working double shifts for about a week, doing my hours as a consultant daytime, and working on redesigning this web site nighttime.
So finally: redesign! And I wanted to get done with it as fast as possible, I couldn’t stand making a live redesign spread over a longer amount of time, like one of my friends does. There have been a number of reasons I wanted to create and implement a new design for this web site, and the factors and choices have mainly been these:
Write the code myself
When I launched robertnyman.com, I installed WordPress and looked around for themes written for it. My previous design was a theme designed by Shawn Grimes, that I tweaked a bit to personalize it. But with me ranting about how web sites should be developed, I ought to live up to what I preach at my own web site. You know, the shoemaker’s children and all…
I wanted something that was really easy on the eyes, something that looked good and also being original to get some attention for that as well. All image material used here is from pictures I’ve taken myself. And since it’s an Easter Island theme, naturally there has to be an Easter egg; if you find and hold down a certain key combination, you will get to see a freaky picture of me! π
Accessibility
I want this web site to be an example of being accessible to everyone:
With or without JavaScript enabled.
With or without CSS switched on/supported.
With a wider or narrower window.
With a smaller or larger text size setting in the visitor’s web browser.
With or without using a mouse.
Technology
Since I work full-time with web development and also have it as a hobby, this web site should be a showcase of how I think a web site should be. Therefore, the layout is elastic and works in most web browser window sizes. I also use AJAX for the search functionality, thus not requiring a post back of the whole page to see the search results.
But naturally, everything should downgrade well too. The search has a fall back that works without JavaScript and all JavaScripts used are unobtrusive, meaning that all events are applied externally from a JavaScript meaning. The effect of this is that no elements have any inline event handlers whatsoever.
It’s possible to easily navigate through the web site just using the keyboard, leaving out the dependency on using a mouse.
Something that will interest certain people out there, and definitely Anne van Kesteren, is that this web site is using strict HTML, not XHTML. The reasons? First, I’m tired of everyone using XHTML without knowing the reasons why. They just do it because their tool/-s deliver it, they’ve heard it’s cool etc.
Second, XHTML should be served as application/xhtml+xml. In my previous design, that was the case first, but since WordPress wasn’t fool-proof and I still wanted it to be user-friendly to write comments on my posts, this ended up in me having to check the web site all the time just to make sure that nothing bad had gotten through. I then went to using text/html with XHTML for that design, according to Appendix C, but knowing that my code should be valid so I could switch to application/xhtml whenever I wanted to, I hadn’t used anything intentionally that should break.
However, now I use innerHTML in my AJAX script and Google’s ads use document write; two things that don’t work with application/xhtml+xml. So, my decision to use plain old HTML is definitely thought through and a very deliberate one. Maybe some day this web site will use XHTML again, but only the future can tell.
Testing web standards
I’ve haven’t had access to an Apple computer during this whole design face. It has been coded using web standards code, well-tested CSS approaches and object detection in JavaScript. My testing in Firefox and Opera 8, two of the most standards-compliant web browsers out there, leads me to believe that it should work automatically in Safari too. Apple user? Please let me know!
So, get going now! Resize your web browser window, increase/decrease your text size setting, turn off using any CSS, try navigating using only your keyboard, turn off JavaScript and test it!
When that’s done, and your eyes have feasted on the new layout, please let me know what you think of it! π
PS. Don’t miss the two new cool map functionalities; they can be found at the bottom of the left column. DS.
PS 2. A big thank you to Henrik Box for helping me evalute my design sketches. DS.
Back in ’99 I wrote my first lines of JavaScript, having instantly fallen in love with it and what can be done. One of my first projects when I was studying in the spring back then was a small campaign web site for a flavored childrens milk called MUUmjΓΖΓΒΆlk (Moo-milk). Please note that, for apparent reasons, the web site only works in Internet Explorer and Netscape 4 (the year after I was writing AJAX-like applications :-)).
Anyway…
What I wanted to talk about are the books that really helped my JavaScript skills to evolve. The three most important ones were:
This book really gave me a thorough understanding of JavaScript and the mechanisms behind it. A book I’d recommend to anyone starting with JavaScript today.
Probably the first book about web developing I read. Introduced some cool features and inspired me to think outside the box.
At least the first two would probably still be applicable today, although they might need some updating to scripting with the DOM. I also remember reading Stefan Koch’s Vodoo’s Introduction To JavaScript.
Back in 2002 I was asked by WROX to write a FAQ about JavaScript that was published in their P2P forums. Unfortunately, after their bankruptcy and redesign, all the FAQs on their web site were removed.
And remember, folks: It’s not hard nowadays to get your script to work in different web browsers. Just use the methods and properties supplied by the DOM. The only substantial difference between Internet Explorer and all other web browsers, though, is that Internet Explorer doesn’t support the standardized event model (see link below).
Where to go from here
The first three are links with introduction to how to approach the DOM. The second two are more in-depth articles and writings about JavaScript. Happy scripting!
Recently, in a customer project, I came upon a situation where I would get a bulk of text delivered from the database through XML. Naturally, the customer wanted the text to be presented in neat paragraphs and the only way to differentiate one paragraph from another in the source text was line breaks.
I then created a JavaScript in the XSLT file to wrap every text entity separated by line breaks within p tags.
If you’re reading this, you’re probably interested in making your CSS-controlled layouts em-based, to be able to adapt the font, width of elements etc to the text size setting the user has in his/her web browser.
A colleauge of mine recently had the problem that the customer of one of the web sites she had worked on got around ten e-mails per day from complaining web site visitors that they couldn’t read the text, since it was to small.
The text size was controlled using em.
After doing some investigation, she found out that all of the complaints were from people using IE that had their Text Size setting set to Smallest. This was probably due to the users having incidentally held down the Ctrl key while scrolling with the mouse wheel (which changes the text size in many web browsers and other programs).
And since most of the web site layouts out there use a px-based font, that IE doesn’t handle correctly when it comes to text resizing, this were the only web site where they saw this “error” occur.
So she asked me if there’s any way to find out the user’s Text Size setting, to optionally warn them and to serve them an alternate style sheet where the font would be a little bit increased. I pondered about this, and came up with a pretty basic JavaScript solution for finding out the Text Size setting.
I regularly express my opinions here about how things should be developed, and now I thought it was time to share something I recently created.
In my current project, I came across the need to have a dynamic column width, i.e. a minimum width but if the editors enter some content that would be wider than it is supposed to be (through their CMS“), it should react as a table does and dynamically resize itself and its sibling column.
To generalize, there are three different standpoints web developers usually take when it comes to implementing JavaScript in a web page.
Make it JavaScript dependant
This usually means making the web site and important functionality of it dependant on the visitor having JavaScipt activated alternatively a web browser that supports JavaScript. Bad.
Have a noscript fallback
Often, in this case, the web site’s functionality is still dependant on JavaScript, but includes a noscript tag with a text explaining for those who don’t have JavaScript that they can’t use it. Better.
Not JavaScript dependant and no noscript tag
This is the ultimate scenario. JavaScript is used to progressively enchance the functionality of the web site, but all the main functionality will work without it. When it comes to the noscript tag, it’s redundant. Instead, include the necessary elements or warning texts in the code that’s initially loaded, and then use JavaScript to hide them. Best!
I reacted in two ways when I heard about his presentation and the crowd reaction:
It’s very good and about time that this is being focused on.
Even though it seems like it was a good presentation, given the slides, how come the crowd reacted that way? Shouldn’t they already know about this? The way I see it, interface developing consists of three layers, where JavaScript correspond to the behavior/interaction layer. When developing web interfaces, you should be aware of all three and the possibilities and caveats they present.
For a long time, JavaScript has had a bad reputation that I don’t think it has deserved. It’s been based on lack of knowledge and common misconceptions that has spread like a virus. Let me meet some of them:
JavaScript doesn’t work in all web browsers
This belief is based on an old era, the so-called browser wars days, when IE 4/5 and Netscape 4 were fighting for domination. And we all know how that went…
Nowadays, if you write proper scripts according to the standardized DOM, also known as DOM scripting, you will target virtually every web browser in the market. For a comparison, you will even get more widespread support than CSS 2 has!
The other day, I was at a seminar by one of the leading CMS manufacturers in Sweden, and one question was if the next version of their product would stop being JavaScript dependant, as opposed to the previous version (this is largely due to using Microsoft.NET and what it generates), or if its scripts would at least work properly cross-browser. The reply:
The problem we had was to get the scripts to work in all web browsers
The way he saw it, the problem was in the web browsers, not in the product, which upset me. At that time, I had to step in to explain that the reason why their scripts didn’t work is because Microsoft.NET’s controls generate JavaScript that is based on the scripting model Microsoft introduced with IE 4, and that’s the reason why they didn’t work in any other web browser.
If Microsoft only had taken the proper time and decision to implement proper DOM scripting, which is supported in any major web browser, as well as from IE 5 and up on PCs, things would’ve been fine. So, let’s kill this misunderstanding once and for all that has flourished for a long time. Correct written scripts will work in any web browser.
JavaScript doesn’t rhyme well with accessibility
JavaScript does rime well with accessibility, but some/many things that have been developed with JavaScript haven’t. The reason for this is web developers not being aware of how it should be done correctly. However, believe me, when it comes to writing JavaScripts every serious web developer focus as much on accessibility and standards as those people promoting it. And when JavaScript is used, be it for form validation on the client side to avoid unnecessary roundtrips, for dynamic menus or something else (why not an AJAX application?), a non-JavaScript alternative should always exist to cater for those where JavaScript isn’t a possibility.
So, how do you create a page with unobtrusive and accessible JavaScript? Humbly, I think my pictures page of my Rome trip web site is a pretty good example of how to enhance the experience for those where JavaScript is an alternative but still functional for those cases where JavaScript can’t be used.
It has a script that triggers when the page is loaded, only for those web browsers that support the document.getElementById, and this is verified through object detection. It then adds onmouseover and onmouseout events to the small images. When they are hovered, they show a larger version of the current image. What this means is that the HTML isn’t cluttered with tons of event handlers and for those who don’t have JavaScript activated/have a web browser that doesn’t support it, the small images are also linked to the same larger version of it. It also means that the script won’t throw an error in web browsers that dont have the necessary support, thanks to object detection.
So now, get out there! Write your DOM-based JavaScripts that will enhance your web sites profusively!
Trust me, it’s a whole new level that will give you a big smile when you realize what you can accomplish! π
Today is the launch of my lab web site, RobLab (yes, it’s a corny name), where I will have code, tips and tricks for anyone to use. For the moment, it only has a few things and I don’t know with what frequency I’ll be adding stuff, but that totally depends on the reception it gets. I hope the web site will act as a resource to you, and will be of use.