Как «Закрытие» влияет на мой вложенный обход dom-узлов в jQuery? - PullRequest
2 голосов
/ 18 августа 2011

Я немного понимаю закрытие, но иногда я не могу понять, как оно правильно.Я считаю, что это виновник здесь ... Так как я пересекаю это, я не уверен, является ли закрытие необходимым или возможным.

Так что я должен проанализировать некоторую внешнюю разметку, которая выглядит следующим образом:

<h2>Fried Calamari</h2>
<dd>Price:$8.95</dd>
<dd>Pan-fried calamari served with our delicious homemade tomato sauce.</dd>
<h3>Extra Sauce</h3>
<dd>Required:0 / Up To:99</dd>
<ol>
<li><dt>Extra Sauce</dt><dd>Price:$0.99</dd></li>
</ol>
<h2>Fried Zuchinni</h2>
<dd>Price:$6.95</dd>
<dd>Tossed with garlic and herbs. Served with a side of tomato sauce.</dd>
<h3>Extra Sauce</h3>
<dd>Required:0 / Up To:99</dd>
<ol>
<li><dt>Extra Sauce</dt><dd>Price:$0.99</dd></li>
</ol>
<h2>Eggplant Rollatini Appetizer</h2>
<dd>Price:$7.95</dd>
<dd>Fresh rolled eggplant filled with Ricotta and topped with tomato sauce and melted Mozzarella.</dd>
<h3>Extra Sauce</h3>
<dd>Required:0 / Up To:99</dd>
<ol>
<li><dt>Extra Sauce</dt><dd>Price:$0.99</dd></li>
</ol>
<h2>Mozzarella Sticks</h2>
<dd>Price:$6.95</dd>
<dd>Classic Mozzarella sticks served with a side of tomato sauce.</dd>
<h3>Extra Sauce</h3>
<dd>Required:0 / Up To:99</dd>
<ol>
<li><dt>Extra Sauce</dt><dd>Price:$0.99</dd></li>
</ol>
<h2>Buffalo Rock Shrimp</h2>
<dd>Price:$9.75</dd>
<dd>Crispy rock shrimp toasted in our signature buffalo sauce. Served with Blue cheese crumbles.</dd>
<h3>Extra Dressing</h3>
<dd>Required:0 / Up To:99</dd>
<ol>
<li><dt>Extra Dressing</dt><dd>Price:$0.99</dd></li>
</ol>

Вот мои js, использующие jQuery ...

$(document).ready(function(){

 $('h2').each(function(i) {
     //to hold the info
     var itemDetail = new Object();
     //h2's contain the name
     itemDetail['name'] = $(this).html();       

     // but dd's contain price description and other
     // and we need to traverse all <dd> tags for each <h2> 
     $(this).siblings('dd').each(function(){             
         var itemInfo = $(this).html();
         var priceLabel = itemInfo.slice(0,7);
         var priceValue = itemInfo.slice(7);
         if (priceLabel='Price:$'){
             itemDetail['price'] = priceValue;
         }else{
             // discard required info (leaving description)
             if (itemInfo.slice(0,9) != 'Required:')
             //descriptions don't have a label 
             itemDetail['description'] = itemInfo;
         }
     });
     console.log(itemDetail)
 }); 
}); 

, если я прохожу обходы, используя alert () для priceLabel и priceValue, логическое эхо соответствует правильным значениям (в частности, PriceValueчисло, когда priceLabel соответствует критериям, но когда я регистрирую объект, я не получаю информацию для каждой итерации внутреннего обхода. Вместо этого priceLabel равен .slice () последней итерации.

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

Ответы [ 2 ]

3 голосов
/ 18 августа 2011

Пара вопросов:

  • = выполняет присваивание , но вы использовали его для сравнения вместо == или ===
  • Вы использовали .siblings('dd'), который дает вам все элементы dd, а не только следующие соседние элементы. С текущей разметкой вы можете использовать nextUntil(':not(dd)').
 $('h2').each(function(i) {
     var itemDetail = new Object();
     itemDetail['name'] = $(this).html();       

       // ----v---get next siblings of "h2" until on that is not "dd" is reached
     $(this).nextUntil(':not(dd)').each(function(){             
         var itemInfo = $(this).html();
         var priceLabel = itemInfo.slice(0,7);
         var priceValue = itemInfo.slice(7);

              //--------v----------- use == instead of =
         if (priceLabel == 'Price:$'){
             itemDetail['price'] = priceValue;
         }else{
             if (itemInfo.slice(0,9) != 'Required:')
             itemDetail['description'] = itemInfo;
         }
     });
     console.log(itemDetail)
 }); 

EDIT:

Если ваша разметка соответствует отображаемой форме, вы можете немного сократить код следующим образом:

 $('h2').each(function(i) {
     var itemDetail = new Object();
     itemDetail['name'] = $(this).html();       

     var dds = $(this).nextUntil(":not(dd)");
     itemDetail['price'] = dds.eq(0).html().slice(7);
     itemDetail['description'] = dds.eq(1).html();
     console.log(itemDetail);
 }); 

Или еще короче, используя литерал объекта:

 $('h2').each(function(i) {
     var dds = $(this).nextUntil(":not(dd)");
     var itemDetail = {
                name: $(this).html(),
               price: dds.eq(0).html().slice(7),
         description: dds.eq(1).html()
     };
     console.log(itemDetail);
 }); 
1 голос
/ 18 августа 2011

Поскольку вы объявили itemDetail внутри функции, которую вы передали в свой первый .each, его область действия ограничена этой функцией (и функциями, которые вы создали внутри этой функции).

Кроме того, вы перезаписываете itemDetail ['price'] и itemDetail ['description'] снова и снова, когда вы шагаете по $ (this) .siblings ('dd'), это намеренно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...