Schrijf eens je eigen jQuery functies

Sinds enkele jaren en zeker sinds Microsoft gestart is met Asp.Net MVC heeft
jQuery een grote rol gekregen binnen de Microsoft wereld. Dit is duidelijk
zichtbaar door de sterke integratie in de Asp.Net MVC project templates, de door
Microsoft aanboden VS2010 integratie, de door Microsoft gedoneerde jQuery
templates en de sterke afhankelijkheid bij de Telerik MVC Extensions.

Waar nog maar enkele jaren geleden het schrijven van Javascript verguist
werd, is javascript en ajax momenteel HOT.

In mijn dagelijkse werkzaamheden is jQuery nu niet meer weg te denken. Toch
heb ik het idee dat ik en vele andere .Net ontwikkelaars jQuery nogal reactief
gebruiken. We schrijven wat code in de pagina ‘Ready’ functie, we binden
functies aan event, we doen wat ajax callback en we integreren leuke plugins om
de website minder spartaans te maken.

Function

En dat knaagt…

Toch heeft jQuery genoeg interessante facetten die het gebruik nog
plezieriger kunnen maken. Kijk maar eens naar het volgende voorbeeld. Ik wil
hier de link naar http://www.nu.nl/ als publieke link bestempelen. Maar zie jij
de bug?

// this code contains a bug
<html>
  <head>
    <script type="text/javascript"
            src="http://ajax.googleapis.com/ajax
                 /libs/jquery/1.6.1/jquery.min.js"></script>
  </head>
  <body>
    <a id="nupuntnl"
       href="http://www.nu.nl">Nu</a>
    <script type="text/javascript">
      $(document).ready(function() {
        $('#nuputnl').text('Public link');
      });
    </script>
  </body>
</html>

Zag u het? jQuery selectors zijn echt gaaf en kunnen heel veel werk besparen.
Met slechts een statement kan een hele verzameling DOM objecten gemanipuleerd  worden en door de fluent notatie kan diezelfde verzameling hergebruikt worden voor nog meer pret. Maar als je een typo in de selector hebt staan dan gebeurt er h-e-l-e-m-a-a-l niks.

Hierboven is de verwijzing naar de id van de link niet correct over genomen.
Het had moeten zijn:

<html>
  <head>
    <script type="text/javascript"
            src="http://ajax.googleapis.com/ajax
                 /libs/jquery/1.6.1/jquery.min.js"></script>
  </head>
  <body>
    <a id="nupuntnl"
       href="http://www.nu.nl">Nu</a>
    <script type="text/javascript">
      $(document).ready(function() {
        $('#<strong>nupuntnl</strong>').text('Public link');
      });
    </script>
  </body>
</html>

In dit geval wisten we bij het schrijven dat we één en slechts één control
wilden manipuleren. Met een klein beetje meer moeite had dit ook afgedwongen
kunnen worden.

Het is namelijk heel simpel om eigen jQuery functies te schrijven die .Net
ontwikkelaars het beste als ExtensionMethods zullen herkennen. Deze zijn dan
fluent uit te voeren op de $ (..)

De volgende jQuery functie controleert of er exact één control gemanipuleerd
wordt:

(function( $ ){
  $.fn.onlyOne = function(mode) {
    var mode = mode || 'off';
    if (mode != 'off') {
      if (this.length == 1) {
        if (mode != 'on') {
          alert('Information: one object found.' );
        }
      }
      else {
        alert('Warning: not one but '
               + this.length + ' objects expected.');
      }
    }
    // do not break the normal flow;
    return $(this);
  };
})( jQuery );

Deze functie heet OnlyOne en accepteert een string om de werking te
manipuleren. De functie staat in een apart javascript bestand die gerefereerd
zal worden.

De (function( $ ){ … })( jQuery ); is bedoeld om ruzie met andere (jQuery)
bibliotheken te voorkomen.

Als we nu de eerste (buggie) code, met deze functie uitgevoerd zouden hebben
dan krijgen we de volgende waarschuwing:

jquery functions

En de code zier er bijna hetzelfde uit:

<html>
  <head>
    <script type="text/javascript"
            src="http://ajax.googleapis.com/ajax
                 /libs/jquery/1.6.1/jquery.min.js"></script>
     <script type="text/javascript"
              src="jquery.functions.js"></script>
  </head>
  <body>
    <a id="nupuntnl"
       href="http://www.nu.nl">Nu</a>
    <script type="text/javascript">
      $(document).ready(function() {
        $('nupuntnl').<strong>onlyOne('on')</strong>
                     .text('Public link');
      });
    </script>
  </body>
</html>

Deze simpele functie maakt een hoop testen in de browser overbodig. En als
het niet meer nodig is, kan de functie zo uitgeschakeld worden.

Voor diegene die dit willen gaan toepassen, de functie accepteert vier
soorten input:

  1. ‘on’ geeft een melding als er niet fluent één object doorgegeven wordt.
  2. ‘verbose’ geeft altijd aan hoeveel objecten fluent doorgegeven worden.
  3. ‘off’ geeft nooit een melding, dit schakelt de interne logica uit.
  4. Geen parameter doorgeven is gelijk aan ‘off’. Of haal je de functie weer weg?

Een aardige variatie op de eerste function is het controleren of er één of
meer objecten doorgegeven worden met een nieuwe functie:

(function( $ ){
  $.fn.atLeastOne = function(mode) {
    var mode = mode || 'off';
    if (mode != 'off') {
      if (this.length > 0) {
        if (mode != 'on') {
          alert('Information: ' + this.length + ' objects found.');
        }
      }
      else {
        alert('Warning: At least 1 object expected.');
      }
    }
    // do not break the normal flow;
    return $(this);
  };
})( jQuery );

Als deze losgelaten wordt op drie links die dezelfde class delen:

<html>
  <head>
    <script type="text/javascript"
            src="http://ajax.googleapis.com/ajax
                 /libs/jquery/1.6.1/jquery.min.js"></script>
    <script type="text/javascript"
            src="jquery.functions.js"></script>
  </head>
  <body>
    <a id="nupuntnl" href="http://www.nu.nl">Nu</a>
    <a id="telegraaf" href="http://www.telegraaf.nl">Telegraaf</a>
    <a id="geenstijl" href="http://www.geenstijl.nl">geenstijl</a>
    <script type="text/javascript">
      $(document).ready(function() {
        $('.public').atLeastOne('verbose').text('Public link');
      });
    </script>
  </body>
</html>

In dat geval krijgen we netjes de melding dat we drie objecten gaan
manipuleren.

jquery functions

Uiteindelijk worden dan ook alle drie de links aangepast:

jquery functions

Conclusie
Natuurlijk kunnen bovenstaande functies nog uitgebreid worden. Te denken
valt aan het globaal aan of uitzetten of een extra string om de melding
specifieker te maken (bij welke aanroep gaat het exact fout).

Maar met een beetje fantasie of juist die minimale frustraties rond
jQuery kan het gebruik van jQuery functies ons dagelijkse leven iets dragelijker
maken. Wil je meer details weten, ga dan naar de jQuery site.

Advertenties