Скрипт Tampermonkey дает разные результаты в зависимости от того, как страница открывается и отображается? (содержимое такое же)

У меня есть пользовательский скрипт (Tampermonkey в Chrome), который запускается либо при открытии страницы пользователем, либо может открывать страницу в отдельном окне (где затем запускается соответствующий скрипт). Когда страница открывается пользователем, все работает как положено.

Однако, когда страница открывается в другом окне, эта функция иногда не обрабатывает текст должным образом.

Код:

function processTableRows() {
  var regex = new RegExp(/(.*?)(\d{7})/);
  var texts = document.querySelectorAll(".table__row");
  var out = [];
  texts.forEach(text=> {
    var fixMonth = text.innerText.replace(/(\d*)月/, function(p1) {
      const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
      return monthNames[(parseInt(p1) - 1)];
    }).replace(regex,
             "example.com/page.html?id=$2\n$1");
    out.push(fixMonth);
  });
 return out;
}

Пример текста страницы (до скрипта):

05 6月 2019  8989898
Some text

Some more text

При пользователь открывает страницу и пользовательский скрипт, и код в консоли дают ожидаемый результат:

example.com/page.html?id=8989898
05 Jun 2019     
Some text

Some more text

Однако, когда он запускается в отдельном окне, он возвращает (как скрипт TM, так и консоль):

05 Jun 2019
example.com/page.html?id=8989898

Some text

Some more text

Я не могу себе представить, почему второй replace() работает по-другому в отдельном окне. Я думал, что это может быть связано с некоторыми забавными регулярными выражениями JavaScript, например. перемещение индекса, влияющее на связанный вызов, но MDN указывает, что он возвращает только строку.

Обновлено: Дополнительная информация, полученная после комментариев, которые были ниже:

Когда страница запускается в новом (всплывающем) окне, она маленькая, а исходный текст выглядит так:

05 6月 2019
8989898
Some text
Some more text

Однако, когда окно больше (например, когда пользователь посещает его), оно выглядит так:

05 6月 2019  8989898
Some text

Some more text

Целевая страница не является общедоступной; чтобы было ясно, когда я имею в виду невозможность воспроизвести его в консоли, то есть включить в консоль окно, открытое сценарием, поэтому в окончательном рендеринге не должно быть никакой разницы. Возможно, это проблема времени, хотя я ожидаю, что в этом случае это также произойдет при открытии пользователем. Я посмотрю на textContent и посмотрю, даст ли это другие/лучшие результаты.

sinaraheneba 06.06.2019 05:21

Я очень хорошо осведомлен об использовании минимальных воспроизводимых примеров; для меня невозможно предоставить копию веб-сайта или намного больше, чем ранее предоставленный текст. Тем не менее, ваш предыдущий комментарий был правильным - это было связано с тем, что размеры открытого окна различались, что приводило к изменению отображаемого пробела (и, следовательно, значения innerText). textContent предоставляет стабильную ссылку, подходящую для последовательного форматирования, большое спасибо!

sinaraheneba 06.06.2019 06:06

@BrockAdams Эти знания о textContent были именно тем, что мне было нужно, чтобы исправить некоторые другие вечные ошибки (и, несомненно, избежать бесчисленных других в будущем); Я бы с удовольствием принял это как ответ, если вы хотите что-нибудь придумать. Спасибо еще раз!

sinaraheneba 07.06.2019 10:04
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
3
194
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В общем, если один и тот же пользовательский скрипт дает разные результаты — на одной и той же странице — в зависимости от того, как открывается эта страница, причины могут быть следующими:

  1. Сроки. Страница загружается медленнее или быстрее в зависимости от различных факторов, часто кэшируется. Таким образом, сценарий может сработать до того, как искомый контент будет представлен/закончен. Используйте waitForKeyElements или MutationObserver для компенсации. Поищите предыдущие вопросы, где это было рассмотрено.

  2. АЯКС. На самом деле страница не выполняет обычную загрузку HTML, а использует javascript для (пере)записи «новой» страницы. Опять же, против таких страниц помогают waitForKeyElements или MutationObserver. И, опять же, рассмотрено в предыдущих вопросах.

  3. «Отзывчивый» макет/поведение. На одной и той же странице может отображаться разный контент и/или по-разному в зависимости от размера окна (как правило), отслеживания состояния или некоторых переданных параметров.
    В таком случае вашему сценарию может понадобиться логический код для адаптации к различным вариантам страницы.

  4. Код, чувствительный к рендерингу. Если ваш скрипт зависит от позиционирования, стиля CSS, размеров элементов и т. д.; он может сломаться просто из-за того, что окно имеет другой размер или когда для отображения страницы требуется разное время.

В этом случае код вопроса имеет вариант причины 4. Он использует innerText и innerText меняет свои результаты в зависимости от пробелов и видимости. (innerText также медленнее, чем textContent.)

Решение используйте textContent вместо innerText.

Вот демонстрация, показывающая, как эти два свойства могут отличаться:

srcNode = $(".variableDiv")[0];
$("#TC").text (srcNode.textContent);
$("#IT").text (srcNode.innerText);
.variableDiv {border: 1px solid gray; margin-bottom: 1em;}
td, th {border: 1px solid gray;  padding: 0.2ex 1ex;}
table {border-collapse: collapse;}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Source Div:
<div class = "variableDiv">
    Chuck Norris has two speeds: <br> Walk, and Kill.<br>
    <span style = "display:none">Hidden Text</span>
</div>
<table>
  <tr> <th>textContent</th> </tr>
  <tr> <td><pre id = "TC">&nbsp;</pre></td> </tr>
  <tr> <th>innerText</th> </tr>
  <tr> <td><pre id = "IT">&nbsp;</pre></td> </tr>
</table>

IIRC, разные браузеры также могут различаться результатами innerText при скрытом переполнении и/или перекрывающих элементах, но я этого не проверял.

Абсолютно гениально, и еще раз спасибо! Небольшой вопрос по использованию waitForKeyElements с проблемами синхронизации/AJAX — эта страница загружает информацию с помощью AJAX, и мой скрипт ранее использовал waitForKeyElements для поддержки этого. С тех пор я изменил его так, что у меня есть функция, которая проверяет, существует ли элемент, и снова вызывает себя через setTimeout(), если это не так. Есть ли проблемы с этим или какие-то другие преимущества, предоставляемые waitForKeyElements, о которых я не знаю?

sinaraheneba 08.06.2019 14:06

@Altigraph, лучше использовать setInterval для таких вещей. Повторяющиеся/сцепленные setTimeout в некоторых случаях могут стать хитом памяти/производительности. ... Преимущества waitForKeyElements: (1) простота использования, (2) проще иметь несколько или цепочку ожиданий без конфликтов, (3) код вашего скрипта более «самодокументируемый», (4) его легче изменить/расширить. ... Но используйте то, что работает для вас (и тех, кто будет работать с кодом через пару лет (даже если это вы сами в будущем)).

Brock Adams 08.06.2019 18:16

Другие вопросы по теме