Follow me: @D_mitar

Most read posts recently



Sep 15th 2009 × mootools colour picker: mooRainbow

I was browsing around the internet and came across Iconza by turbomilk. As it seemed rather nice and my Framework Detector Firefox add-on sniffed out mootools, I had a look at the source.

It uses what looks like a colour picker plugin for mootools called mooRainbow. Nice to have in your toolkit, you never know. Iconza’s png trickery is not too shabby either, nice site (as you’d expect from Turnomilk anyway).


Aug 4th 2009 × Don’t copy and paste my javascript blindly…

Just a quick request – if you go and use snippets of javascript code from this site, great, it’s what it’s there for.

Just please, please, don’t copy and paste my google analytics javascript into your pages as well, it kind of messes up my stats. Thanks in advance.

no

Aug 4th 2009 × Stop bot spam without OCR: hOOmanTest – a modern javascript captcha class

It has always annoyed me as a user when having to strain my eyesight and having to type weird letters or numbers in order to prove I am a human. The practice is known as ‘captcha’ and dates back a while now. Regretfully, nothing much has changed aside from the ability of the bots to OCR better – we still need to read some obtuse characters.

This is why I wrote a javascript mootools captcha class called hOOmanTest – making the whole ‘prove you are not a bot’ a lot easier to stomach. Regretfully, it has no degradation as it relies on drag and drop, but you can use reCaptcha inside your target div as the fallback and have the class apply an .empty() before populating it, providing the upper layer.

*edit*: I really do hope it helps somebody, here is the first site that uses it out there–in a quotation webform on the cleaning 4u site, click the free quote banner to view.


Aug 3rd 2009 × Enough of the jQuery already…

This is not much of a post but a bit of a rant. “It’s my party and I’ll cry if I want to”, right?

I have a problem with jQuery–not with the framework as such, but with some of its users. And who in their right mind wouldn’t be getting the amp when just about any webdev site, forum and topic is now full of clever know-it-alls that come and declare how ‘such and such jQuery plugin will do what you want’. There’s always a jQuery plugin for everything, didn’t you know…

Does not matter if the question at hand is on vanilla javascript or mootools, just add jQuery and whistle… Already use another framework? Get jQuery anyway, it’s so good you can run in compatibility mode!

The sad part is in how a large portion of these jquerysts have absolutely no understanding of vanilla javascript. It feels as if some of them inadvertently consider ‘javascript’ and ‘jQuery’ to be synonymous…

Aren”t people just getting carried away slightly? I’ll be the first to admit how jQuery is full of awesome features, documentation and support. Why, it’s so great and so far removed from standard javascript syntax that some go to extreme lengths to mimic its shorthand in other frameworks as well. Just the other, having downvoted a jQuery solution for a mootools question on stackoverflow, I was told how $(“someid”).click(); was a perfectly reasonable and valid mootools syntax (as shown by David Walsh)

Paradoxically, in lowering the standards and requirements (in the sense of, by being too accessible and too easy to use), jQuery has spawned an army of coders that don’t even have to learn javascript. A lot of badly formed code gets released, complete with a disregard for best practices, memory, bandwith use, usability and god knows what else…

Still, perhaps there will come a day when mootools sports a high-spirited in-your-face following. For we have a lot to be tooting about, after all…


Jun 22nd 2009 × facebOOkTips: mootools facebook style tooltips – update

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.


Jun 20th 2009 × mootools 1.2.3 released, bug fixes and compatibility with other frameworks

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.


Jun 12th 2009 × imageScrOOler: a mootools image thumbnails scrolling class with carousel effect

*update* 15/09/2009 – Added a new option, carousel: true|false, which creates a never-ending wrap of the image set. Check the imageScrOOler example page for more.

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):

imageScrOOler example

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.


Jun 8th 2009 × jquery vs mootools: a look at what each framework represents and how to choose wisely

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.


May 18th 2009 × Preloading images using javascript, the right way and without frameworks

Many a post on javascript forums are still on the subject of image pre-loading via vanilla javascript. With so many results on google on a simple pre-loading images via 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 to examine when and how image pre-loading can be enhancing the user experience. 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:

  1. It needs to be threaded and not sequential (to use the browser’s maximum threads)
  2. 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
  3. There are differences and quirks in the way the onload event works between browsers that we need to accommodate for
  4. 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 fire, 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.


May 2nd 2009 × our mootools largerBox modal lightbox: it makes you a better man!

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.