2013-04-18 8 views
0

Disons que j'ai 10 divs avec des ID uniques. Lorsque je clique sur un élément dans chaque élément, je souhaite afficher un div superposé et y insérer du contenu basé sur l'ID de la div originale.Quelle est la meilleure façon d'écrire la population de contenu?

Est-il préférable de faire:

$('#inventory > div').find('i.icon-plus').on('click', function(){ 
    $('#add-item').slideDown(100); 
    if ($(this).parent('div').attr('id') == '#id1') { 
     // load unique template 
     // or 
     // create form content here 
    } 
    else if ($(this).parent('div').attr('id') == '#id2') { 
     // load other unique template 
     // or 
     // create other form content here 
    } 

    ... 

    else if ($(this).parent('div').attr('id') == '#id10') { 
     // load other unique template 
     // or 
     // create other form content here 
    } 
}); 

Ou:

$('#inventory > div#id1').find('i.icon-plus').on('click', function(){ 
    $('#add-item').slideDown(100); 
    // load unique template 
    // or 
    // create form content here 
}); 
$('#inventory > div#id2').find('i.icon-plus').on('click', function(){ 
    $('#add-item').slideDown(100); 
    // load unique template 
    // or 
    // create form content here 
}); 

... 

$('#inventory > div#id10').find('i.icon-plus').on('click', function(){ 
    $('#add-item').slideDown(100); 
    // load other unique template 
    // or 
    // create other form content here 
}); 

? Fondamentalement, ce que je demande est: est-il préférable d'avoir un seul gestionnaire d'événements avec une tonne d'instructions if/else ou une tonne de gestionnaires d'événements sans instructions if/else, ou cela n'a-t-il même pas d'importance?

+3

Je vous recommande personnellement à l'aide d'un gestionnaire d'événements, la mise en cache du 'this.parentNode.id' et en utilisant un' switch' base sur ce 'id'. Cependant, pouvez-vous définir «mieux» en contexte? Et, accessoirement: [JS Perf] (http://jsperf.com/). –

+1

Cela semble être un bon sujet pour un test [JSPerf] (http://jsperf.com/). –

+0

Merci! Je ne savais pas à propos de ce petit outil soigné. – tenub

Répondre

2

Je vous suggère d'utiliser on pour déléguer vos gestionnaires d'événements au parent, évitant ainsi que jQuery doive attacher des gestionnaires à chaque i.icon-plus.

Ensuite, utilisez une carte de gestionnaires avec des identifiants comme des clés avec des fonctions qui exécutent leur code correspondant. De cette façon, vous n'ajouterez pas beaucoup d'instructions if. Chaque «cas» peut contenir du code qui se répète et qui, si nous le savions, pourrait être optimisé davantage. si la div référencée par #inventory > div,

//add handles here, with id as the key and a 
//corresponding function that does what its supposed to do 
var handles = { 
    '#id1' : function(){/*do something*/}, 
    '#id2' : function(){/*do something*/}, 
    ... 
} 

//let's cache this one as well 
var addItem = $('#add-item'); 

$('#inventory > div').on('click','i.icon-plus', function(e){ 

    //get the corresponding handler 
    var handler = handles[$(this).parent('div').attr('id')]; 

    //return if the handler isn't defined for this id 
    if(!handler) return; 

    //otherwise, execute. the context and arguments are passed on 
    addItem.slideDown(100); 
    handler.apply(this,arguments); 
}); 

Cela peut encore être optimisé qui est notre: Mais puisque nous ne savons pas ce que chaque bloc des fonctions mappées faire, voici le code générique qui devrait servir le même but delegate target, est la même div que $(this).parent('div'). Dans ce cas, il peut être remplacé pour réduire les appels de fonction:

$(this).parent('div').attr('id') 

//can be replaced by 

$(e.delegateTarget).attr('id') 
1

Essayez ceci:

$("#inventory").children("div").on("click", "i.icon-plus", function (e) { 
    console.log(e.delegateTarget.id); 
    // Do your logic based on e.delegateTarget.id 
}); 

DEMO:http://jsfiddle.net/7kyGP/

Cela lie un événement à chacun des "parent" (cible) <div> éléments. Vous utilisez .parent() dans votre code, mais vous utilisez .find() pour obtenir le <i>. C'est un peu contradictoire parce que .find() obtient des descendants ... donc .parent() ne sera pas nécessairement ce que vous pensez que c'est si le <i> est imbriqué. Avec ce code, les éléments <i> ne doivent pas nécessairement être des enfants immédiats - ils peuvent être des descendants.

l'intérieur du gestionnaire, this fait référence à l'élément <i> spécifique cliqué, alors que e.delegateTarget fait référence à l'élément que l'événement est en fait lié à - les enfants <div> s de #inventory. Bien sûr, vous pouvez utiliser jQuery pour manipuler la cible avec $(e.delegateTarget).

0

Je pense qu'il ya une approche plus générique ici - si vous pouvez ajouter les données dont vous avez besoin d'attributs pour vous permettre de charger le modèle unique, ou de créer du contenu de forme alors pas besoin de beaucoup d'instructions if ou de plusieurs gestionnaires d'événements.

HTML

<div id="inventory"> 
    <div id="id1" data-template-url="subform1.htm"> 
     ... some content 
     <i class="icon-plus"></i> 
    <div> 
    <div id="id2" data-template-url="subform2.htm"> 
     ... some content 
     <i class="icon-plus"></i> 
    <div> 
    <div id="id3" data-panel-id="panel3"> 
     ... some content 
     <i class="icon-plus"></i> 
    <div> 
</div> 

<div id="panel3" class="hide-until-required"> 
... panel content 
</div> 

JAVASCRIPT

$('#inventory > div').find('i.icon-plus').on('click', function() { 
    $('#add-item').slideDown(100); 

    var templateUrl = $(this).parent('div').attr('data-panel-id'); 
    // or 
    var panelId = $(this).parent('div').attr('data-template-url'); 

    // do something with template or panel data 
}); 
Questions connexes