An easy way to manipulate data off dom using jQuery

When you’re working with javascript you need to take the execution speed into account since its all being processed on the client. There are lots of best practices when it comes to working with websites. You should for example always minify and concatenate your scripts, and make good use of closures and avoid polluting the global scope.

Another thing you should keep in mind is to keep as much big changes to the DOM offside the DOM. This is because every time you change something the browser needs to calculate a lot of things again (repaints and reflows) and more importantly, every query to the DOM is very slow.

If you need to change a part of the page you need to do this of course, and you can’t get around it when you want to animate stuff (when CSS3 is no possibility). But when you want to update a large amount of data on the page (at the same time) it’s best to temporary take that part off the dom, update everything you want and put it back on the dom. This way you don’t have a reflow / repaint on every manipulation.

This can easily be achieved by using jQuery.

//instead of doing:
$('#container').find('p').each(function(i) {
   $(this).append('this is p ' + i);
});

Keep in mind that you need to know the parent element to which you want to append (or prepend) it later on. Notice how I chain it all together, by using .appendTo instead of .append we can use the current working set we have already instead of saving it into a variable.

more

Posted at March 06, 2012, under jQuery.

How to ajaxify your WordPress theme

When building a custom WordPress based website for a client I needed to include AJAX based page transitions into the website. In this video I’ll explain a little about how I did it.

In the video I’ll explain some simple principles I followed like graceful degration and don’t break the back button.

Here is the code that makes it happen.

These are the ajax checks inside page.php to serve only the content to an ajax call:

if(!$GET['ajax']) 
   getheader();

// code to get the content

And here is the javascript:

Edit: This is a small revision of the code in the video, it only contains code to make the transitions happen. You can find the original code in the video here.

