我们正在使用一个框架来创建由属性data-type=[some data type]
标识的任意嵌套的HTML数据元素。其中每个都可以包含直接输入字段以及其他data-type
,可以是单例或数组。嵌套结构的唯一保存优势是data-type
在任何深度都不会包含相同类型的data-types
。
HTML 必须使用
<div data-type='project' id='example1'>
<input name='start-date'/>
<div data-type='project-lead' id='example2'>
<input name='department'/>
<input name='email'/>
<div data-type='analyst'>
<input name='department'/>
<input name='email'/>
</div>
<div data-type='analyst'>
<input name='department'/>
<input name='email'/>
</div>
<div data-type='analyst'>
<input name='department'/>
<input name='email'/>
</div>
</div>
<div class="JustToMakeMyLifeMoreDifficult">
<div data-type='sponsor'>
<input name='department'/>
<input name='email'/>
</div>
<div data-type='sponsor'>
<input name='department'/>
<input name='email'/>
</div>
</div>
</div>
选择器问题
我需要一个JQuery查找选择器,它在给定对象下面获取data-type
元素集合data-type
级别的集合:
myData($obj){
return $obj.find('[data-type]').not([data-type elements further down]);
}
这样:
myData($('#example1'))
myData($('#example2'))
分别产生jquery结果:
[project-lead,sponsor,sponsor]
[analyst, analyst, analyst]
JQuery向导,请帮帮我。你是唯一可以的人。
回答
使用JQuery选择器是不可能的。我将下面帕特里克非常优雅的解决方案包含在一个通用的JQuery函数中 -
(function( $ ){
$.fn.dataChildren = function(_selector) {
var iter = this;
var res = this.children(_selector);
while ( ( iter = iter.children(':not(' + _selector +')') ).length ) {
res = res.add(iter.children(_selector));
}
return res;
};
})( jQuery );
那样:
$('#example1').dataChildren('[data-type]')
如上所述工作。我&lt; 3 SO。
答案 0 :(得分:2)
编辑2:我认为这就是您所需要的:
var el = $('#example1');
var res = el.children('[data-type]');
while ( ( el = el.children(':not([data-type])') ).length ) {
res = res.add(el.children('[data-type]'));
}
这个递归深入,但是当找到 data-type
的元素时,任何子分支上的递归都会停止,所以只要有一个孩子执行不有data-type
。
如果我使用do-while
循环,可能会更容易理解,并展开一些代码:
var el = $('#example1'); // el is the current level
var res = $(); // res holds the result
var data_types; // holds the children with data-type for the current level
do {
// from current level, get children with data-type
data_types = el.children('[data-type]');
// add those to the result set
res = res.add( data_types );
// make the current level be the children of the current level that
// do NOT have data-type
el = el.children().not( data_types );
} while( el.length ); // continue as long as the new current level
// has at least one element
编辑: 我可能误解了一部分。
看起来data-type
的元素可能包含data-type
的子元素。如果是这种情况,请将选择器更改为:
var ex = $('#example1');
var res = ex.find('> [data-type], > * > [data-type]');
所以总结一下,它会说所有具有data-type
属性的孩子和孙子。
原始回答:
如果我理解您希望有data-type
的孩子以及非data-type
的孩子,则您需要添加data-type
的孩子。
var ex = $('#example1');
var res = ex.find('> [data-type], > :not([data-type]) > [data-type]');
第一个选择器是:
'> [data-type]'
...将获得具有data-type
属性的孩子。
第二个选择器是:
'> :not([data-type]) > [data-type]'
...首先会让不的孩子拥有data-type
,但是那些会让他们的孩子做拥有{{1} }}
这看起来像你想要的吗?
答案 1 :(得分:1)
执行所需操作并返回匹配元素数组的POJS函数是:
function getNodes(id) {
var el = (typeof id == 'string')? document.getElementById(id) : id;
var result = [];
var node, nodes = el.childNodes;
var prop = 'data-type';
var tag = 'div';
for (var i=0, iLen=nodes.length; i<iLen; i++) {
node = nodes[i];
if (node.tagName && node.tagName.toLowerCase() == tag) {
if (node.getAttribute(prop)) {
result.push(node);
} else {
result = result.concat(getNodes(node));
}
}
}
return result;
}
然而,我不确定你是否希望它像这个一样深。它可以修改为仅达到某个深度(比如一个或两个级别)。
答案 2 :(得分:0)
此
$obj.find('> [data-type]');
如果我的问题得到解决,应该有效。
选择器'> [data-type]'
的意思是“给我所有定义了'数据类型'的元素,这些元素是容器的直接子元素。
答案 3 :(得分:0)
$obj.children().map(function () {return this.name;})
也许?