I have had the facebook tooltip available as a part of my core library for a while now. However, usage on various sites highlighted certain visual errors in the way it rendered on sites with custom CSS settings for line-height and line-spacing. This (plus the ineffectiveness of the old way the tooltip arrow was injected) caused me to sit down and refactor the whole function. Look at the demo tooltip page for possible uses.

facebook, javascript, mootools, tooltip
Nathan White announced the mootools 1.2.3 release today. This is to be the last version prior to bumping everything into mootools 2.0.
Although mootools 1.2.3 is mostly about bug fixing, it does introduce an important feature: “Element: MooTools compatibility mode: the $ function is only defined if no pre-existing $ function is found. If an existing $ function is found, you can use document.id()”
In reality this means that mootools will be able to co-exist with frameworks such as jQuery (or others). It will still not work alongside Prototype, for example – extending prototypes just cannot be namespaced. Also, even though you now CAN use more than one framework at a time, you probably shouldn’t do so on the same page, its a wasteful and needless practice.
frameworks, javascript, mootools
I have had this in my pipeline a while now but it’s time to release it for whoever needs this kind of thing. The idea is simple: have an array of images that are scrolling from left to right and right to left in a containing layer with a possible click event that goes to a relevant URL.
Here is an example using some brands and a click through to their respective pages (taken from webtogs.co.uk where the original script for 1.11 resides):

