@S10LI

Как написать скрипт проверяющий наличие элемента с определенным ID?

Добрый день. Есть следующая структура

<html>
      <head>
      </head>
      <body>
          <a href="Simple_Text.zip" id="plseditme">Simple_Text.zip</a><br>
          <a href="Simple_Text.exe" id="plseditme">Simple_Text.exe</a><br>
          <a href="Simple_Text.msi" id="plseditme">Simple_Text.msi</a>
     </body>
</html>


Есть следующий скрипт, который должен выполняться до тех пор, пока находится элемент с
id="plseditme"

<script>
    function SpaceReplacer(){
        document.getElementById('plseditme').innerHTML = document.getElementById('plseditme').innerHTML.replace(/_/gi, ' ').replace(/.exe/gi, '').replace(/.msi/gi, '').replace(/.zip/gi, '').replace(/.txt/gi, '');
        document.getElementById('plseditme').id = 'edited';
        SpaceReplacer();
    }
    window.onload = SpaceReplacer;
</script>


Его смысл в том, что он изменяет текст ссылки из Simple_Text.exe в Simple Text, изменяет ID на edited после чего переходит к следующему элементу с начальным ID
В целом он выполняет свою задачу, после чего выдает ошибку
"TypeError: Cannot read property 'innerHTML' of null"

Вопрос
Как переделать его в нормальный цикл, который работает до тех пор, пока существует элемент с ID="plseditme", что бы при его отсутсвии он останавливался?
  • Вопрос задан
  • 122 просмотра
Решения вопроса 1
Ваша логика работает отлично, как я понял в этом случае неизвестен количество plseditme элементов. Поэтому нужно использовать рекурсию.

Только беда в том что перед каждым запуском рекурсий, то есть перед каждым циклом надо проверить существует ли эти элементы с id. Если нет то остановить цикл.

function SpaceReplacer() {
  document.getElementById('plseditme').innerHTML = document.getElementById('plseditme').innerHTML
    .replace(/_/gi, ' ')
    .replace(/.exe/gi, '')
    .replace(/.msi/gi, '')
    .replace(/.zip/gi, '')
    .replace(/.txt/gi, '');

  document.getElementById('plseditme').id = 'edited';

  if (document.getElementById('plseditme')) { // Тут проверяем существуют ли элементы
    SpaceReplacer(); // И потом уже вызываем функцию
  }
}


И еще ID должен быть уникальным так что желательно использовать Class.

Либо если известно количество элементов. То просто перебираем по циклу.

const plseditme = document.querySelectorAll('#plseditme');

plseditme.forEach(el => {
  el.innerHTML = el.innerHTML
    .replace(/_/gi, ' ')
    .replace(/.exe/gi, '')
    .replace(/.msi/gi, '')
    .replace(/.zip/gi, '')
    .replace(/.txt/gi, '');

  el.id = 'edited';
});
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Pashevka
Чтобы решить вашу проблему, надо просто убрать рекурсивный вызов функции SpaceReplacer
function SpaceReplacer(){
        document.getElementById('plseditme').innerHTML = document.getElementById('plseditme').innerHTML.replace(/_/gi, ' ').replace(/.exe/gi, '').replace(/.msi/gi, '').replace(/.zip/gi, '').replace(/.txt/gi, '');
        document.getElementById('plseditme').id = 'edited';
    }


Почему так происходит. getElementById возвращает не коллекцию элементов, а только 1. И тип возвращаемого элемента - HTMLElement | null. Каждый раз, после изменения текста, ваша функция ищет новый элемент, и, когда они заканчиваются, вместо элемента приходит null и умирает смертью храбрых собачек.
По правильному на странице не должно быть больше одного элемента с одинаковым id, и лучше для этого использовать тэги.

Но, если мы хотим сделать так, чтобы ваша функция работала и не падала, нужно переписать ее следующим образом
function SpaceReplacer(tagName: string) {
    const nodeList = document.querySelectorAll(`[${tagName}]`);
    [...nodeList].map(elem => {
        elem.innerHTML = elem.innerHTML
            .replace(/_/gi, ' ')
            .replace(/.exe/gi, '')
            .replace(/.msi/gi, '')
            .replace(/.zip/gi, '')
            .replace(/.txt/gi, '');
        return elem;
    });
}


А если мы хотим, чтобы было немного веселее, можно сделать вот так
<html>
      <head>
      </head>
      <body>
          <a href="Simple_Text.zip" data-text >Simple_Text.zip</a><br>
          <a href="Simple_Text.exe" data-text>Simple_Text.exe</a><br>
          <a href="Simple_Text.msi" data-text">Simple_Text.msi</a>
     </body>
</html>

<script>
   function SpaceReplacer(tagName) {
    const nodeList = document.querySelectorAll(`[${tagName}]`);
    [...nodeList].map(elem => {
        elem.innerHTML = elem.innerHTML
            .replace(/_/gi, ' ')
            .replace(/.exe/gi, '')
            .replace(/.msi/gi, '')
            .replace(/.zip/gi, '')
            .replace(/.txt/gi, '');
        return elem;
    });
}
    window.onload = ('data-text') => SpaceReplacer(data-text);
</script>
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы