简体   繁体   中英

Selecting relative child tags jquery

I am currently new to JavaScript (I am using jQuery) and I was wondering how I could select all the children Something tags from the following HTML

<Something attribute="first">
    <div class="container">
        <Something attribute="second" />
        <Something attribute="third">
            <Something attribute="fourth" />
        </Something>
    </div>
</Something>
<Something attribute="fifth">
    <Something attribute="sixth" />
</Something>

I had code like so to select both the child Something tags

$("Something[attribute='first']").children("Something").each({});

but this does not work because of the div in between. How can I bypass all tags that are not Something and select only those elements that are one level deep if you remove all the tags that are not Something ? So if I want to query the children of the Something tag with attribute first I would get second and third (not fourth or sixth ). Similarly if I query fifth I would get sixth

NOTE Sorry for being unclear about this but I only want the Something tags one level after the Something tag whose children I am trying to find. So for example in the above HTML I do not want the query to return the Something tag with attribute fourth . So in essence if you strip out the tags in between every other Something tag I want the tags that are only one level deep from the one in question .

NOTE There can be other tags in between the Something tags, not just the one div . For example the above can be

<Something attribute="first">
    <div class="container">
        <div class="container">
            <Something attribute="second" />
            <Something attribute="third">
                <Something attribute="fourth" />
            </Something>
        </div>
    </div>
</Something>
<Something attribute="fifth">
    <div>
        <div>
            <Something attribute="sixth" />
        </div>
    </div>
</Something>

and the same selection criteria would apply. So the results would be

first -> [second, third]
third -> [fourth]
[fifth] -> [sixth]

A recursive solution in pseudocode for what I want would be

function get_immediate_children_for(element, array_of_children) {
    $(element).children().each(function() {
        if (this.tagName == "SOMETHING") {
            array_of_children.push(this);
        }
        else {
            get_immediate_children_for(this, array_of_children);
        }
    });
}

and you would call this as so

var array_of_children = get_immediate_children_for($("Something[attribute='first']")); 

JSFiddle: https://jsfiddle.net/qdhnfdcx/

var elem = document.getElementsByTagName("something");

function getChildren(name) {
    var list = []
  var len = name.length;

  for (var i = 0; i < len; i++) {
    if(name[i].parentElement.className != name[i].className) {
      for (var j = 0; j < len; j++) {
        return list.push(name[i].children[j]));
      }
    }
  }
}

getChildren(elem);

Do the following:

var allChildren = document.getElementsByTagName("Something");

Then you can simply select the corresponding index:

allChildren[0];
allChildren[1];

Or you could loop and edit all of them:

for (var i = 0, len = allChildren.length; i < len; i++) {
  allChildren[i].style.display = "none";
}

If you want certain somethings not to appear then do:

for (var i = 0, len = allChildren.length; i < len; i++) {
  if(allChildren[i].getAttribute("attribute") != "fourth") {
    allChildren[i].style.display = "none";
  }
}

If you only want the something tags one level after the something tags:

for (var i = 0, len = allChildren.length; i < len; i++) {
  if(allChildren[i].className == allChildren[i].parentElement.className) {
    allChildren[i].style.display = "none";.
  }
}

EDIT (due to edited question)

If you want a single level after the child of a specific element, then use something like this:

$("Something[attribute='first']").children("div").children("Something").each({});

Instead of .children() use .find()

(from jquery docs)

The .children() method differs from .find() in that .children() only travels a single level down the DOM tree while .find() can traverse down multiple levels to select descendant elements (grandchildren, etc.) as well.

var smth = document.getElementsByTagName('Something')[0];
var chindren = smth.getElementsByTagName('Something');
for(var i = 0, el;el = children[i];++i){
//do what you want
}

Edit 1 (final)
I answered to the first edition of the question.
Possible answer is to convert / read current document as XML and manage accordingly. Or parse inner/outerHTML to a node tree. There are a lot of pitfalls on both ways (including browser comatibility, at least) but it is the only approach to the problem.

$("Something").each(function() {
var childSomething = $(this).find("Something");
$.each(childSomething,function() {
//do something
});
});

You can use jquery find function to achieve that. Like this:

$("Something[attribute='first']").find("div > Something").each({});

Thanks for the answers! I do not believe that jQuery or Javascript either have a native way to do this but a simple recursive solution to this would be

function get_immediate_children_for(element) {
    var array_of_children = [];
    get_immediate_children_for_helper(element, array_of_children);
    console.log(array_of_children);
    return array_of_children;
}
function get_immediate_children_for_helper(element, array_of_children) {
    $(element).children().each(function() {
        console.log(this.tagName);
        if (this.tagName == "ACTIVITY") {
            array_of_children.push(this);
            console.log(array_of_children);
        }
        else {
            get_immediate_children_for_helper(this, array_of_children);
        }
    });
}

So that now get_immediate_children_for($("Activity[path='']")) would return the elements one level deep ignoring all other tags

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM