检索不在其他子元素中的子元素

时间:2016-09-19 13:30:25

标签: javascript jquery

我需要一种方法来检索给定元素的元素,这些元素不是某些其他元素的子元素。区分这些"父母"元素我一直在使用数据属性。

这是我以下HTML结构的示例:

<form method="post" data-component-id="3">
<table border="0">
    <thead>
        <tr>
            <th></th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Date of Birth (dd/mm/yyyy)</th>
            <th>Sex</th>
        </tr>
    </thead>
    <tbody>
        <tr data-component-id="8">
            <td>Spouse</td>
            <td><input name="txtFirstName_1" type="text" maxlength="255" id="txtFirstName_1" data-mapping-id="Person.Firstname"></td>
            <td><input name="txtLastName_1" type="text" maxlength="255" id="txtLastName_1" data-mapping-id="Person.Lastname"></td>
            <td><input name="txtDOB_1" type="text" maxlength="10" id="txtDOB_1" data-mapping-id="Person.Birthday"></td>
            <td>
                <select name="ddlSex_1" id="ddlSex_1" data-mapping-id="Person.Sex">
                    <option value=""></option>
                    <option value="Male">Male</option>
                    <option value="Female">Female</option>
                </select>
            </td>
        </tr>
        <tr data-component-id="9">
            <td>Child</td>
            <td><input name="txtFirstName_2" type="text" maxlength="255" id="txtFirstName_2" data-mapping-id="Person.Firstname"></td>
            <td><input name="txtLastName_2" type="text" maxlength="255" id="txtLastName_2" data-mapping-id="Person.Lastname"></td>
            <td><input name="txtDOB_2" type="text" maxlength="10" id="txtDOB_2" data-mapping-id="Person.Birthday"></td>
            <td>
                <select name="ddlSex_2" id="ddlSex_2" data-mapping-id="Person.Sex">
                    <option value=""></option>
                    <option value="Male">Male</option>
                    <option value="Female">Female</option>
                </select>
            </td>
        </tr>
        <tr data-component-id="9">
            <td>Child</td>
            <td><input name="txtFirstName_3" type="text" maxlength="255" id="txtFirstName_3" data-mapping-id="Person.Firstname"></td>
            <td><input name="txtLastName_3" type="text" maxlength="255" id="txtLastName_3" data-mapping-id="Person.Lastname"></td>
            <td><input name="txtDOB_3" type="text" maxlength="10" id="txtDOB_3" data-mapping-id="Person.Birthday"></td>
            <td>
                <select name="ddlSex_3" id="ddlSex_3" data-mapping-id="Person.Sex">
                    <option value=""></option>
                    <option value="Male">Male</option>
                    <option value="Female">Female</option>
                </select>
            </td>
        </tr>
    </tbody>
</table>
<input type="button" name="submit" value="SUBMIT">

注意 :有两个data-component-id="9"属性的原因是因为我将此属性视为后端中用于映射目的的类型。 (8 =配偶数据,9 =儿童数据)

我创建了一个JavaScript函数,它接受一个元素并递归地构建一个Component对象,包含一个ID,一个字段数组和子组件(递归)。

// Component Object
function Component(componentID, fields, subComponents) {
    this.ComponentID = componentID; // Numeric
    this.Fields = fields; // Array
    this.Components = subComponents; // Array
}

// Recursively build component (and sub-components)
$.fn.formDataToComponent = function() {
    var componentID = $(this).attr("data-component-id");
    var componentName = "";
    var fields=[];
    var subComponents=[];
    var subComponentsIndex=0;

    // Recursively create the sub components
    $(this).find("[data-component-id]").each(function(oSubComponent){
        subComponents[subComponentsIndex] = $(oSubComponent).formDataToComponent();
        subComponentsIndex++;
    });

    $(this).find('[data-mapping-id]').each(function() {
        // $(this).find('[data-mapping-id]') will retrieve all elements with the data attribute (therefore 12 elements will be selected)
        // With the list of these elements, I want to select ONLY those which are closest to the parent element with the attribute "data-component-id". 
        // Therefore in this particular scenario I only want to select the 4 elements of each "tr" element with each recursive call. 
        // I need to do so in a way that is dynamic and is based on the data attribute as I'll be using this with various forms. 
    });

    return new Component(componentID, componentName, fields, subComponents);
}

我已经看过在jQuery中使用.not()函数,但我认为这不符合我的想法。我将继续寻找解决方案,但如果有人知道这样做的简单/有效方式,我将非常感谢您的帮助!

解决方案

  

要解决您的问题,请在此处查看jQuery的.filter函数:http://api.jquery.com/filter/

// Get list of sub components
var subComponentArray = $(this).find("[data-component-id]");

// Get all fields that are not within the sub components
$(this).find('[data-mapping-id]').filter(function(){ 
    return $(this).closest(subComponentArray).length === 0;}).each(function(index) {
        // DO STUFF
    }); 

2 个答案:

答案 0 :(得分:1)

要解决您的问题,请在此处查看jQuery的.filter函数:

http://api.jquery.com/filter/

并做这样的事情:

$(this).find('[data-mapping-id]').filter(function(){ 
    return $(this).closest("[parent selector you don't want]").length === 0;
 }).each(function() { .... }); 

答案 1 :(得分:0)

可以使用not()。如果您只想在Field内嵌套Child,可以使用Root,Child和Field标记作为示例:

$('Field').not("Root > Field');

这将排除Field

的直接子项Root

目前尚不清楚您要过滤的内容