admin管理员组

文章数量:1123943

Got a weird one! I have this React app that has a component "OHSList" that builds out a table of results from the Python API backend. I can set it to be sortable using HTML's dragging feature. Each row is draggable and can be placed somewhere else in the lines of rows. There are a couple of on-events (see code) to handle the dragging events. I am able to drag the rows around and have it save the order to the backend. But sometimes if you drag something slow or move it around in a certain area, it will start duplicating sub-elements of other rows and appending "null" under it. I have no clue what this could be. Please see the video of it happening below. Thoughts? I am an amateur coder, please forgive any non-standard practices :)

Screen recording

export default function OHSList (props) {
   // States and Variables
   const listID = 'ohslist-' + Math.floor(Math.random() * 999999);
   //const [popups, setPopups] = useState({});
   var dragRow = null;
   var dragPosition = 0;

   // Functions
   function showPopup (index) {
      props.setPopups({...props.popups, [index]: true});
   }
   function hidePopup (index) {
      props.setPopups({...props.popups, [index]: false});
   }
   function dragStart (event) {
      dragRow = event.target;
   }
   function dragRun (event) {
      event.preventDefault();
      event.dataTransfer.dropEffect = 'move';
      if ((event.target.tagName == "TD") && (event.target.parentNode.parentNode.tagName == "TBODY")) {
         // Build Children Array
         let children = Array.from(event.target.parentNode.parentNode.children);

         // Position Dragged Element
         if (children.indexOf(event.target.parentNode) > children.indexOf(dragRow)) {
            event.target.parentNode.after(dragRow);
         } else {
            event.target.parentNode.before(dragRow);
         }

         // Set Final Position
         dragPosition = children.indexOf(event.target.parentNode);
      }
   }
   function dragEnd () {
      // Acquire New Order
      var order = [];
      var i = 1;
      $('#' + listID + '-rows').children().each(function () {
         order.push({
            'id': $(this).data('ohslistdataid'),
            'display_order': i
         });
         i++;
      });

      // Send Back New Order
      props.handleDragging(JSON.stringify({
         order: order
      }));
   }


   // Component
   return (
      <div id={listID} className='ohslist'>
         {props.content ? props.content.length > 0 ? 
            <>
               <table>
                  <thead>
                     <tr>
                        {props.enableDragging && <th className='ohslist-header-dragger'></th>}
                        <th className='ohslist-header-selector'></th>
                        {Object.values(props.content[0]).map(function (header, i) {
                           if ((header.display !== false) && (header.metadata !== true)) {
                              return (
                                 <th key={`ohslist-header-${i}`}>
                                    <p>{header.title}</p>
                                 </th>
                              );
                           }
                        })}
                     </tr>
                  </thead>
                  <tbody id={`${listID}-rows`}>
                     {props.content.map(function (item, i) {
                        // Build OHS Filter attribute
                        var ohsfilter = "";
                        Object.values(item).map(function (subitem) {
                           if ((subitem.display !== false) && (subitem.metadata !== true)) {
                              ohsfilter = ohsfilter + " " + subitem.value;
                           }
                        });

                        // Build rows
                        return (
                           <tr key={`ohslist-item-${i}`} data-ohsfilter={ohsfilter} data-ohslistdataid={item.id.value} draggable={props.enableDragging} onDragStart={(event) => {dragStart(event);}} onDragOver={(event) => {dragRun(event);}} onDragEnd={() => {dragEnd();}}>
                              {props.enableDragging &&
                                 <td className='ohslist-body-dragger'>
                                    <div>
                                       <div></div>
                                       <div></div>
                                       <div></div>
                                    </div>
                                 </td>
                              }
                              <td className='ohslist-body-selector'>
                                 <div>
                                    <input type='checkbox' className='ohsinput' disabled />
                                 </div>
                              </td>
                              {Object.values(item).map(function (subitem, j) {
                                 if ((subitem.display !== false) && (subitem.metadata !== true)) {
                                    return (
                                       <td key={`ohslist-subitem-${i}-${j}`} onClick={() => {showPopup(i);}}>
                                          <div>
                                             <p>{subitem.value}</p>
                                          </div>
                                       </td>
                                    );
                                 }
                              })}
                           </tr>
                        );
                     })}
                  </tbody>
               </table>
               {props.enableDragging && <p>Drag and drop a row to set the order of the entries (not supported on mobile)</p>}
               {props.template && props.content.map(function (item, i) {
                  return (
                     <OHSListPopup key={`ohslist-popup-${i}`} index={i} popups={props.popups} hidePopup={hidePopup}>
                        {cloneElement(props.template, {
                           content: item,
                           index: i,
                           showPopup: showPopup,
                           hidePopup: hidePopup
                        })}
                     </OHSListPopup>
                  );
               })}
            </>
         : <p className='ohslist-noitems'>There are no items to display</p> : <p className='ohslist-noitems'>There are no items to display</p>}
      </div>
   );
}

本文标签: javascriptReact Draggable Element Causes Null Appending to ElementsStack Overflow