• You are currently browsing the archives for the javascript category.

  • Archive for the ‘javascript’ Category

    Maintainable JavaScript – Videos of my Fronteers talk are now available

    Saturday, October 11th, 2008

    The lovely people (check the interview to see what I mean) at Bachelor ICT just released “the videos of my talk about Maintainable JavaScript”http://www.bachelor-ict.nl/christian-heilmann at the Fronteers conference in Amsterdam:

    Here’s part one of the talk:


    Chris Heilmann: Maintainable JavaScript, part 1 from Bachelor-ict.nl on Vimeo.

    And Part 2:


    Christian Heilmann: Maintainable JavaScript, part 2 from Bachelor-ict.nl on Vimeo.

    They also interviewed me after the talk to re-iterate some of the points:


    Christian Heilmann: Maintainable JavaScript from Bachelor-ict.nl on Vimeo.

    Great job guys, thank you!

    You can find the slides of the talk at slideshare.

    Conjuring YUI from thin air

    Saturday, August 2nd, 2008

    I love the YUI loader as it is a great way of including the YUI on the fly. The coolest bits about it is that it gets the YUI components from the CDN and knows the dependencies so I don’t have to. So if I need the YUI for something, I don’t need extra SCRIPT nodes a maintainer has to include, just my SCRIPT. However, what we still need is including the YUI loader itself.

    Unless… you use the YAHOO_config listener. This thing is older than both YUI get and YUI Loader and is an object method that gets called every time a YUI component is loaded. So why not load the YUI Loader using this?

    One problem is that the YUI Loader doesn’t call the config listener saying it is a loader, but saying it is the get utility. Another issue is that it does not work to execute the Loader immediately after it called itself “get”. The workaround is to use a timeout.

    Wrap all of that inside the YAHOO_config object and you’ll conjure the YUI out of thin air. The following example loads YUI Dom, YUI Event and alerts “done” once all is ready. Check it out here

    
    YAHOO_config = function(){
      var s = document.createElement('script');
      s.setAttribute('type','text/javascript');
      s.setAttribute('src','http://yui.yahooapis.com/2.5.2/'+
                     'build/yuiloader/yuiloader-beta-min.js');
      document.getElementsByTagName('head')[0].appendChild(s);
      return{
        listener:function(o){
          if(o.name === 'get'){
            window.setTimeout(YAHOO_config.ready,1);
          }
        },
        ready:function(){
          var loader = new YAHOO.util.YUILoader();
          var dependencies = ['yahoo','dom','event'];
          loader.require(dependencies);
          loader.loadOptional = true;
          loader.insert({
            onSuccess:function(){
              console.log('done!');
            }
          });
        }
      };
    }();
    

    Thanks to Alex Liu to get the setTimeout trick.

    The missing native DOM methods – according to my course attendees

    Thursday, July 31st, 2008

    During the course I am currently giving in Sunnyvale on basics of the DOM and progressive enhancement I asked the attendees which methods seem to be missing in the native DOM implementation and this is what we came up with:

    • createLink(url,text) – a shortcut method to create a link with a text node inside – something you constantly have to do when creating interfaces
    • insertAfter(newNode,oldNode) – there is an insertBefore, but no insertAfter
    • removeNode(node) – the native removeChild is convoluted
    • textElement(elementName,text) – it seems not necessary to create an Element, then create a text node and apply it, this could be one step
    • addScript(url) – to lazy-load JavaScripts
    • normalizeNode(node) – to remove those pesky line-breaks that interfere with nextSibling or previousSibling
    • getText(node) – retrieving the text content of a node that is either a text or an element node
    • setText(node,text) – setting the text regardless of node type

    I asked the attendees to come up with a method each and to present them, here’s what we got:

    
    jukuhelpers = function(){
      function createLink(url,text,cssClass){
        var link =  document.createElement('a');
        if (typeof url === 'string'){
          link.setAttribute('href', url);
        }
        if (typeof text === 'string'){
           link.appendChild(document.createTextNode(text));
        }
        if (typeof cssClass === 'string'){
          link.className = cssClass;
        }
        return link;
      }
      function insertAfter(newNode,oldNode){
        oldNode.nextSibling
          ? oldNode.parentNode.insertBefore(newNode, oldNode.nextSibling)
          : oldNode.parentNode.appendChild(newNode);
      } 
      function removeNode(node){
        if (node) {
          node.parentNode.removeChild(node);
        }
      }
      function textElement(elementName,text){
        if (typeof text === 'string'){
          var txtElement = document.createElement(elementName);
          var txtNode = document.createTextNode(text);
          txtElement.appendChild(txtNode);
        }
      return txtElement;
      }
      function addScript(url){
        var s = document.createElement('script');
        s.setAttribute('type', 'text/javascript');
        s.setAttribute('src', url);
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(s);
      }
      function getText(node){
        var txt;       
        if (node && node.nodeType === 1) {
          if (node.hasChildNodes()) {
            txt = node.firstChild.nodeValue;
          }
        }
        if (node && node.nodeType === 3) {
          txt = node.nodeValue;
        }
        return txt;
      }
      function setText(node,text){
        if (node && node.nodeType === 1) {
          if (node.hasChildNodes()) {
            node.firstChild.nodeValue = text;
          }
          else {
            node.appendChild(document.createTextNode(text));
          }
        }
        if (node && node.nodeType === 3) {
          node.nodeValue = text;
        }
      }
      function normalizeNode(node){
        if(node.hasChildNodes){
          var spaceTest = /^\s+$/;
          var children = node.childNodes;
          for(var i=0;children[i];i++){
            if(children[i].nodeType === 3){
              if(spaceTest.test(children[i].nodeValue)){
                children[i].parentNode.removeChild(children[i]);
              }
            }
          }
        }
      }
      return{
        createLink:createLink,
        insertAfter:insertAfter,
        removeNode:removeNode,
        textElement:textElement,
        addScript:addScript,
        getText:getText,
        setText:setText,
        normalizeNode:normalizeNode
      }
    }();
    

    You can get the jukuhelpers.js file if you want to use it yourself.

    Anything else that is missing or any bugs in this?

    @mediaAjax 2008 site is live

    Tuesday, July 1st, 2008

    @mediaAjax Just like last year, Patrick Griffith managed to assemble quite an impressive group of JavaScript experts to talk about all things Ajax and Scripting. This year’s schedule reads very nicely indeed and I am happy to see that all aspects of using JS are covered, including a session by Richard Rutter of clearleft on how to wireframe Ajax interactions.

    This is especially welcome to me, as JavaScript is so omnipresent in web development these days that we all need to know about it and bring in our different skills to make great products. JavaScript should not shock Information Architects and Designers, but help them make things easier for the end users.

    This also ties in nicely with my session which is, not to anyone’s surprise on using JavaScript to increase the accessibility of products, named Scripting Enabled, the same as the event I am organizing revolving around the same topic:

    Scripting Enabled The relationship of JavaScript and accessibility has never been a good one. A lot of myths circulating around the use and capabilities of assistive technology branded JavaScript as a bad technology and Ajax as a total faux pas. This is changing as a lot of companies now open their systems to developers with APIs that are Ajax and JavaScript driven. This session will explain how some of these can be used to make data available to users with disabilities that were blocked out before. Accessibility is first and foremost about removing barriers for users, regardless of ability. Using JavaScript and Ajax to work around accessibility issues of rich media applications is one way of doing that. It is like creating mash-ups to test out some APIs – only that the benefit is much higher than just proving a point.

    I am looking forward to @mediaAjax, having had a great time there last year. I might be a bit knackered though, as I will be at the Fronteers conference in Amsterdam just a few days before :)

    How to stop event delegation(obvious fact #12132)

    Monday, June 9th, 2008

    This was a question I got in the office today and there is no shame in asking it:

    I am using Event Delegation on one of my products and I need to stop the main handler on the body from firing when I click a certain button. How do I do that?

    The answer is of course to use stopPropagation() or cancelBubble(), both nicely wrapped in YAHOO.util.Event.stopPropagation():

    HTML:

    
      <form id="buttons">
        <p><input id="tease" type="button" value="click me, wuss!"></p>
        <p><input id="tease2" type="button" value="click me, wuss! (I bubble)"></p>
        <div id="littlesnitch"></div>
      </form>
    

    JavaScript:

    
    YAHOO.util.Event.onContentReady('buttons',function(){
      YAHOO.util.Event.on(document.body,'click',function(e){
        var t = YAHOO.util.Event.getTarget(e);
        snitch('<p>It was the ' + t + ' that was clicked</p>');
      });
      YAHOO.util.Event.on('tease','click',function(e){
        snitch('<p>that was the first button</p>');
        YAHOO.util.Event.stopPropagation(e);
      });
      YAHOO.util.Event.on('tease2','click',function(e){
        snitch('<p>that was the second button</p>');
      });
      function snitch(msg){
        document.getElementById('littlesnitch').innerHTML += msg;
      }
    });
    

    Try it out here: Overriding Event Delegation with stopPropagation

    Wait till I come! is the blog of Christian Heilmann , a developer evangelist living and working in London, England. Download vcard.

    Feed me, Seymour: Entries (RSS) and Comments (RSS).