srgg6701
srgg6701

Reputation: 2038

Can't change .html()

I have a simple html (see here: http://plnkr.co/edit/nqfLNfYxV2B8AwsDAcNu?p=preview):

<section class="divs">
    <div>div1
        <div>div1.1.
            <div>div1.1.1</div>
            <div>div1.1.2</div>
        </div>
        <div>div1.2.</div>
    </div>
    <div>div2</div>
</section>

I want go through all section div:first-child elements and add some mark to see if it belongs to that selector. In order to implement this there is following code:

$(function(){
    $('section div:first-child').each(function(index,element){
        console.log('element.html before: '+$(element).html());
        var elementHTML = '['+index+']: '+$(element).html();
        $(element).html(elementHTML);
        console.log('element.html after: '+$(element).html());
    });
});

But it adds the [index] to the element's html only for the first selector. Can anybody explain why?


UPD


Not quite the answer, but nevertheless, Pete gave me the understanding of the problem. So in order to make it working there is necessary to change

$(element).html(elementHTML);

to

$('section div:first-child')
                    .eq(index).html(elementHTML);

It's not about efficiency ofcourse, it's about how to solve the problem in place. The real solution, no doubt, is to use .prepend() method.

Upvotes: 0

Views: 228

Answers (4)

blex
blex

Reputation: 25634

Since you replace the HTML every time, the elements are replaced on the fly. To avoid that, don't replace the entire HTML, just $.prepend() to it. Try it:

$(function() {
  $('section div:first-child').each(function(index, element) {
    console.log('element.html before: ' + $(element).html());
    var elementHTML = '[' + index + ']: ';
    $(element).prepend(elementHTML);    //    <------------------------ HERE !
    console.log('element.html after: ' + $(element).html());
  });
});
body * { box-sizing: border-box; }
div { background-color: white; }
section div { border: solid 2px #888; margin: 4px; padding: 10px; }
section div:first-child { background-color: lightcyan; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<section class="divs">
  <div>div1
    <div>div1.1.
      <div>div1.1.1</div>
      <div>div1.1.2</div>
    </div>
    <div>div1.2.</div>
  </div>
  <div>div2</div>
</section>

Upvotes: 2

Pete
Pete

Reputation: 58422

Your problem is the first time instance of section div:first-child is the top level div (div1) so when you replace the html of this div, the divs 2 and 3 in the loop no longer exist in the dom and so they don't get updated as such

Instead of replacing the html, just prepend the text:

$('section div:first-child').each(function(index, element) {
  $(element).prepend('[' + index + ']: ');
});

New plunker

Upvotes: 4

Joe Young
Joe Young

Reputation: 21

When you set the html, the elements below it don't get updated, they get replaced

Your code works, it's just updating the elements that are no longer attached to the DOM.

Upvotes: 1

timothyclifford
timothyclifford

Reputation: 6959

$('section div:first-child')

https://developer.mozilla.org/en-US/docs/Web/CSS/%3Afirst-child

The :first-child CSS pseudo-class represents any element that is the first child element of its parent.

If you want to select only the divs one level below section, you can try:

$('section > div')

Upvotes: 4

Related Questions