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.