[wp-trac] [WordPress Trac] #39762: Change in DOM Element Properties as seen in Javascript Event Handlers Between 4.6.2 and 4.7+

WordPress Trac noreply at wordpress.org
Wed Feb 1 22:55:08 UTC 2017


#39762: Change in DOM Element Properties as seen in Javascript Event Handlers
Between 4.6.2 and 4.7+
----------------------------+-----------------------------------------
 Reporter:  reldev          |       Owner:
     Type:  defect (bug)    |      Status:  new
 Priority:  normal          |   Milestone:  Awaiting Review
Component:  Administration  |     Version:  4.7
 Severity:  normal          |  Resolution:
 Keywords:                  |     Focuses:  javascript, administration
----------------------------+-----------------------------------------
Description changed by SergeyBiryukov:

Old description:

> I'm seeing a problem that appears to be related to the change introduced
> by ticket #[37973] in 4.7. I don't see this issue in 4.6.2. I filed
> ticket #[39739] earlier this week that documented another problem related
> to this change as well.
>
> This problem is also related to a "select all" checkbox but has to do
> with the state of child checkboxes within javascript event handlers being
> different between 4.6.2 and 4.7. In short, I have an event handler for
> "click" for the "manage-column check-column" checkbox (simplified HTML
> shown below). This event handler looks for child checkboxes in the table
> ("nslb_import_rows") and triggers their "click" event accordingly. The
> "click" events are triggered so that additional HTML can be displayed on
> the page if certain conditions are met when the individual rows are
> selected / unselected or en masse via this "select all".
>

