【问题标题】:Create array, grouping based on child elements创建数组,根据子元素分组
【发布时间】:2016-12-10 10:36:09
【问题描述】:

我有这个 html:

<select id="this_id">
 <option value="0" class="empty-item">Choose Type</option>
 <optgroup label="FirstGrouping"></optgroup>
 <option value="2">Thing1</option>
 <optgroup label="SecondGrouping"></optgroup>
 <option value="8">Thing4</option>
 <option value="4">Thing3</option>
 <optgroup label="ThirdGrouping"></optgroup>
 <option value="7">Thing8</option>
 <option value="5">Thing9</option>
</select>

我要做的是创建一个如下所示的数组:

"data": [{
    "Label": "FirstGrouping",
    "Options": ["Thing1"]
}, {
    "Label": "SecondGrouping",
    "Options": ["Thing4", "Thing3"]
}, {
    "Label": "ThirdGrouping",
    "Options": ["Thing8", "Thing9"]
}]

optgroupoption 元素没有给定的顺序。所以基本上我需要首先将optgroup 和以下options 元素分组到data 数组中的第一个对象中。其中"Label"optgroup"Options" 是下一个optgroup 元素之前的所有option 元素。 data 内的第二个对象具有下一个 optgroup 作为其 "Label""Options" 是以下 option 元素,位于以下 optgroup 元素之前。等等。

如果optgroup 会包装 option 元素,那么我可以这样做:

var yearz = [];
var yearz2 = $('#this_id');
yearz2.each(function() {
    var thelabel = $(this).attr('label');
    var lengthch = $(this).children().length;
    var thisch = $(this).children();
    var theobj = [];
    var alls = [];
    for (var i = 0; i < lengthch; i++) {
        alls.push({
            "Value": thisch.eq(i).val(),
            "Text": thisch.eq(i).text()
        });
    }
    theobj = {
        Label: thelabel.trim(),
        Options: alls
    };

    yearz.push(theobj);
});

但 'optgroup' 不包装 option 元素。 有什么聪明的方法吗? 最好的问候

【问题讨论】:

  • 您的 HTML 是在字符串中还是在当前页面/文档中?
  • @trincot 当前页面/文档,casperjs
  • optgroups 不是应该包装他们的options 吗?
  • @sabithpocker 是的,我尝试了一些东西但没有成功。我知道如何检查.is(),如果是optgroupoption,但可以成功分组...
  • @sabithpocker 请查看我的编辑,如果optgroup 将包装option 元素。但在这种情况下不是。

标签: javascript jquery arrays casperjs


【解决方案1】:

你可以使用这个 ES5 代码:

var data = [];
var elems = document.getElementById('this_id').children;
for (var i=0; i<elems.length; i++) {
    var el = elems[i];
    if (el.tagName === 'OPTGROUP') {
        data.push({ label: el.getAttribute('label'), options: []});
    } else if(el.tagName === 'OPTION' && data.length) {
        data[data.length-1].options.push(el.textContent);
    }
}
console.log(data);
<select id="this_id">
 <optgroup label="FirstGrouping"></optgroup>
 <option value="2" style="text-indent: 10px;">Thing1</option>
 <optgroup label="SecondGrouping"></optgroup>
 <option value="8" style="text-indent: 10px;">Thing4</option>
 <option value="4" style="text-indent: 10px;">Thing3</option>
 <optgroup label="ThirdGrouping"></optgroup>
 <option value="7" style="text-indent: 10px;">Thing8</option>
 <option value="5" style="text-indent: 10px;">Thing9</option>
</select>

【讨论】:

  • 这是es6解决方案吗?
  • 是的。你需要 ES5?
  • 现在它是 ES5 兼容的。
  • 谢谢,但似乎不起作用。也许第一个 empty 选项需要跳过?第一个 optgroup 之前的 option。抱歉,好像更新之前没有添加该选项...
  • 现在是VM5207:8 Uncaught TypeError: Cannot read property 'options' of undefined(…)
猜你喜欢
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
  • 2020-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多