2010-11-17 4 views
4

J'écris ma propre méthode de liaison JavaScript (pour la pratique) et je n'arrive pas à résoudre le besoin de gérer différemment des objets individuels et des objets multiples dans cette méthode, uniquement parce que je dois parcourir des objets d'une longueur supérieure à un. (voir obj vs obj [i] ci-dessous)Comment gérer des objets de longueur 1 et supérieure à 1 dans une méthode sans redondance

Est-il possible de rendre cette méthode de liaison moins redondante? (s'il vous plaît assumer à l'aide d'une autre bibliothèque est hors de question .. merci)

var foo = (function() { 
    return { 
     bind: function (obj, type, handler, delegate) { 
      var delegate = delegate || false, 
       len = obj.length; 
      if (typeof obj == 'undefined') { 
       return false; 
      } 
      if (len > 1) { 
       for (var i = 0; i < len; i++) { 
        if (obj.addEventListener) { 
         obj[i].addEventListener(type, handler, delegate); // false: bubble (^). true: capture (v). 
        } else if (obj.attachEvent) { 
         obj[i].attachEvent('on' + type, handler); 
        } else { 
         obj[i]['on' + type] = handler; 
        } 
       } 
      } else { 
       if (obj.addEventListener) { 
        obj.addEventListener(type, handler, delegate); // false: bubble (^). true: capture (v). 
       } else if (obj.attachEvent) { 
        obj.attachEvent('on' + type, handler); 
       } else { 
        obj['on' + type] = handler; 
       } 
      } 
     } 
    } 
})(); 
+0

Votre code ne fonctionnera pas pour les tableaux à un seul élément. – SLaks

+0

J'avais à l'origine installé des méthodes de getElementByClass() pour retourner l'objet réel s'il avait une longueur de un. commencer à penser que c'était une idée stupide maintenant. Cela a essentiellement créé le besoin de lancer cette vérification dont vous parlez. – tester

Répondre

1

Concat obj avec un tableau vide:

obj = [].concat(obj) 
2

Vous pouvez forcer dans un tableau:

if (!('length' in obj)) 
    obj = [ obj ]; 

for (var i = 0; i < obj.length; i++) { 
    if (obj[i].addEventListener) { 
     obj[i].addEventListener(type, handler, delegate); // false: bubble (^). true: capture (v). 
    } else if (obj[i].attachEvent) { 
     obj[i].attachEvent('on' + type, handler); 
    } else { 
     obj[i]['on' + type] = handler; 
    } 
} 
+0

+1 en 20 minutes, quand je reçois mes votes ... (Même si je n'aime pas votre omission de parenthèses bouclées sur la déclaration if.) – lonesomeday

0

Sans comprendre pleinement votre code, je dirais que si vous avoir seulement 1 objet, il devrait toujours être contenu dans un tableau, et donc une seule itération se produirait. Il ne devrait pas être nécessaire de prendre en compte le cas singulier.

Vous devriez vérifier le cas singulier et le convertir en un tableau avec une seule entrée:

if (obj.constructor.toString().indexOf("Array") == -1) { 
    obj = [obj]; 
} 
+0

À droite, je supposais qu'il pouvait comprendre que si l'objet est singulier, à Convertissez-le en tableau. Je vais modifier en conséquence. –

1

Vous pouvez tester obj pour voir si elle a une propriété nodeType. Si oui, placez-le dans un tableau.

if(obj.nodeType) { 
    obj = [ obj ]; 
    //... 

ou vous pouvez faire une concat sur un tableau vide.

obj = [].concat(obj); 

Cela vous donnera un tableau si vous n'en avez pas.


donc votre code final pourrait ressembler à ceci:

var foo = (function() { 
    return { 
     bind: function (obj, type, handler, delegate) { 
      var delegate = delegate || false 
      if (typeof obj == 'undefined') { 
       return false; 
      } 
      obj = [].concat(obj); 
      for (var i = 0, len = obj.length; i < len; i++) { 
       if (obj[i].addEventListener) { 
        obj[i].addEventListener(type, handler, delegate); // false: bubble (^). true: capture (v). 
       } else if (obj.attachEvent) { 
        obj[i].attachEvent('on' + type, handler); 
       } else { 
        obj[i]['on' + type] = handler; 
       } 
      } 
     } 
    } 
})(); 
Questions connexes