2

I select an element of the page:

$mainSection = $('#main');

then I add more Elements via AJAX into the <div id="main"></div> element. Next time I call $mainSection, the newly added elements are also in it. But I don't want that. I would like that the variable $mainSection only has the content in it from the initial rendering of the page. I can't find a way to prevent jQuery from updating.


I tried this:

$(document).ready(function(){
  $mainSection = $('#main').clone(true);

Then I add new elements to #main and then I check if they get found via:

$foundElement = $($mainSection + ":not(:has(*)):not(script):contains('"+newlyAddedContent+"')");

On page load, they are not there. But after I add them, they get found.

I also tried:

$mainSection = $('#main').html();
$mainSection = $($mainSection);

didn't work also.


Here is a jsFiddle to illustrate my point:

http://jsfiddle.net/VEQ2E/2/


The problem is somewhere burried in this line: $foundElement = $($mainSection + ":not(:has(*)):not(script):contains('"+newlyAddedContent+"')");

It somehow always searches through the whole document, when I do it like this.

Simon S.
  • 563
  • 4
  • 21

3 Answers3

3

You can use .clone(true):

$mainSection = $('#main').clone(true);

It every time takes the clone/copy of the initial state of this div.

Note:

.clone( [withDataAndEvents ] [, deepWithDataAndEvents ] )

withDataAndEvents : Boolean (default: false)

deepWithDataAndEvents : Boolean (default: value of withDataAndEvents)

A Boolean indicating whether event handlers and data for all children of the cloned element should be copied.

Jai
  • 74,255
  • 12
  • 74
  • 103
  • Thanks for the answer, but it does not work. Here is a jsFiddle to better illustrate my point: http://jsfiddle.net/VEQ2E/2/ – Simon S. Jun 13 '14 at 13:22
1

You can take several approaches:

Cache the contents of #main before the update. This gives you just the contents of the element without the element.:

mainsectionContents = $('#main').html();

Or Cache a copy of #main before the update. This will give you the content together with the element, and depending on whatever else you may want to copy feel free to check the api docs:

$mainsectionCopy = $('#main').clone();
PeterKA
  • 24,158
  • 5
  • 26
  • 48
1

Your problem was not that your clone was getting changed, but rather the selector you were using to try finding something within the clone. Your code was like this:

$($mainSection + ":not(:has(*)):not(script):contains('"+newlyAddedContent+"')");

Concatenating an object with a string will turn the object into a string, simply "[object Object]", then your selector will just look at the ":not(:has..."

Instead, you should use filter:

$foundElement = $mainClone.filter(":not(:has(*)):not(script):contains('world')");

This will now only look within your $mainClone for items matching that filter.

JSFiddle

Smern
  • 18,746
  • 21
  • 72
  • 90
  • If you could explain it in more details I would be so happy! I still don't get why my first approach didn't work. – Simon S. Jun 13 '14 at 14:10
  • @user3181141, do `console.log($mainSection + ":not(:has(*)):not(script):contains('"+newlyAddedContent+"')"`, you'll see that $mainSection gets turned into a string. – Smern Jun 13 '14 at 14:17
  • @user3181141, so your selection was basically this (no matter what elements were in $mainSelection): `$("[object Object]:not(:has(*)):not(script):contains('"+newlyAddedContent+"')")` – Smern Jun 13 '14 at 15:17