> {{{
> <table class="form-table">
>   <tbody class="nslb-dynamic-content">
>     <tr>
>       <td>
>         <table class="wp-list-table fixed widefat striped">
>           <thead>
>             <tr>
>               <th scope="col" class="manage-column check-column">
>                 <label><input type="checkbox" class="check-all"></label>
>               </th>
>               <th scope="col">
>                 Name
>               </th>
>             </tr>
>           </thead>
>           <tbody id="the-list">
>             <tr>
>               <th scope="row" class=" check-column">
>                 <input type="checkbox" id="cb-select-1"
> name="nslb_import_rows" class="nslb-input" value="1">
>               </th>
>               <td>
>                 Steven<input type="hidden" name="s_1_1" class="nslb-
> input" value="Steven">
>               </td>
>             </tr>
>             <tr>
>               <th scope="row" class=" check-column">
>                 <input type="checkbox" id="cb-select-2"
> name="nslb_import_rows" class="nslb-input" value="2">
>               </th>
>               <td>
>                 David<input type="hidden" name="s_2_1" class="nslb-input"
> value="David">
>               </td>
>             </tr>
>           </tbody>
>         </table>
>       </td>
>     </tr>
>   </tbody>
> </table>
> }}}
>
> Please note the first <tbody> element with the class "nslb-dynamic-
> content". As the name implies, this content is created dynamically and
> added to the page via javascript as certain other options on the page are
> chosen. Because the inner HTML is added dynamically, when this code in
> common.js at line 459 at the 4.6.2 level executes:
>
> {{{
> $('thead, tfoot').find('.check-column :checkbox').on( 'click.wp-toggle-
> checkboxes', function( event ) {
> ...
> }}}
>
> it doesn't find any elements that match the search criteria as they are
> not present on the page yet, therefore no event handlers are registered
> here. The HTML at this point would look only like this:
>
> {{{
> <table class="form-table">
>   <tbody class="nslb-dynamic-content">
>   </tbody>
> </table>
> }}}
>
> Conversely, the code in common.js at 4.7+ on line 452 that replaced this
> line
>

> {{{
> $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox,
> tfoot .check-column :checkbox', function( event ) {
> ...
> }}}
>
> fires when the "manage-column check-column" checkbox is clicked even
> though it's in HTML that is added dynamically. This is because the line
> in 4.7+ handles click events in the body and then evaluates whether or
> not a "check-column" checkbox was clicked in a <thead> or <tfoot> as part
> of click event processing itself thereby finding my "manage-column check-
> column" checkbox" in the DOM at that point.
>
> The net of effect of all this is a change in the value of the "clicked"
> property of these child checkboxes when my own click event handler
> executes. For example, in 4.6.2, if no checkboxes are selected on the
> page and I click my "manage-column check-column" checkbox, the "clicked"
> properties for the child checkboxes are "false" because the event handler
> on line 459 in common.js doesn't execute. However, in 4.7+ given the same
> scenario, the "clicked" properties for the child checkboxes are already
> "true" because the event handler on line 452 in common.js does execute
> each time.
>
> You could actually argue the behavior in 4.6.2 is defective since the
> handler does not get registered for "check-column" checkboxes added
> dynamically. FYI, if I hard code this exact HTML statically, then the
> 4.6.2 event handler does get registered and the "clicked" property for
> child checkboxes is consistent between 4.6.2 and 4.7+.
>
> Additionally, the code in common.js at the 4.7+ level could potentially
> trigger the "click" event for any child checkboxes it finds as opposed to
> just modifying their "checked" property, although I'm not sure of the
> ramifications of that type change.

New description:

 I'm seeing a problem that appears to be related to the change introduced
 by ticket #37973 in 4.7. I don't see this issue in 4.6.2. I filed ticket
 #39739 earlier this week that documented another problem related to this
 change as well.

 This problem is also related to a "select all" checkbox but has to do with
 the state of child checkboxes within javascript event handlers being
 different between 4.6.2 and 4.7. In short, I have an event handler for
 "click" for the "manage-column check-column" checkbox (simplified HTML
 shown below). This event handler looks for child checkboxes in the table
 ("nslb_import_rows") and triggers their "click" event accordingly. The
 "click" events are triggered so that additional HTML can be displayed on
 the page if certain conditions are met when the individual rows are
 selected / unselected or en masse via this "select all".


 {{{
 <table class="form-table">
   <tbody class="nslb-dynamic-content">
     <tr>
       <td>
         <table class="wp-list-table fixed widefat striped">
           <thead>
             <tr>
               <th scope="col" class="manage-column check-column">
                 <label><input type="checkbox" class="check-all"></label>
               </th>
               <th scope="col">
                 Name
               </th>
             </tr>
           </thead>
           <tbody id="the-list">
             <tr>
               <th scope="row" class=" check-column">
                 <input type="checkbox" id="cb-select-1"
 name="nslb_import_rows" class="nslb-input" value="1">
               </th>
               <td>
                 Steven<input type="hidden" name="s_1_1" class="nslb-input"
 value="Steven">
               </td>
             </tr>
             <tr>
               <th scope="row" class=" check-column">
                 <input type="checkbox" id="cb-select-2"
 name="nslb_import_rows" class="nslb-input" value="2">
               </th>
               <td>
                 David<input type="hidden" name="s_2_1" class="nslb-input"
 value="David">
               </td>
             </tr>
           </tbody>
         </table>
       </td>
     </tr>
   </tbody>
 </table>
 }}}

 Please note the first <tbody> element with the class "nslb-dynamic-
 content". As the name implies, this content is created dynamically and
 added to the page via javascript as certain other options on the page are
 chosen. Because the inner HTML is added dynamically, when this code in
 common.js at line 459 at the 4.6.2 level executes:

 {{{
 $('thead, tfoot').find('.check-column :checkbox').on( 'click.wp-toggle-
 checkboxes', function( event ) {
 ...
 }}}

 it doesn't find any elements that match the search criteria as they are
 not present on the page yet, therefore no event handlers are registered
 here. The HTML at this point would look only like this:

 {{{
 <table class="form-table">
   <tbody class="nslb-dynamic-content">
   </tbody>
 </table>
 }}}

 Conversely, the code in common.js at 4.7+ on line 452 that replaced this
 line


 {{{
 $body.on( 'click.wp-toggle-checkboxes', 'thead .check-column :checkbox,
 tfoot .check-column :checkbox', function( event ) {
 ...
 }}}

 fires when the "manage-column check-column" checkbox is clicked even
 though it's in HTML that is added dynamically. This is because the line in
 4.7+ handles click events in the body and then evaluates whether or not a
 "check-column" checkbox was clicked in a <thead> or <tfoot> as part of
 click event processing itself thereby finding my "manage-column check-
 column" checkbox" in the DOM at that point.

 The net of effect of all this is a change in the value of the "clicked"
 property of these child checkboxes when my own click event handler
 executes. For example, in 4.6.2, if no checkboxes are selected on the page
 and I click my "manage-column check-column" checkbox, the "clicked"
 properties for the child checkboxes are "false" because the event handler
 on line 459 in common.js doesn't execute. However, in 4.7+ given the same
 scenario, the "clicked" properties for the child checkboxes are already
 "true" because the event handler on line 452 in common.js does execute
 each time.

 You could actually argue the behavior in 4.6.2 is defective since the
 handler does not get registered for "check-column" checkboxes added
 dynamically. FYI, if I hard code this exact HTML statically, then the
 4.6.2 event handler does get registered and the "clicked" property for
 child checkboxes is consistent between 4.6.2 and 4.7+.

 Additionally, the code in common.js at the 4.7+ level could potentially
 trigger the "click" event for any child checkboxes it finds as opposed to
 just modifying their "checked" property, although I'm not sure of the
 ramifications of that type change.

--

--
Ticket URL: <https://core.trac.wordpress.org/ticket/39762#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list