Функция случайного копирования отображаемой таблицы перестает работать, обновление страницы устраняет проблему

#javascript #reactjs #typescript

#javascript #reactjs #typescript

Вопрос:

Кажется, я не могу понять, почему эта функция перестает работать. Обновление страницы устраняет проблему. Что он делает, так это берет таблицу по идентификатору, удаляет классы и выполняет некоторую оптимизацию стилей. Пользователи копируют и вставляют сгенерированную таблицу в свои электронные письма.

Можете ли вы определить, почему он иногда выходит из строя? Я не вижу никаких ошибок в консоли, когда это происходит, и, кажется, я могу понять, почему большую часть времени это работает нормально.

Обновление страницы устраняет проблему.

(эта функция вызывается при нажатии кнопки в React. Он работал более года просто отлично, но, похоже, периодически переставал работать на прошлой неделе, и я не могу найти какие-либо обновления пакетов, которые могли повлиять на это)

 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 amp;amp; 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();
  }
  

Комментарии:

1. Это приложение в React.js ?

2. Да, реагирует. Вероятно, мне следует добавить консоль. регистрируйте или выдавайте ошибку, когда элемент не передается, чтобы он не выполнялся без сбоев. Может быть, это как-то связано с этим?

3. Вы не должны делать это в react. Все это должно обрабатываться компонентами react. Я думаю, что это ваша проблема.

4. Я не понимаю — это делается в компоненте внутри React. Кнопка (в React) вызывает функцию, которая копирует таблицу по идентификатору.

5. В React не рекомендуется манипулировать элементами DOM подобным образом, вместо этого вы управляете стилями на основе props и state . Кроме того, многие изменения стиля могут быть обработаны с помощью наличия или отсутствия одного имени класса, а не управления несколькими свойствами по отдельности.

Ответ №1:

Проблема возникла из-за другого компонента React, который блокировал окно просмотра при первом монтировании (модальное наложение). Сначала не казалось интуитивно понятным, что это может вызвать проблему с собственной функцией копирования в браузере.

После обновления компонента и переработки наложения проблема разрешилась сама собой.