views:

1145

answers:

3

I got a markup with the following structure :

<body>
  <h1>Title</h1>
  <p>bla</p>
  <div>
    ... <!-- a thousand tags -->
  </div>

  <div id="do-not-modify-me">
   <!-- a hundred tags -->
  </div>

</body>

I wish to do a little search an replace in the body, but this must not change #do-not-modify-me because it has JS events attach on it and nothing to refresh them.

I played with the not() function, with filter and with the CSS 3 selecter ":not" but I can't get quite the result I want.

+6  A: 

Try this:

$('body > *:not(div#do-not-modify-me)').whateverYouWantToDo();

Edit: Added >

Blixt
Using the firebog live shell, I typed : console.log(jQuery("body > *:not(div#do-not-modify-me)").html()); and got only "Title". I find it very strange because your answer seems quite reasonable.
e-satis
Note that it will only look at the level directly below the body tag. Check the HTML tab in Firebug and open the body tag. The list you get is the same list that jQuery will fetch, excluding the element in the :not filter. I tried it and it works as expected.
Blixt
Yep, I understand that. I'm going to try in the page, without the live shell to see if it works.
e-satis
Nope, same result ! I got the content of the h1 tag. But the div is just under the body tag.
e-satis
The funny part is that $('body > *:not(div#do-not-modify-me)').remove() works exactly as expected...
e-satis
Most likely you were calling a single node method on a node collection, which always results in the result of calling the method on the first node in the collection.
Blixt
That makes sense. Validated :-) Thanks for that ! For a bonus point, how would you make this a jquery context so I can use jQuery(selector, context), making the filtering operation invisible. For now, if I do that, selector will select on the child of the child of body, which I'm not interested in.
e-satis
Made it another question : http://stackoverflow.com/questions/977185/turning-a-complex-jquery-css-selector-into-a-context-for-caching/977224#977224
e-satis
A: 

If you are wanting to replace everything, but leave your div intact, you can capture the current content of the div first, then replace the entire body, then put your div back into the document.

I hope that made sense...

rikh
Doing that will involve remove, that would detach all events, wouldn't it ?
e-satis
A: 

If your div is top-level, you can iterate over all the children of body and remove them one by one excepting your div.

Mr. Shiny and New