0

This is probably a long shot but is there a way to get a collection of elements in JQuery or not without a specific tag/class/id, even the nested ones?

Let's say I have this piece of code:

<div class="container1">
    Lorem ipsum dolor sit amet
    <br><br>
</div>

<p>This is p 1
    <div class="footer">
       tessssst
        <p>
            p test
        </p>
    </div>
</p>

<div class="container">
    tessst
</div>

<p>This is p 2
    <div id="someID" class="container">
        tessssst 2
    </div>
</p>

Now, I'm using JQuery like this, in order to find all but div tags, including descendants:

$('body').find(':not(div, div *)')

In the result collection, I still get the div inside the p elements and I don't want that. Is there any way to achieve that? I know that this div is part of h1 and since I just want to select elements and not removing or doing DOM manipulations it could be a weird thing to wish for but this is what I need.

The bigger problem - I need to retrieve all text nodes but to exclude some tags/classes/IDs. I'm doing so as suggested here but it's not good enough.

Thanks.

Community
  • 1
  • 1
mrgoos
  • 1,294
  • 14
  • 26
  • 1
    You can start writting good semantical code. You should close `h1` after the end of the string and don't append all that don't are part of a heading. – Marcos Pérez Gude Oct 01 '15 at 13:36
  • It's just an example. Imagine that the div is inside a p element. Here, I've changed it to 'p' just for you :) – mrgoos Oct 01 '15 at 13:37
  • Well, I have to say that putting it in h1 got me to this misunderstanding... After switching from h1 to p, this is working! Placing the div in the h tag messes up with the selectors I guess. Cheers. – mrgoos Oct 01 '15 at 15:14

4 Answers4

0

The code you provided seems to work, but maybe you could try this?

$('body').find("*").filter(":not(div)");
Tempestas Ludi
  • 1,113
  • 9
  • 24
0

There is a jQuery function not(), which removes matching elements from the current set.

So all you need to do is

var nonDivs = $('body').find('*').not('div');
Cedric Reichenbach
  • 8,970
  • 6
  • 54
  • 89
0

You can do that by first selecting all elements, then selecting <div>s and their descendants, and filtering the "all" results with the "divs" result using .not() (the red style is used to mark the matched set):

var all = $('body').find('*');
var divAll = $('body').find('div, div *');

var nonDiv = all.not(divAll);

nonDiv.css('color', 'red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container1">
    Lorem ipsum dolor sit amet
    <br><br>
</div>

<p>This is p 1
    <div class="footer">
       tessssst
        <p>
            p test
        </p>
    </div>
</p>

<div class="container">
    tessst
</div>

<p>This is p 2
    <div id="someID" class="container">
        tessssst 2
    </div>
</p>
Amit
  • 45,440
  • 9
  • 78
  • 110
  • Wow I really don't understand it. I tried your solution - bottom line it's working. But I don't understand why. If I'm trying this piece of code in Chrome: 'var all = $('body').find('*'); var divAll = $('body').find('div, div *'); all.not(divAll);' I get the collection BUT I can still see the div in the collection, same as happened to me and I thought that it doesn't work. If, for example you try '.text()' on this collection you'll still get the text in the div which is not good. I don't need the text in the div. – mrgoos Oct 01 '15 at 14:26
  • But if I do that: '$('body').find(':not(div, div *)').contents().filter(function(){return this.nodeType == 3})' - then, for some reason it is working, I get only the text that I want. I have no clue why. Do you have any thought? – mrgoos Oct 01 '15 at 14:26
  • What I meant in sort, this is working: $('body').find(':not(div, div *)').css('color', 'red'); But this will bring all the text, including the ones that are in the nested div(s): $('body').find(':not(div, div *)').text(); I guess I will open a new question for that. – mrgoos Oct 01 '15 at 14:49
  • @mrgoos - it turns out your original code is fine (`$('body').find(':not(div, div *)')`), so I'm not really getting the problem. What do you mean *I can still see the div in the collection*? can you explain how you're *seeing* it? and what undesirable effect it has? since either using my method, or yours, you can manipulate all non-div nodes, which is what you asked for. – Amit Oct 01 '15 at 18:54
0

In the filter function check if it's a text node and also check all of its parents for class, id, tag name - whatever selectors you would like to filter by.

var textnodes = $('body').find("*").contents()
    .filter(function () {
        return (this.nodeType === 3 && $(this).parents("div").length <= 0);
    })
    .each(function () {
        console.log($(this).text());
    });

Here's a working example: https://jsfiddle.net/hracw15o/3/

Olena Vikariy
  • 217
  • 1
  • 3
  • 9
  • 1
    Thanks but for some reason this works too, still don't understand why... $('body').find(':not(div, div *)').contents().filter(function(){return this.nodeType == 3}); – mrgoos Oct 01 '15 at 14:50
  • Ah yes that does work. Find() gives you all the nodes except divs, contents() gives you all immediate children of those nodes and filter() only returns text nodes - that's why it works. – Olena Vikariy Oct 01 '15 at 15:24