2013-01-28 1 views
1

Я хочу иметь множество элементов «infoItem», каждый из которых имеет свой собственный jQuery, который ими управляет. Может ли кто-нибудь сказать мне, почему, когда я называю «displayText()», что элементы внутри этой функции не те элементы в элементе, который содержит обработчик кликов, но всегда элемент LAST на странице?Как вызвать метод из jQuery .click() и сохранить контекст?

enter image description here

<html> 
    <head> 
     <script type="text/javascript" src="systemJavascript/jquery-1.8.3.min.js"></script> 
    </head> 
    <body> 
     <div class="infoItem"> 
      <div class="menu"> 
       <span class="menuOne">one</span> 
       <span class="menuTwo">two</span> 
      </div> 
      <div class="content">intro message</div> 
     </div> 
     <div class="infoItem"> 
      <div class="menu"> 
       <span class="menuOne">eins</span> 
       <span class="menuTwo">zwei</span> 
      </div> 
      <div class="content">Introtext</div> 
     </div> 
    </body> 

</html> 
<script type="text/javascript"> 

    var INFOITEM = INFOITEM || {}; 

    INFOITEM.initialize = function(infoItem) { 
     var elemMenuOne; 
     var elemMenuTwo; 
     var elemContent; 

     this.defineVariables = function() { 
      elemMenuOne = infoItem.find('.menuOne'); 
      elemMenuTwo = infoItem.find('.menuTwo');    
      elemContent = infoItem.find('.content');    
     } 

     this.decorateElements = function() { 
      elemMenuOne.css('background-color', 'beige'); 
      this.decorateAsLink(elemMenuOne); 
      elemMenuTwo.css('background-color', 'beige'); 
      this.decorateAsLink(elemMenuTwo); 
     } 

     this.functionalizeElements = function() { 
      that = this; 
      elemMenuOne.click(function(e) { 
       that.displayText('ONE'); 
      }); 
      elemMenuTwo.click(function(e) { 
       that.displayText('TWO'); 
      }); 
     } 

     this.displayText = function(text) { 
      elemContent.html('you selected ' + text); 
     } 

     this.decorateAsLink = function(elem) { 
      elem.css({ 
       'cursor' :'pointer', 
       'text-decoration' : 'underline', 
       'font-weight' : 'normal' 
      }); 
     } 

     this.defineVariables(); 
     this.decorateElements(); 
     this.functionalizeElements(); 
    } 


    $('.infoItem').each(function(){ 
     INFOITEM.initialize($(this)); 
    }); 

</script> 
+0

Когда вы вызываете 'INFOITEM.initialize', вы устанавливаете' this.defineVariables' функции. Каждый раз, когда вызывается 'initialize',' defineVariables' заменяется на новую функцию. Итак, после цикла 'each'' defineVariables' является функцией, связанной с последним элементом. –

ответ

3

INFOITEM является глобальной переменной, так что вы перезагружаем это для каждого элемента вашей страницы, так что это всегда указывает на последний элемент:

$('.infoItem').each(function(){ 
     INFOITEM.initialize($(this)); 
    }); 

Вы бы быть лучше выключив его в структуру типа Jquery pluin, а затем привязывая его к одному элементу и передавая связанный элемент.

Вот bolierplate, чтобы вы начали:

http://stefangabos.ro/jquery/jquery-plugin-boilerplate-revisited/

0

Как я решил эту проблему, чтобы добавить идентификатор к каждому элементу, и в замковом событий, получать этот пункт еще раз, что я могу тогда перейти к любому методу, где я могу манипулировать им надлежащим образом, а не внутренние переменные.

<html> 
    <head> 
     <script type="text/javascript" src="systemJavascript/jquery-1.8.3.min.js"></script> 
    </head> 
    <body> 
     <div id="infoItem_123" class="infoItem"> 
      <div class="menu"> 
       <span class="menuOne">one</span> 
       <span class="menuTwo">two</span> 
      </div> 
      <div class="content">intro message</div> 
      <div class="contentOne">you clicked one</div> 
      <div class="contentTwo">you clicked two</div> 
     </div> 
     <div id="infoItem_456" class="infoItem"> 
      <div class="menu"> 
       <span class="menuOne">eins</span> 
       <span class="menuTwo">zwei</span> 
      </div> 
      <div class="content">Introtext</div> 
      <div class="contentOne">du hast auf eins geklickt</div> 
      <div class="contentTwo">du hast auf zwei geklickt</div> 
     </div> 
    </body> 

</html> 
<script type="text/javascript"> 

    var INFOITEM = INFOITEM || {}; 

    INFOITEM.initialize = function(infoItem) { 
     var elemMenuOne; 
     var elemMenuTwo; 
     var elemContent; 
     var elemContentOne; 
     var elemContentTwo; 
     var itemId; 

     this.defineVariables = function() { 
      elemMenuOne = infoItem.find('.menuOne'); 
      elemMenuTwo = infoItem.find('.menuTwo');    
      elemContent = infoItem.find('.content');    
      elemContentOne = infoItem.find('.contentOne');    
      elemContentTwo = infoItem.find('.contentTwo');    
      itemId = infoItem.attr('id'); 
     } 

     this.decorateElements = function() { 
      elemMenuOne.css('background-color', 'beige'); 
      this.decorateAsLink(elemMenuOne); 
      elemMenuTwo.css('background-color', 'beige'); 
      this.decorateAsLink(elemMenuTwo); 
      elemContentOne.hide(); 
      elemContentTwo.hide(); 
     } 

     this.functionalizeElements = function() { 
      that = this; 
      elemMenuOne.click(function(e) { 
       that.displayText($('#'+itemId), elemContentOne.html()); 
      }); 
      elemMenuTwo.click(function(e) { 
       that.displayText($('#'+itemId), elemContentTwo.html()); 
      }); 
     } 

     this.displayText = function(clickedInfoItem, text) { 
      clickedInfoItem.find('.content').html(text); 
     } 

     this.decorateAsLink = function(elem) { 
      elem.css({ 
       'cursor' :'pointer', 
       'text-decoration' : 'underline', 
       'font-weight' : 'normal' 
      }); 
     } 

     this.defineVariables(); 
     this.decorateElements(); 
     this.functionalizeElements(); 
    } 


    $('.infoItem').each(function(){ 
     INFOITEM.initialize($(this)); 
    }); 

</script> 
Смежные вопросы