Búsqueda de sitios web

javascript - Función para copiar tabla renderizada se detiene aleatoriamente, refrescar la página soluciona el problema


No puedo entender por qué esta función deja de funcionar. Refrescar la página soluciona el problema. Lo que hace es tomar una tabla por ID, eliminar las clases y hacer algunas optimizaciones en los estilos. Los usuarios están copiando y pegando una tabla generada en sus correos electrónicos.

¿Puedes ver por qué falla ocasionalmente? No veo ningún error en la consola cuando sucede, y no puedo entender por qué funciona bien la mayor parte del tiempo.

Actualizar la página soluciona el problema.

(esta función se llama onPress por un botón en React. Ha funcionado durante más de un año sin problemas, pero parece que ha dejado de funcionar de manera intermitente en la última semana y no puedo encontrar ninguna actualización de paquetes que pueda haberlo afectado)

function copyByElementId(element: HTMLElement | null) {
    if (!element) return false;

    // Clone the node so we don't interrupt the view
    let el = element.cloneNode(true) as HTMLTableElement;
    el.className = ""; // Remove classes from parent Div

    if (comparedScenarios.length > 1) {
      // Delete last row if the arrows are present
      el.deleteRow(el.children[0].children.length - 1);
    }

    // Add default fonts to the table
    el.style.fontSize = "inherit";
    el.style.fontFamily = "San Francisco, Helvetica, Arial, sans-serif";

    // This works for clients other than Outlook grrr...
    el.style.borderCollapse = "collapse";
    el.style.borderSpacing = "16px 4px";
    el.style.border = "0";

    let rows = el.children[0].children; // Rows in the table

    // Add padding to the left side of each cell other than the 1st column
    for (let i = 0; i < rows.length; i++) {
      let cells = rows[i].children;
      rows[i].className = ""; // Remove classes from rows
      for (let i = 0; i < cells.length; i++) {
        cells[i].className = ""; // Remove classes from cells
        // Only the 2nd column and after
        let cell = cells[i] as HTMLTableCellElement; // TD element
        cell.style.border = "0";
        if (i > 0) {
          cell.style.paddingTop = "0";
          cell.style.paddingRight = "0";
          cell.style.paddingBottom = "0";
          cell.style.paddingLeft = "20px";
        }
      }
    }

    // Create our hidden div element
    let hiddenDiv = document.createElement("div");
    hiddenDiv.style.position = "absolute";
    hiddenDiv.style.left = "-9999px";
    hiddenDiv.style.backgroundColor = "";

    // Render the table of the hidden div
    hiddenDiv.appendChild(el);

    // Check and see if the user had a text selection range
    let currentRange;
    let documentSelection = document.getSelection();
    if (documentSelection?.rangeCount && documentSelection?.rangeCount > 0) {
      // The user has a text selection range, store it
      currentRange = document.getSelection()?.getRangeAt(0);
      // Remove the current selection
      window.getSelection()?.removeAllRanges();
    }

    // Append the div to the body
    document.body.appendChild(hiddenDiv);
    // Create a selection range
    let CopyRange = document.createRange();
    // Set the copy range to be the hidden div
    CopyRange.selectNode(hiddenDiv);
    // Add the copy range
    window.getSelection()?.addRange(CopyRange);

    //since not all browsers support this, use a try block
    try {
      //copy the text
      document.execCommand("copy");
    } catch (err) {
      window.alert("Your browser doesn't support copy and paste! Error:" + err);
    }
    //remove the selection range (Chrome throws a warning if we don't.)
    window.getSelection()?.removeAllRanges();
    //remove the hidden div
    document.body.removeChild(hiddenDiv);

    //return the old selection range
    if (currentRange) {
      window.getSelection()?.addRange(currentRange);
    }
    runButtonStates();
  }

Respuesta #1

El problema se debió a otro componente de React que estaba bloqueando la ventana de visualización cuando se montaba por primera vez (una superposición modal). Al principio no parecía intuitivo que esto pudiera estar causando un problema con la función de copiar nativa en el navegador.

Después de actualizar el componente y rehacer la superposición, el problema se resolvió por sí mismo.