The code used to generate this
// compose your data through PHP or whatever:
var mc, sdata = [{image: '4.jpg', url: '/Berghaus/', title: 'Berghaus'},
{image: '88.jpg', url: '/Big_Agnes/', title: 'Big Agnes'},
{image: '63.jpg', url: '/Brasher/', title: 'Brasher'},
{image: '35.jpg', url: '/Bridgedale/', title: 'Bridgedale'},
{image: '65.jpg', url: '/Buff/', title: 'Buff'},
{image: '3.jpg', url: '/Camelbak/', title: 'Camelbak'},
{image: '6.jpg', url: '/Craghoppers/', title: 'Craghoppers'},
{image: '93.jpg', url: '/Crumpler/', title: 'Crumpler'},
{image: '39.jpg', url: '/Deuter/', title: 'Deuter'},
{image: '86.jpg', url: '/Haglofs/', title: 'Haglofs'},
{image: '71.jpg', url: '/Helly_Hansen/', title: 'Helly Hansen'},
{image: '95.jpg', url: '/Icebreaker/', title: 'Icebreaker'},
{image: '92.jpg', url: '/Inov8/', title: 'Inov8'},
{image: '61.jpg', url: '/Jetboil/', title: 'Jetboil'},
{image: '31.jpg', url: '/Keen/', title: 'Keen'},
{image: '97.jpg', url: '/Kuhl/', title: 'Kuhl'},
{image: '48.jpg', url: '/Trangia/', title: 'Trangia'},
{image: '42.jpg', url: '/Vango/', title: 'Vango'},
{image: '44.jpg', url: '/Vaude/', title: 'Vaude'},
{image: '52.jpg', url: '/Victorinox/', title: 'Victorinox'}];
window.addEvents({
domready: function() {
mc = new ImageScrOOler(sdata, {
imagePath: "http://www.webtogs.co.uk/brands75/",
imageHeight: 85,
targetElement: $("scr"),
clickEvent: function(obj) {
window.location.href = "http://www.webtogs.co.uk" + escape(obj.url);
// can use a lightbox or whatever instead - for example, if your obj has a property .largerImage,
// you can modal / largerBox it instead of a direct url visit.
},
showProgress: false,
});
// it also supports events in case you want to do something once scroll ends...
mc.addEvent("complete", function(direction) {
console.log("hello from events, we just finished moving all the way to the " + direction);
});
},
beforeunload: function() {
mc.stop();
mc.options.targetElement.empty();
} // end domready
});
All you need to do is include your mootools more and moootools core, then imageScr00ler.js. Change as you deem fit, use as you like – any linkback or such can’t hurt. Just have a look at the source code and the possible methods and uses on the imageScrOOler example page and use your common sense. I hope somebody does find it useful, any feedback / ideas is always appreciated.
imageScrOOler, javascript, mootools
There’s yet another one of these problems that are inherently weaved deep into CubeCart that you just wouldn’t know about… It displays different versions of pages to search engines and to humans, namely–it disables the shopping basket and checkout functionality as well as the login and registration.
First of all, I have to say that troubleshooting this and finding the reason for users being unable to purchase off a CubeCart site is an absolute nightmare. When a customer says they use ‘bog standard’ IE8 and report their ‘add to basket’ button doing nothing whatsoever, you think ‘has the javascript handler gone wrong?’. You spend a lot of time trying to reproduce the problem and failing, installing various javascript exception tracking modules and, generally, being really worried about the possible extent of the problem. It’s only when you accidentally discover customers unable to purchase also lack the login/register links that you start connecting the dots…
From session.inc.php:
if (!$cc_session->user_is_search_engine() || $config['sef'] == false)
The template does not get shown to search engines? Having different versions of pages shown to users and to spiders is not only a bad enough practice (google really don’t appreciate “cloaking” techniques), there is just NO need for it whatsoever. In order to prevent spiders from indexing pages that are deemed irrelevant to e-commerce and spill page rank / relevance, they could have been disallowed from within the robots.txt file or a rel=nofollow could have been applied to all links to such pages. So, what have the clever folks at CubeCart done instead?
This boolean method from the sessions class that decides if the user is a bot or not, user_is_search_engine() compares the contents of a file called spiders.txt, filled with “known” extracts from the user agent strings of various spiders from around the web against the user agent string of the visitor. To be fair, the original idea for this kind of testing comes from OS Commerce…
The problem is when a legitimate customer is being discarded from using the site because they use a customised user agent string. Oh, and that spiders.txt has lines that reject things like:
‘googlebot’ but also just ‘google’,
‘msnbot’ but also just ‘msn’
And so forth… multiply by x number of toolbars and custom strings CubeCart may never know about and you have a HUGE problem. For instance, users with Google Desktop get their user agent string set to Mozilla/5.0 (compatible; Google Desktop) so they promptly get rejected. Luckily, that’s not a very popular application but the “MSN” string and the absolutely COUNTLESS numbers of people that have got a user agent string like this one: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; Sky Broadband; GTB6; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506; InfoPath.2; .NET CLR 3.5.21022; MSN OptimizedIE8;ENGB) presents a VERY real problem. MSN optimized IE8? Not on my shop site, mate.
I have been looking at the user sessions table and have thus far found over 3000 genuine users that have been rejected by CubeCart’s loose user agent matching routine. That’s a lot of business to lose and the owners are VERY pissed off. And rightly so, it’s not some free software and, at a testing time like the credit crunch we’re having, this is unacceptable. More so, due to the fact that people had reported the intermittent loss of shopping cart functionality on the CubeCart forums and bug / ticketing system. Reported and been rejected – apparently, too difficult to trace. And this is what is really wrong here. Everyone does mistakes, but being unable to rectify them and failing to provide support to your paying customers – it’s just bad business. I am sorry to say, CubeCart has failed to impress once again…
The fix to the CubeCart user agent problem:
1. apply nofollow to the links for login, register and checkout
2. empty the contents of spiders.txt in your cubecart root folder (don’t delete it)
or
2. change user_is_search_engine() to always return false.
To test if your store is affected, use FireFox and check this post on how to change your user agent string, set it to the one I put as an example above and visit your shopsite, then try to add a product to your basket.
CubeCart, e-commerce, spiders.txt, user agents
Aaron Newton has written up what appears to be one of the most comprehensive and unbiased answers to the eternal question: jquery or mootools. I cannot recommend it enough to anyone that’s just starting with javascript or is looking at both frameworks from the “which is better for me and my project’s needs” angle. It’s worth mentioning before you begin, this is a comparison of the core functionality, provided by each framework – not what is possible should you decide to build on it.
The short summary: both frameworks are great but serve a different purpose, with jquery is more user and beginner-friendly, focused / optimised around DOM access and mootools, building and extending the javascript native prototypes and methods (not at the expense of the things that jquery can do).
Another way to look at it: mootools takes things further than jquery and makes javascript fun, introduces features that are coming in javascript 1.8 and provides a great layer for object orientated programming whereas jquery is staying where it’s at its best: shortcuts, chaining and styling, leaving anything else you may need to plugins and vanilla javascript.
http://jqueryvsmootools.com/
The comments are also well worth the read, some good points on the pro’s and con’s of each framework and a bit on why mootools does not try to be unobtrusive / conflict free with other frameworks.
frameworks, javascript, jquery, mootools
If you happen to play games like quakelive or WOW and need your connection to be smooth and without lag, then Windows Vista is going to disappoint you. A lot…
The problem: every 60 seconds or so, Windows Vista does a wireless sweep that looks for any available wi-fi networks in your vicinity. Which is great but in doing so, Vista also causes your game to experience a huge lag spike for about 5 seconds, a gap through which you appear to be ‘warping’ to the other players. Oh, and more often than not, you also get fragged.
Over the course of a 20 minute game, that’s 18 guaranteed spikes of 5 seconds each, totalling over 90 seconds… In other words, a whopping 7.5% of your playing time is spent being lagged out… Go, Microsoft and SP1…
Looking around on Google for a fix has not been very fruitful. Turns out, way too many people get this problem and the solutions are nothing but very inconsistent–what works for one nic / router fails for others. Here is a quick summary of things you can try that I had to go through:
a resident tool called Vista Anti Lag which is said to disable the WLAN discovery. It failed to do so on my Intel chipset card, but many people swear by it. Downsides to using VAL (aside from tested support for D-Link only): it does not understand firewalls and crashes if your firewall binds to a dummy adaptor.
WLAN optimizer, yet another resident utility, reported to work by some people. Once again, did not work on my Intel 4965 card.
running as admin from shell: netsh wlan set autoconfig enabled=no interface=”Wireless Network Connection”, alleged to disable the autoconfig and to replicate the Windows XP Wireless Zero suppression… Downsides: you need to run this each time you have established connection and you need to run the opposite, netsh wlan set autoconfig enabled=yes interface=”Wireless Network Connection” to allow yourself to reconnect. Note: “Wireless Network Connection” should be whatever your have called your connection, this is just the default name. And, yes. It did not work for me.
disabling the WLAN Auto Config service. Does not work for me, drops connection and makes reconnecting impossible.
using your network card’s manufacturer bridge/connection management software instead of the windows one (in conjunction with previous idea). Intel do not provide anything with their drivers other than a diagnostics toolkit
disabling DHCP on your client. Did not work for me.
changing your wireless router’s protocol from 802.11 b/g to 802.11 g or b(legacy). Did not work for me.
installing the XP version of your nic drivers (network interface card). And yes, that also did not work for me.
So, what did work?
Great thanks need to be extended to SC2008, a user on a German forum who posted his solution called Vista Background Scan (written in Delphi) in this thread. It’s very basic and lacks a proper / intuitive interface but it does what it says on the tin… For the first time ever since I got my new Toshiba laptop, I can enjoy lag-free gaming. Thank you ever so much…

