Как проверить, был ли HTMLElement уже сгенерирован? - PullRequest
0 голосов
/ 26 марта 2020

У меня есть компонент от стороннего производителя, который генерирует событие "onCellEdit" и передает элемент ячейки в качестве параметра.

В моем обработчике событий я хочу автоматически выбрать весь текст в элементе ввода, который создается внутри этой ячейки.

Проблема, которую я имею, состоит в том, что, когда мой обработчик запущен, элемент ввода еще не загружен. (cellElement as HTMLTableCellElement).querySelector('input') ничего не возвращает, так как стороннему компоненту нужно время, я думаю.

Мое решение теперь выглядит так:

selectTextOnEdit(cell: HTMLTableCellElement) {
    const repeater = (element: HTMLTableCellElement) => {
      const inputElement = element.querySelector('input');
      if (inputElement) {
        inputElement.select();
      } else {
        setTimeout(() => { repeater(element); }, 50);
      }
    };
    repeater(cell);
  }

эта функция затем запускает функцию повторителя, которая работает до тех пор, пока элемент ввода найден. Я знаю, что пропускаю какую-то проверку на случай, если элемент ввода никогда не генерируется ... но это не важно для этого вопроса.

Мне очень не нравится это решение, и я уверен, что есть лучшие.

Обновление:

После некоторых исследований я узнал о "MutationObserver".

Вот мое новое решение:

selectTextOnEdit(cell: HTMLTableCellElement) {
    const observer = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        if (mutation.addedNodes && mutation.addedNodes.length > 0) {
          const inputElement = cell.querySelector('input');
          if (inputElement) {
            inputElement.select();
            observer.disconnect();
          }
        }
      });
    });
    observer.observe(cell, {childList: true});
  }

Ответы [ 2 ]

0 голосов
/ 27 марта 2020

После некоторых исследований я узнал о MutationObserver.

Вот мое новое решение:

selectTextOnEdit(cell: HTMLTableCellElement) {
    const observer = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        if (mutation.addedNodes && mutation.addedNodes.length > 0) {
          const inputElement = cell.querySelector('input');
          if (inputElement) {
            inputElement.select();
            observer.disconnect();
          }
        }
      });
    });
    observer.observe(cell, {childList: true});
  }
0 голосов
/ 26 марта 2020

Для таких сценариев ios, я хотел бы использовать служебную функцию waitUntil.

import { interval } from 'rxjs';
import { take } from 'rxjs/operators';
...
export const waitUntil = async (untilTruthy: Function): Promise<boolean> => {
  while (!untilTruthy()) {
    await interval(25).pipe(
      take(1),
    ).toPromise();
  }
  return Promise.resolve(true);
}

Тогда в вашей функции это будет:

async selectTextOnEdit(cell: HTMLTableCellElement) {
    await waitUntil(() => !!cell.querySelector('input'));
    const inputElement = element.querySelector('input');
    inputElement.select();
  }

Это то же самое, но немного чище, на мой взгляд. Почему проблема в том, что input никогда не создавалась, не всегда должна создаваться, если вызывается обратный вызов selectTextOnEdit?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...