/* Author: Mike van Rossum */
$(function(){
  var $footer = $('#footer'),
    url = $footer.data('url'),
    $book = $('#innerBook'),
    speed = 200,
    $menu = $('.menu');
  if(Modernizr.hashchange) {
    var baseLength = url.split('/').length,
      ajaxPage = function() {
        $book.children().fadeOut(speed);
        $.get(location.href.replace(/#/,") + '?ajax=true', function(data) {
          //insert the data into the page and fade it in
          $book.html(data).children().hide().fadeIn(speed);
          if($('#pageData').data('title') === 'Portfolio') {
            $book.addClass('portfolio');
            log('a');
          } else {
            $book.removeClass('portfolio');
            log('b');
          }
        });
      }
    if(location.hash)
      ajaxPage();
    // if a direct page get's loaded we want to reload the homedir and ajax it:
    //    http://website.com/page
    // to
    //    http://website.com/#page
    var loc = location.href;
    if(loc != url && !/#/.test(loc)) {
      var redirect = location.href.split('/');
      redirect[baseLength -- 1] = '#' + redirect[baseLength -- 1];
      redirect = redirect.join('/');
      location = redirect;
    }
    // convert all links to the website from
    //    http://website.com/page
    // to
    //    http://website.com/#page
    $menu.find('a').add('.ajax').each(function() {
      $(this).attr('href', function() {
        var url = $(this).attr('href').split('/');
        url[baseLength -- 1] = '#' + url[baseLength -- 1];

    return url.join('/');
  });
});
// bind ajax to hashchange
$(window).on('hashchange', function() {
  ajaxPage(location.href.replace(/#/,'') + '?ajax=true');
});

Sharing JSON data between jQuery and PHP using Ajax

When building interactive websites I often find the need to send or receive data after a page load. Ajax is the perfect solution for this problem, as it permits data sharing between the front end (javascript) and the backend (PHP) in the background.

Why would I need Ajax?
When you you start using Ajax it opens endless possibilities for your website, think about autoupdating a page (timing), showing specific content on a click or adding new content on a scroll (for example when scrolled to the bottom), or logging details (think Google Analytics).

When you use jQuery you can use a couple of very powerful build in functions to make Ajax a breeze.

more

Posted at February 06, 2012, under jQueryPHP.

Animeer kleuren via jQuery

Als je veel met jQuery werkt sta je soms versteld als je erachter komt dat er dingen zijn die niet standaard mogelijk zijn met de uitgebreide javascript library. Zo liep ik gister tegen het probleem dat ik kleuren wou animeren via jQuery maar dit standaard niet mogelijk is.

Als uitbreiding op jQuery kan je jQuery UI integreren in je website, maar ik vond hem nogal groot en lomp. Helemaal als je hem puur inlaadt voor de kleuranimatie’s.

Hier is de jQuery color plugin van een aantal developers die erg betrokken zijn bij jQuery. Ook al is de enige functionaliteit van de plugin kleuren animaren, hij is alsnog best groot. Hij biedt allemaal extra functionaliteit die soms handig kan zijn, maar in mijn geval alsnog overbodig was.

Na wat zoeken vond ik op stackoverflow een oplossing die perfect leek. Je ript gewoon de kleuren functie uit jQuery UI en je hebt een perfecte oplossing. Helaas kon ik dit op deze manier niet werkend krijgen: in de functie wordt namelijk een aantal keer verwezen naar een colors array die niet mee geript was. Hier is de functie zodanig dat hij bij mij wel werkt:

/* stripped from jquery UI 1.9pre /
function getColor(a,b){var c;do{c=$.curCSS(a,b);if(c!=""&&c!=="transparent"||$.nodeName(a,"body"))break;b="backgroundColor"}while(a=a.parentNode);return getRGB(c)}function getRGB(a){var b;if(a&&a.constructor===Array&&a.length===3)return a;if(b=/rgb(s([0-9]{1,3})s,s([0-9]{1,3})s,s([0-9]{1,3})s)/.exec(a))return[parseInt(b[1],10),parseInt(b[2],10),parseInt(b[3],10)];if(b=/rgb(s([0-9]+(?:.[0-9]+)?)%s,s([0-9]+(?:.[0-9]+)?)%s,s([0-9]+(?:.[0-9]+)?)%s)/.exec(a))return[parseFloat(b[1])2.55,parseFloat(b[2])2.55,parseFloat(b[3])2.55];if(b=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))return[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)];if(b=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(a))return[parseInt(b[1]+b[1],16),parseInt(b[2]+b[2],16),parseInt(b[3]+b[3],16)];if(b=/rgba(0, 0, 0, 0)/.exec(a))return colors["transparent"];return colors[$.trim(a).toLowerCase()]}$.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(a,b){$.fx.step[b]=function(a){if(!a.colorInit){a.start=getColor(a.elem,b);a.end=getRGB(a.end);a.colorInit=true}a.elem.style[b]="rgb("+Math.max(Math.min(parseInt(a.pos(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var colors={black:[0,0,0],blue:[0,0,255],green:[0,128,0],red:[255,0,0],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]}

Als je deze functie na jQuery inlaadt (hij past jQuery aan) en voor je eigen script kan je kleuren ook animeren.

Hieronder is een voorbeeld waar ik de achtergrond kleur animeer on hover (ik gebruik de .on functie in plaats van hover omdat er in mijn geval dynamisch content wordt ingeladen nadat dit script wordt uitgevoerd).

if(!Modernizr.csstransitions) {
    $('#blog-posts').children()
        .on('mouseenter', { color: '#eeeeee' }, fadeBg)
        .on('mouseleave', { color: '#ffffff' }, fadeBg);
}
function fadeBg(e) {
    $(this).stop().animate({ backgroundColor: e.data.color }, 400 );
}

Zoals je ziet is er een if die checkt of een bepaalde waarde juist is of niet. In mijn geval wil ik een achtergrond animeren on hover, dit kan ik ook doen met CSS3. Ik gebruik modernizr om te checken of de browser de CSS3 eigenschap transition ondersteund, als de browser het ondersteund wordt de klasse .csstransitions aan mijn html tag toegevoegd en wordt bovenstaande boolean in de if check op true gezet.

Als de browser de eigenschap ondersteund doe ik de animatie via css:

.csstransitions #blog-posts a.blog-post {
    background-color:#ffffff;
    moz-transition: background-color .4s;
    -webkit-transition:background-color .4s;
    -o-transition: background-color .4s;
    -ms-transition: background-color .4s;
    transition: background-color .4s;
}

Note

Op het moment van schrijven is er een bug in chrome die ervoor zorgt dat animeren via CSS3 niet werkt zodra je de link al bezocht heb. Zie deze twee bugs.

Posted at January 03, 2012, under jQuery.