Just so that the program does not get lost, I am going to host a local mirror for it (277k).
Note: at times, VNGScan can stop working even though it’s still running. If this were to happen, simply click the button / tickboxes a few times and it will kick off again. There’s also a handy utility called Intel WIFI Advanced Statistics which can give you accurate real time data of any Acccess Point (AP) association and confirm with certainty if VBG Scan (or any of the other methods) is doing the business.

AP disocvery, games, intel, lag, spikes, vista, wifi, wireless
It may be difficult to believe but there are people out there that have yet to realise the benefits of using mootools. Recently, I tried to help out on the Digital Point javascript forums on the subject of image pre-loading via vanilla javascript. With so many SERPs on a preloading images javascript search, it’s surprising how very few scripts do a decent job. To understand why, we need to look at the possible pitfalls here but also, examine when and how image pre-loading can be of benefit and not just a gimmick… In other words do you really need it?
There are two scenarios here. Case 1: you just want to load all your images prior to displaying the rest of your page. Whether that’s because you like it this way or you need to get the browser to ‘know’ your images widths and heights first, it does not matter. The arguments for ’speeding up’ page loads are a bit moot now, with modern connections and modern browsers there are no great benefits to preloading. Either way, you need to arrange your code in a way that allows you to trigger some event or function when the loading is complete in order to continue displaying your site.
And then, there’s case 2: precognitive image loading / cache priming, which is the more interesting use. This is a relatively new trend that involves examining the user’s browsing pattern and anticipating what they do next. For instance, if they are browsing product listings as a result of a search with 100 results (20 per page), it is almost safe to assume they may want to go to page 2 or 3. It is also safe to assume the average user would take a while to finish appraising their results, scroll down and locate the ‘next’ link. This idle slot is where you can put their connection to better use by priming the browser cache with the product thumbnails of the next results page. In this instance, you don’t really care for any onload / oncomplete events, the benefits of the cache will be reaped on the next page instead.
Now, we’ve established why you may want to preload images, let’s focus on the how instead.
There are some considerations we need to be aware of here:
- It needs to be threaded and not sequential (to use the browser’s maximum threads)
- It needs to raise the browser’s onload event so we ‘tick off’ our image from our images array and / or save the new image object into a new array for later insertion
- There are differences and quirks in the way the onload event works between browsers that we need to accommodate for
- We need to clean up resources and memory, or at least not leak
Now, 2 of these are more important than the rest. First of all, it’s important to understand that you need to assign the onload event BEFORE you set the src property of the image object:
// wrong:
var image = new Image();
image.src = 'image.jpg';
image.onload = function() { // evil, won't work if image already cached, it won't trigger
...
};
// right:
var image = new Image();
image.onload = function() { // always fires the event.
...
};
image.src = 'image.jpg';
And second, in Internet Explorer, the onload event fires ALL THE TIME for animated gifs. That’s right, on each loop it fires an ‘onload’ for you. Which is why you need to make sure you release your image objects – or should you need to store them as objects into a new array – remove all onload-based events attached to them.
Anyway, without further ado, the code. I hope it makes sense – you can see it working here.
// assign images as global
var imagesArray = [
"8-0.gif",
"article-bg.gif",
"article-page-bg.gif",
"big-bg.gif"
]; // etc etc, as many image elements as you need to cache.
window.onload = function() {
// local scope. strictly speaking, images loading does not need to wait for onload, so you can change this.
// good to keep it under a namespace / anon closure if you don't use the window.onload.
var loadedImages = [], reportProgress = function(where) {
// used to show how many images loaded thus far and / or trigger some event you can use when done.
// optional to show onscreen..., 'where' should be an object referencing an element in the DOM
// to do it silently, just remove the output bits below.
var output = "loaded ";
output += loadedImages.length;
output += " of ";
output += imagesArray.length;
output += " images.";
where.innerHTML = output;
// this bit will fire when all images done:
if (imagesArray.length == loadedImages.length) {
// total images onComplete. done. rewrite as you deem fit - call your main site load function from here
// keep in mind that if 1 of your images is a 404, this function may not, you
// may want to assign onerror and onabort events
// you can loop through them (if you use the objects, then output loadedImages[x].src or inject them.
for (x in loadedImages) {
where.innerHTML += "" + loadedImages[x]; // comment this out - debug.
}
}
}, loadImage = function(imageSrc, reportDiv) {
// actual function that loads image into DOM
var image = new Image(); // local scope, new object created per instance.
image.onload = function() {
if (!image) return;
loadedImages.push(image.src); // record this image path as loaded in global scope
// or... store the objects themselves so you can inject them:
// loadedImages.push(this);
// sample report of progress
reportProgress(reportDiv, image.src);
// remove event and self to prevent IE on animated gif loops and clear up garbage.
image = image.onload = image.onabort = image.onerror = null;
};
image.src = imageSrc;
}, total = imagesArray.length, loadedProgress = document.getElementById("mydiv"); // more local variables
// loop through the images and load.
while(total-- || loadedImages.length == imagesArray.length) {
loadImage("http://fragged.org/images/" + imagesArray[total], loadedProgress, total);
}
}; // end window.onload
I really do hope this helps somebody.
best practices, IE, javascript, onload, pre-loading
Shockingly, I discovered that largerBox is our biggest keyword by far but with a 75% bounce rate… After some searching, I found www.largerboxmen.com (nofollow)–so apparently, largerBox is a modal viewer _AND_ a device that pumps blood into your mantool…
I thought it was funny anyway… so to those of you that came here looking to buy your pump, UNLUCKY. You go away with a simple image enlarging tool instead (what a pun, even if I say so myself!). Try and make it bigger here:
In other news, largerBox has received a massive update! First of all, the function interface has changed! It now is no longer a snippet, it has been namespaced and organised:
var largerBox = {
version: function() {
return 2.1; // 17/05/2009 14:18:40
},
init: function(options) {
// by default it works on image links with the class 'fullImage'
// set other defaults.
var options = $merge({
selector: "a.fullImage", // can pass on any A object or array of objects, need to contain links to images.
styleBorder: "1px solid #000", // border style around image
useShadow: false, // apply a css shadow after image is drawn
useModal: true, // use a modal window (toggleModal function) or not
useTooltip: true, // uses element.tooltip prototype (needs it defined, set to false if not avail)
colourModal: "#555", // default colour for modal,
imageBackground: "#fff", // useful to have one for png or gif with transparency
zIndex: 1000000000 // default z-index for the enlarged images
}, options);
This post uses the following code to instigate the lightbox on the image above:
largerBox.init({
selector: "a.newimage",
useModal: true,
useShadow: true,
colourModal: "#fff"
});
The style and effect are somewhat different from our traditional style, visible on the image below:
Anyway, you can grab the latest dci_core library and search for the string largerBox. Dependent functions from dci_core are toggleModal and the element.tooltip prototype, both are optional though.
javascript, largerBox
I’ve had this post in my submission bin for a while but a question of the digital point forums today prompted me to dig it out… First of all, what is the difference between a javascript exception and a javascript error? Well, my view on this is simplistic: an exception IS an error of a runtime nature that can be handled, whereas an error is typically to do with syntax and can’t be ‘caught’.
So why would we care of exception errors anyway?
Whilst programmers take every possible measure to release compliant and bug-free code for all possible browsers, the sad truth is that–for ajax-rich applications–no amount of testing can ensure things won’t break for somebody. There always will be the ‘daft’ people, their quirky old browsers (IE6, anyone?), odd plug-ins, proxies / anti-virus software, leap years and so forth–somehow managing to trigger unexpected javascript exceptions. The more traffic you get, the better the chances are for somebody to stumble upon such difficulties. What you don’t always get is people phoning up to tell you about it. Not unless it’s something critical – like the inability to add an item to a shopping basket or failure to checkout. And let me tell you, your customer services won’t be able to get any meaningful debug information.
A practical example?
Recently I got a report of a customer that was unable to checkout and for whom the ‘checkout’ button did nothing. The button itself had an onclick event assigned to it within the mooTools domready function… Surprisingly, it turned out the domready just consistently fired up earlier than expected for him, with the checkout.gif image just not being a part of the DOM at the time of the event assignment. This got me worried and made me want to try and discover other such potential deterrents to people’s browsing experience.
The solution is closer when you know your problem areas…
I created a javascript exception trapping handler and placed it around what was perceived to be the ‘dangerous / unsafe’ portions of the checkout code. The handler itself was set to use XHR (ajax) to send me the exception data via email, alongside of whatever additional data the PHP script was able to grab (browser, user info, basket contents and so forth). The results were… astonishing. This quirk was happening a fair bit more than we would have liked (1 in 30 customers). We also found out that our promo codes buttons were also being affected… The flaw in the mooTools 1.11 domready code aside, how did we fix it? By not assigning events until all the elements were available, by using load as opposed to domready for IE users and so forth.
Here is the refactored code for mootools 1.2+ instead:
var errorHandler = function(dbug) {
// trap errors and send via ajax to a script that logs them
new Request({
url: "/errorTrap.php",
data: dbug,
onComplete: function() {
$("errorOutput").set("html", this.response.text);
} // comment this function out out and the comma on the line above. data will arrive via $_POST.
}).send();
return true;
}; // end errorHandler
$("makeException").addEvent("click", function(e) {
new Event(e).stop();
try {
duffColours[2] = 0;
} catch(er) {
errorHandler(er); // install it.
}
});
And here is an example of the errorTrap.php contents, I’d advise you to do data washing/escaping as well:
<?PHP
$body = "ERROR DETAILS FOLLOW:\n\n";
foreach($_REQUEST as $key => $value) {
$body .= "$key: " . str_replace('"', '\"', $value) . "\n";
}
$body .= "\n----------------------------------------------------\nServer variables:\n\n";
foreach($_SERVER as $key => $value) {
$body .= "$key: " . mysql_escape_string($value) . "\n";
}
mail("your@email.com", "JS exception on {$_SERVER['HTTP_REFERER']}", $body);
?>
To create an exception, click here – it will send it to a file called errorTrap.php, which iterates the $_GET and $_SERVER variables before dispatching me the email
Error output here
ajax, error trapping, exceptions, javascript, mootools
Some web dev I am–thanks to google adwords I on this very site I only just noticed an advert by microsoft for downloading IE8… Not how I should have found out about it but it beats not knowing at all, I guess.
I wonder how many issues this will introduce and how complicated my life will soon become… grab it if you have to (no follow link via google)
*update* as I went over to my Microsoft Virtual PC in order to test IE8, I accidentally loaded this site in IE6 and IT WAS HORRIBLE. In particular, it failed to inherit the width of the main content div so it spilled and defaced the site each time any code got posted (affected were code, blockquote and pre tags). Sigh… apologies, reparations have been done now, I just tend to ignore IE6 even though it still amounts to almost 15% of visitors… Even though it has been fixed in part, I should perhaps think of a gentler degradation for IE6 users, one that offers them a chance to upgrade what is now an 8 years old system…
Speaking of IE6 quirks, I had to do a semantic tab system for mootools 1.11 the other day and discovered how IE6 completely messes up the display of LI elements in an ordered list when having nested elements, spilling to the whole available space on the current line instead. The only fix for this is to float the children elements as well… For example:
<li style=”float: left”><strong>this is some text</strong></li> won’t just assume the text’s width, it will span over the whole available width and will push down a line the next LI. You need to float the strong as well in order to achieve the desired effect… Pants!
css, IE6, IE8, quirks