How to get all parent elements except for a few

Asked

Viewed 1,563 times

5

I’m in a situation where I need to take all the "parent elements" of a div, but I can’t take them all, because it would not solve my problem. I wonder if I can put a limit on getting these elements. With an example it becomes clearer. Consider the structure:

<div class="all">
    <div class="1">
        <div class="2">
            <div class="3">
                <div class="4">
                <!-- Conteúdo -->
                </div>
            </div>
        </div>
    </div>
</div>

In that case I’d like to take all the parent elements of the div with the class 4, with the exception of the class div all but I also want all those above .all. It is possible to do this via jquery?

2 answers

10


With the function parents() is simple, just put inside the function not() those elements you don’t want:

var pais = $('.4').parents().not('.all, body, html');
pais.each(function() {
  console.log('classe do pai ' +$(this).prop("tagName")+ ': ' +$(this).prop('class'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="my-section">
    <div class="0">
        <div class="all">
            <div class="1">
                <div class="2">
                    <div class="3">
                        <div class="4">
                        <!-- Conteúdo -->
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</section>

4

You already have an answer with jQuery, here is one with native Javascript. Remember that in HTML classes cannot start with numbers, I think you have given numbers only for example but I leave the warning anyway.

var getParents = (function() {
    function hasClass(el, classes) {
        var elClassList = [].slice.call(el.classList);
        return elClassList.filter(function(_class) {
            return classes.indexOf(_class) != -1;
        }).length != 0;
    }

    return function(from, not /*, not2, etc...*/ ) {
        var args = [].slice.call(arguments);
        var el = document.querySelector('.' + args.shift());
        var parents = [];
        while (el = el.parentElement) {
            if (el == document.body) break;
            if (!hasClass(el, args)) parents.push(el);
        }
        return parents;
    }
})();

console.log(getParents('c4', 'all')); // [div.c3, div.c2, div.c1]
<div class="all">
    <div class="c1">
        <div class="c2">
            <div class="c3">
                <div class="c4">
                    <!-- Conteúdo -->
                </div>
            </div>
        </div>
    </div>
</div>

I made this function that takes as first argument the class of the element where it starts, and then in the remaining arguments the other classes that you don’t want to catch. You can pass N arguments.

  • @Miguel I prefer my way :) notParent = document.querySelector(notParents[i]); weighs a lot in the Browser

  • 'Cause you really are a lot more javascript pro than I am. Although I think yours has the downside of the elements 'not' have to be classes document.querySelector('.' + args.shift())

  • But now that I think you wear it too ...document.querySelector(..., will weigh more because I do not specify the type of selector?

  • A version with a minor modification: https://jsfiddle.net/ks8hu650/1/

  • @Miguel I use document.querySelector once to get the starting point, you had inside the while, that can run many times.

  • You’re right, I was in the while and I’m in the over @Sergio

  • I’ve changed, https://jsfiddle.net/ks8hu650/2/ . Lighter

  • @Miguel better, but you’re still running .querySelector within a loop for all notParents.

  • But I think it’s the best way not to restrict myself only to classes/ids/tagname etc... Right @Sergio?

  • @Miguel you can ask a question about how to do $('.4').parents().not('.all, body, html'); in native JS :)

  • Done and challenging you a little more @Sergio :P

  • @Miguel aceite :P

Show 7 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.