Bug Tracker

Modify

Ticket #9181 (closed bug: invalid)

Opened 3 years ago

Last modified 3 years ago

$.each() fails to iterate properly over custom HTML elements when using replaceWith()

Reported by: chris.young-zawada@… Owned by:
Priority: low Milestone: 1.next
Component: core Version: 1.6
Keywords: Cc:
Blocking: Blocked by:

Description

When using $.each() to iterate over an array of custom HTML elements, reformatting these elements with .replaceWith() does not work properly. The first iteration is correctly replaced, but the following iterations improperly pass the 'DOMWindow' object to 'this', rather than the 'HTMLElement' object.

<!doctype html>
<html xmlns:custom="http://customelement.com">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<script>
$(function($){

  //get the list of custom elements
  var elems = document.getElementsByTagName('custom:element');

  //iterate over them
  $.each(elems,function(){

    /*
    replace each element with a div instead
    the error that is occurring is that after the first element is replaced,
    the following elements' targets are lost, and each is passed as a 'DOMWindow'
    object instead of the correct 'HTMLElement' object
    */

    console.log('about to kill element: ');
    console.log($(this));

    $(this).replaceWith('<div class="customElement"></div>');
    
    console.log('killed element');
  });


});
</script>
</head>
<body>
  <p>
    Check out the console...
  </p>
  <custom:element>1</custom:element>
  <custom:element>2</custom:element>
  <custom:element>3</custom:element>
</body>
</html>

Change History

comment:1 Changed 3 years ago by rwaldron

  • Priority changed from undecided to low
  • Resolution set to invalid
  • Status changed from new to closed
  • Component changed from unfiled to core

Because getElementsByTagName returns a live nodelist, as you are replacing items in the list, elements matching the tag "custom:element" are being reduced by one each on each iteration.

live nodelists are notoriously unpredictable, as seen here.

comment:2 Changed 3 years ago by rwaldron

If you copy the nodelist to a plain array that wont be affected by the "live" nature of a getElementsByTagName nodelist it works as expected:  http://jsfiddle.net/rwaldron/pc9qs/

comment:3 Changed 3 years ago by chris.young-zawada@…

Got it - thanks!

comment:4 Changed 3 years ago by rwaldron

You're welcome!

Please follow the  bug reporting guidlines and use  jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.