7

I was looking for an answer to this question, and I came up with this

stackoverflow - How do I select text nodes with jQuery?

Is there so far another way to do this ?? In my very case I'm trying to find every text node starting from a given DOM element and

empty()

it. Any suggestions ?

UPDATE - After a bit of messing I came up with this jsFiddle

Now the function selects each text node but instead of replacing only the empty ones with the new value given, it replaces all of them. What am I doing wrong ??

Alex van
  • 187
  • 1
  • 3
  • 12
  • Using `.contents()` and filtering on nodetype is the only way to get textNodes using jQuery. If you post the actual code you're using we may be able to advise you better. – Rory McCrossan Sep 09 '13 at 08:40
  • And *still* there is no good answer to this seemingly simple operation -- I've found a half-dozen other answers to essentially the same issue, that either get half way there, or miss the mark entirely. My use case is that I want to clone a table row, but I want to clear the contents of each cell, preferably before inserting into the document. I'm opening a bounty on this question, if my requirement is unclear let me know, thanks. – Dexygen Dec 03 '13 at 17:57
  • It's fine if you answer *this precise question* of course, with any hints as to how to apply it to my use case, perhaps up here in the comments. – Dexygen Dec 03 '13 at 18:07
  • 1
    Well actually the following `headerEl.after($('').append(headerEl.clone().find('td').empty()));` solved my problem, but the bounty still stands for the original question – Dexygen Dec 03 '13 at 18:24
  • @GeorgeJempty can I get some feedback on my answer? Thanks – Trevor Dec 03 '13 at 20:54
  • @AlexVan I'ts not very clear exactly what you're trying to achive, but is this in the ballpark? http://jsfiddle.net/RajB4/41/ – Rory McCrossan Dec 04 '13 at 07:40
  • Can you clarify exactly what is the desired result? – andi Dec 09 '13 at 20:21

5 Answers5

2

With reference to this 'Now the function selects each text node but instead of replacing only the empty ones with the new value given, it replaces all of them. What am I doing wrong ??'

What is required is that just test the nodeValue for whitespace using a regex and then on the basis of this proceed forward.

I have updated it like this and it works fine http://jsfiddle.net/Vj5LR/2/

$(document).ready(function(){

   var prova = ['1','2','3','4','5','6'];
   var regForNonWhiteSpace = /\S/; // non white space
   $('.example').find('*').each(function(){
       $(this).contents().filter(function(){
           //this.trim();
           if( this.nodeType === 3 && !regForNonWhiteSpace.test(this.nodeValue)){
               this.nodeValue = 'new value'; // only when there is no content at all
           }
       });
    });
});

Hope this solves the problem

tariq
  • 2,193
  • 15
  • 26
  • This is hard there is no clear winner and lots of similar answers but I have to make a decision and think I will pick this one. I do like the regex solution though I think we've turned something concise into something verbose: just inline the regex it's such a simple one: `&& !/\S/.test(this.nodeValue)` .... – Dexygen Dec 10 '13 at 13:01
1

empty() is used to empty the innerText of an element and does not apply to textNodes. Instead you need to use remove():

$('.example')
    .contents()
    .filter(function () {
    return this.nodeType === 3; //Node.TEXT_NODE
}).remove();

Example fiddle

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • Well, I'm trying to get the nodes and then empty them and replace the text inside... – Alex van Sep 09 '13 at 09:46
  • In that case you don't need to `empty()` them you can just assign a new value using `node.nodeValue = "new value";` – Rory McCrossan Sep 09 '13 at 09:51
  • @Alexvan you need to put an `each()` in after the `filter()` so you can access each node individually: http://jsfiddle.net/RajB4/15/ – Rory McCrossan Sep 09 '13 at 10:28
  • @ Rory McCrossan, yeah but this way it's replacing every single empty text node. I would like the function replaces just the old ones. The goal of it all is a simple text replacing function. – Alex van Sep 09 '13 at 10:35
  • Ok, you need to write some code in the `filter()` to exclude the cases you do not want. – Rory McCrossan Sep 09 '13 at 10:36
  • Please, have a look at my new version... I'm still missing something! – Alex van Sep 11 '13 at 16:03
1
$(document).ready(function(){

    var prova = ['1','2','3','4','5','6'];

    $('.example').find('*').each(function(){
        $(this).contents().filter(function(){
            //this.trim();
            if( this.nodeType === 3 && this.nodeValue.trim().length === 0){
                this.nodeValue = 'new value';
            }
        });
    });
});

http://jsfiddle.net/trevordowdle/RajB4/40/

Trevor
  • 16,080
  • 9
  • 52
  • 83
  • @GeorgeJempty if I understand correctly I am answering the original question.. Does this answer help you? – Trevor Dec 03 '13 at 18:55
  • 1
    Answering the original question is fine considering my problem did not turn out to be the same -- still though it got me curious. And now I see your fiddle is up to version 40 ;) – Dexygen Dec 03 '13 at 22:21
  • @GeorgeJempty Oh I just grabbed the fiddle from the update which was already version `38`, when I hit update it went to `40`. Looks like someone was working hard on this! :) – Trevor Dec 03 '13 at 22:26
  • @GeorgeJempty Is your problem different from the original question? – Selvakumar Arumugam Dec 05 '13 at 16:40
  • Yes and I've solved my problem, but only after opening the bounty on the original question. So my bounty stands *on the original question* and there seems to be a couple of good answers so far – Dexygen Dec 05 '13 at 17:38
1

What about this Demo http://jsfiddle.net/RajB4/42/

if( this.nodeType === 3 && this.nodeValue.trim().length != 0){
                this.nodeValue = 'new value';
            }
Dev
  • 6,628
  • 2
  • 25
  • 34
0

As I understood it, I think this is what you are looking for:

$('.example').each(function(){
    console.log($(this).contents());
    $(this).contents().filter(function(){
        if( this.nodeType === 1 && this.childElementCount == 0 && this.textContent == ''){
            this.textContent = 'new value';
        }
    });
});

You can check fiddle

Dharmesh Patel
  • 1,881
  • 1
  • 11
  • 12