我有一个与此类似的HTML表单(请注意,它是由选项卡、可选字段集和字段元素组织的):
每个div都是一个或多个input元素的容器,但对于这个问题,我将重点放在容器上。
我正在尝试编写一个JavaScript函数,该函数将“遍历”指定的HTML元素,并以这种格式生成JSON对象 (注意基于表单的选项卡、字段集和输入元素形成的嵌套):
{
"content":
[
{
"type": "tab",
"id": "left-defaults1",
"order": 1,
"content":
[
{
"id": "fieldset-3",
"order": 1,
"type": "fieldset",
"content": [
{
"id": "container308",
"order": 1,
"type": "field"
},
{
"id": "container314",
"order": 1,
"type": "field"
},
{
"id": "fieldset-4",
"order": 1,
"type": "fieldset",
"content": [
{
"id": "container309",
"order": 1,
"type": "field"
},
{
"id": "container310",
"order": 1,
"type": "field"
}
]
}
]
},
]
},
{
"type": "tab",
"id": "left-defaults2",
"order": 2,
"content":
[
{
"id": "fieldset-1",
"order": 1,
"type": "fieldset",
"content": [
{
"id": "container311",
"order": 1,
"type": "field"
},
{
"id": "fieldset-2",
"order": 1,
"type": "fieldset",
"content": [
{
"id": "container313",
"order": 1,
"type": "field"
},
{
"id": "container312",
"order": 1,
"type": "field"
}
]
}
]
}
]
},
{
"type": "tab",
"id": "left-defaults3",
"order": 3,
"content":
[
{
"id": "container315",
"order": 1,
"type": "field"
},
{
"id": "container316",
"order": 1,
"type": "field"
}
]
}
]
}我遇到了通过第二层的问题。我可以识别要“遍历”的HTML元素,并可以将"tab“级别建立到JSON对象中。我还可以将下一层的字段集或字段元素推入其中。但除此之外,我迷失了方向;我不知道如何在JSON对象中定位给定的第三层的父层(或第四层的父层,或第五层的父层,等等)。
这个JavaScript是该尝试的核心:
var createNestedJSON = function(){
//establish JSON object
var tab_order = 0,
form_content_nested_and_ordered = {'content': []},
element_ii_object = {};
//so we can retrieve them in the order they exist in the page, class as "JSONMe" all the things we are going to want to represent in form_content_nested_and_ordered
$('#fmWkflw').find('.tab-option-container').addClass('JSONMe').find('li').addClass('JSONMe');
$('.JSONMe').each(function(element_index){
var $this = $(this).data('JSON_id', element_index);
console.log('tag:'+ this.tagName +', id:'+ this.id +', parentId: '+ $this.parent().prop('id') +', className: '+ this.className);
if( this.tagName === 'UL' ){
//this is a tab; add it
form_content_nested_and_ordered["content"].push( {'type': 'tab', 'id': this.id, 'order': ++tab_order, 'content' : []} );
console.log('added tab');
}
else {
element_ii_object = {
'id': this.id,
'order': 1,
'type': 'field'
};
if( $this.hasClass('fieldset') ) {
//this is a fieldset, so it has type "fieldset" and a "content" array
element_ii_object.type = 'fieldset';
element_ii_object.content = [];
}
console.log(element_ii_object);
form_content_nested_and_ordered.content[ tab_order-1 ]['content'].push( element_ii_object );
console.log('added '+ element_ii_object.type);
};
});
/*
form_content_nested_and_ordered["content"][getIndexIfObjWithOwnAttr(form_content_nested_and_ordered["content"], 'id', 2)]['content'].push( {'type': 'field', 'id': 14, 'order': 12} );
form_content_nested_and_ordered["content"][getIndexIfObjWithOwnAttr(form_content_nested_and_ordered["content"], 'id', 1)]['content'].push( {'type': 'field', 'id': 23, 'order': 7} );
form_content_nested_and_ordered["content"][getIndexIfObjWithOwnAttr(form_content_nested_and_ordered["content"], 'id', 1)]['content'].push( {'type': 'field', 'id': 24, 'order': 8} );
*/
//tear down
$('#fmWkflw').find('.JSONMe').data('JSON_id', 0).removeClass('.JSONMe');
return form_content_nested_and_ordered;
};我试着切换到reduce(),但是像一个铅气球一样起飞。
发布于 2020-06-19 17:51:46
据我所知,您必须进行递归,因为您不知道递归的级别,所以这里有一个示例,希望这能帮助您。
function copyTree(originalTree){
return originalTree.map((elem, index) => ({
id: 'div.'+elem.id,
content: !elem.content ? [] : this.copyTree(elem.content),
}));
}编辑:我想得到你想要的东西,这是你想要得到的东西,我希望这能帮到你。
代码的一些解释:我使用querySelectorAll是因为它返回一个您可以迭代的NodeList,...arr的原因是
如果对象是可迭代的,它将使该对象的数组退出。更多的例子是过滤器或映射NodeList
在此之后,我要做的是创建一个递归调用的函数,以便将内容推送到找不到更多的匹配。
var getIndexIfObjWithOwnAttr = function(array, attr, value) {
for(var i = 0; i < array.length; i++) {
if(array[i].hasOwnProperty(attr) && array[i][attr] === value) {
return i;
}
}
return -1;
};
var createNestedJSON = function(){
//establish JSON object
var tab_order = 0,
form_content_nested_and_ordered = {'content': []},
element_ii_object = {};
//so we can retrieve them in the order they exist in the page, class as "JSONMe" all the things we are going to want to represent in form_content_nested_and_ordered
$('#fmWkflw').find('.tab-option-container').addClass('JSONMe').find('li').addClass('JSONMe')
var htmltest = document.querySelectorAll('.JSONMe')
form_content_nested_and_ordered = function (arr){
return [...arr].map((elem, index) => ({
type: elem.localName,
id: elem.id,
content: elem.children && elem.children.length>0 && (elem.localName ==='li' || elem.localName ==='ul' || elem.localName ==='fieldset') ? form_content_nested_and_ordered(elem.children) : [],
}));
}
//console.log(form_content_nested_and_ordered(htmltest))
var filtered = form_content_nested_and_ordered(htmltest).filter((x)=>{
return x.type == 'ul'
})
return filtered;
};
$('#formSubmit').click(function(){
$('#resulting_JSON')[0].innerHTML = JSON.stringify(createNestedJSON());
});
https://stackoverflow.com/questions/62475645
复制相似问题