将数据属性从一个元素传递到另一个元素

时间:2017-12-02 10:02:45

标签: javascript html

我有两个主要的html元素。第一个是一组选项,第二个是ul,我在其中显示内容,如下所示:

<optgroup style="display:none;" class="groupOfOptions">
  <option value="15" data-upsell="presentation1">
    Item 1
  </option>
  <option value="3" data-upsell="presentation2">
    Item 2
  </option>
  <option value="5" data-upsell="presentation3">
    Item 3
  </option>
</optgroup>

<ul class="displayedList">
  <li>
   <label>
     <input value="15" type="radio"> 
     Item 1         
   </label>
  </li>
  <li>
   <label>
     <input value="3" type="radio"> 
     Item 2         
   </label>
  </li>
  <li>
   <label>
     <input value="5" type="radio"> 
     Item 3         
   </label>
  </li>
</ul>

我尝试做的是将data-upsell-type中的optgroup分配到ul列表中。如果li项具有与value中的某个option元素相同的文本(第1项,第2项,第3项)或optgroup输入,则取{来自该data-upsell项的{1}}并将其分配给特定的option元素。

这就是我的尝试:

li

然而,没有任何反应,也没有错误让我分析。有人可以看看这个吗?

2 个答案:

答案 0 :(得分:0)

var objWithData = document.getElementsByClassName('groupOfOptions')[0];
objWithData = objWithData.getElementsByTagName('option');
var listToModify = document.getElementsByClassName('displayedList')[0];
listToModify = listToModify.getElementsByTagName('li');

var listObj = {};

for (var i = 0; i < listToModify.length; i++) {
  var el = listToModify[i];
  var text = el.innerHTML.replace(/<[^>]*>/g, "").replace(/\\n/g).trim();
  var value = el.getElementsByTagName('input')[0].value;
  if(!listObj[text]){
    listObj[text] = [];
  }
  listObj[text].push(el);
  if(!listObj[value]){
    listObj[value] = [];
  }
  listObj[value].push(el);  
}

for (var i = 0; i < objWithData.length; i++) {

  var el = objWithData[i];
  var text = el.innerHTML.replace(/\\n/g).trim();
  var value = el.value;
  var data = el.getAttribute('data-upsell');
  if(listObj[text]){
    listObj[text].forEach(function(v){
      v.dataset.upsell = data;
    })
  }
  if(listObj[value]){
    listObj[value].forEach(function(v){
      v.dataset.upsell = v.dataset.upsell || data;
    })
  }
  
}
<optgroup style="display:none;" class="groupOfOptions">
  <option value="15" data-upsell="presentation1">
    Item 1
  </option>
  <option value="3" data-upsell="presentation2">
    Item 2
  </option>
  <option value="5" data-upsell="presentation3">
    Item 3
  </option>
</optgroup>

<ul class="displayedList">
  <li>
   <label>
     <input value="15" type="radio"> 
     Item 1         
   </label>
  </li>
  <li>
   <label>
     <input value="3" type="radio"> 
     Item 2         
   </label>
  </li>
  <li>
   <label>
     <input value="5" type="radio"> 
     Item 3         
   </label>
  </li>
</ul>

答案 1 :(得分:0)

我要做的是,将groupOfOptions内的选项循环一遍,构建一些查找对象。然后,使用查找对象循环遍历displayedList li个元素,看看它们是否需要加售价值:

&#13;
&#13;
// the [...iterable] syntax is just converting the NodeList that querySelectorAll
// returns into an array using the ES6 spread operator. If you can't/don't want
// to use ES6 you could leave it a NodeList and loop over it with a normal
// for loop instead of .forEach like I will below.
//
// The selector .groupOfOptions [data-upsell] looks for all of the elements
// inside of groupOfOptions that have a data-upsell attribute, the option
// elements we want.
let optionNodes = [...document.querySelectorAll('.groupOfOptions [data-upsell]')],
 textLookup = {},
 valueLookup = {};
 
 // build lookup tables
 optionNodes.forEach(function (el) {
   let text = el.textContent.trim(),
     upsell = el.dataset.upsell,
     value = el.value;
     
   textLookup[text] = upsell;
   valueLookup[value] = upsell;
 });
 
 // get the li elements inside of displayedList
 let listItems = [...document.querySelectorAll('.displayedList li')];
 
 listItems.forEach(function (li) {
   let text = li.textContent.trim(),
     value = li.querySelector('input').value,
     textResult = textLookup[text],
     valueResult = valueLookup[value];
   // If we found an upsell for text or value
   if (textResult || valueResult) {
     // use the valueResult, fallback to the textResult if there was no valueResult
     li.dataset.upsell = valueResult || textResult;
     // Just for presentation purposes in this answer,
     // I'm also adding it to the title so you can mouse over
     // the list items and see what upsell value they got
     // without needing to inspect the DOM with dev tools.
     li.title = valueResult || textResult;
   }
   
 });
&#13;
<optgroup style="display:none;" class="groupOfOptions">
  <option value="15" data-upsell="presentation1">
    Item 1
  </option>
  <option value="3" data-upsell="presentation2">
    Item 2
  </option>
  <option value="5" data-upsell="presentation3">
    Item 3
  </option>
</optgroup>

<ul class="displayedList">
  <li>
   <label>
     <input value="15" type="radio"> 
     Item 1         
   </label>
  </li>
  <li>
   <label>
     <input value="3" type="radio"> 
     Item 2         
   </label>
  </li>
  <li>
   <label>
     <input value="5" type="radio"> 
     Item 3         
   </label>
  </li>
</ul>
&#13;
&#13;
&#13;

  • 有关spread
  • 的更多信息
  • 我使用let代替var。在这段代码中它并不重要,但在大多数情况下使用let是个好习惯。 let现在fair well supported,甚至回到IE11。
相关问题