Есть ли способ обернуть весь javascript, чтобы он запускался только с определенным идентификатором HTML?

#javascript #html

#javascript #HTML

Вопрос:

Я унаследовал сторонний Javascript — в уменьшенном виде это около 7000 строк — который мне нужно использовать для открытия и закрытия панели содержимого при нажатии на ссылку. Он отлично работает, когда я импортирую HTML и js-файл в модуль содержимого в моей CMS (DNN), но имеет неприятный побочный эффект, заключающийся в нарушении меню bootstrap hamburger при просмотре страницы на мобильном устройстве.

У меня нет ни времени, ни навыков JS, чтобы точно определить, как работают 7000 строк скрипта, какие биты мне действительно нужны, а затем настроить их так, чтобы они выполняли только то, что мне нужно, и не влияли на меню.

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

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

Обновите после прочтения начальных ответов…
Код-нарушитель можно увидеть на https://dnnplaypen.epicservices.com.au/application
Файл JS (не уменьшенная версия) можно найти по адресу https://dnnplaypen.epicservices.com.au/portals/0/scripts/main.unmin.js — Я полагаю, что на самом деле это может быть полная реализация BootStrap JS, которая, возможно, объясняет конфликт.
и это соответствующий раздел HTML…

 <a href="#MemberTypes" class="btn btn-link" data-toggle="collapse" role="button" aria-expanded="false" aria-controls="MemberTypes">View them.</a></p>
<div id="MemberTypes" class="collapse">
<p style="margin-left:20px;"><img src="/portals/0/Images/OrangeDot.png"> amp;nbsp;<span style="font-weight:bold">Civil Intrastructure (CIM) Entrant</span></p>
<p style="margin-left:40px;">(Works in the civil industry and either supervises 1 or more people or has a civil university qualification e.g. leading hands, site supervisors, engineers, project managers, CEOs)</p>
<p style="margin-left:40px;">You’ll answer some questions about your qualification amp; employment details to confirm your eligibility.</p>
<p style="margin-left:20px;"><img src="/portals/0/Images/OrangeDot.png"> amp;nbsp;<span style="font-weight:bold">Student</span></p>
<p style="margin-left:40px;">(Studying civil-related course at university at least 50% of the time)</p><p style="margin-left:40px;">Please have current enrolment document(s) as evidence.</p>
<p style="margin-left:20px;"><img src="/portals/0/Images/OrangeDot.png"> amp;nbsp;<span style="font-weight:bold">Affiliate</span></p><p style="margin-left:40px;">i.e. Part of the supply chain servicing the industry</p>
</div>  

Любая помощь в определении того, какая часть JS вызывается при нажатии на ссылку, была бы высоко оценена.

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

1. Скрипт не «применяется» ни к какой части HTML. Он просто запускается и вносит любые изменения, которые он хочет, в DOM. Невозможно сказать «эта часть DOM недоступна».

2. К сожалению, нет простого ответа на этот вопрос, не видя кода. Если у вас есть 7000 строк кода, это, безусловно, не то, что можно просто «обернуть» и применить к одному элементу. Во всем коде будет много логики, которая выполняет всевозможные действия.

3. Если вы не можете опубликовать пример кода, попробуйте изучить HTML элементов, которые вы хотите исправить, а затем выполнить поиск в коде JS для кода, который выбирает эти узлы DOM, используя классы, идентификаторы, имена тегов, атрибуты.

4. удалите bootstrap, напишите свой собственный код.

Ответ №1:

Возможно.

Во-первых, открытие и закрытие элемента по щелчку не должно занимать даже 7 строк кода, не говоря уже о 7000. Отказ от просмотра этого кода является нарушением. Просто бросать его в приложение, не зная, что оно делает, безответственно.

Во-вторых, лучше всего использовать DevTools для отслеживания события click. В Chrome вы открываете панель источников, а в Firefox — панель отладчика. С правой стороны, вверху, есть значок паузы. Щелкните это, затем щелкните часть веб-страницы, которая переключает содержимое. Если вам повезет, отладчик остановит выполнение на первом операторе в toggle codepath, который вы можете и должны выполнить.

В-третьих, стратегия, которую мы будем использовать, заключается в том, чтобы обернуть весь блок кода внутри функции, которая предоставляет поддельную версию DOM API. Этот 7-килобайтный блок таинственного кода в конечном итоге использует некоторые из основных методов DOM для идентификации и манипулирования соответствующими элементами. Вашей целью будет создать поддельную версию этого API, которая только возвращает конкретный элемент, который вам нужен. Вы добавите идентификатор или другой идентифицирующий атрибут к рассматриваемому элементу, а затем возвращаете этот элемент всякий раз, когда таинственный код вызывает ваш API (который он подумает, что это настоящий API).

Вот простой пример:

 // first, get our hands on the one element you want the mystery code to see
const elementThatShouldToggle = document.getElementById('target-element')

// second, construct an object that provides methods with the same names as what the real document provides
const fakeDOM = {
    // normally, document.getElementById takes an argument
    // your fake version will ignore that arg and just return the content el
    getElementById: () => elementThatShouldToggle,
    
    // you may need to mock several DOM accessor methods
    querySelector: () => elementThatShouldToggle,
    querySelectorAll: () => [elementThatShouldToggle]
}

// third: wrap the mystery code in a function that uses variable shadowing to obscure the real DOM, substituting your fake DOM instead

(function sandbox(document) {
    /* paste the 7000 lines of mystery code here */
})(fakeDOM)
  

У этого подхода есть недостатки:

  • Вам нужно будет создать поддельные версии каждого метода DOM, который использует таинственный код; это потребует от вас запуска приложения несколько раз и поиска исключений. Для каждого исключения вам нужно будет изучить трассировку стека, чтобы определить любые задействованные методы DOM, а затем создать mocks, которые возвращают безопасные значения.
  • Если таинственный код использует те же методы DOM, что и код, который вам нравится, ваши поддельные реализации API должны быть немного умнее. Возможно, вам потребуется настроить поведение ветвления в ваших поддельных методах, которые в некоторых случаях возвращают реальные элементы и безопасные значения для всех остальных случаев. Опять же, это будет делом догадок и тестов.
  • Как только таинственный код попадает в руки реального узла DOM, он может использовать API на этом узле для доступа ко всей остальной части документа. Вероятно, это не развивающаяся угроза, поэтому, вероятно, достаточно затем также издеваться над DOMNode API для элемента, который вы предоставляете таинственному коду.
  • Внутри таинственного кода могут быть вызовы, которые делают страшные или плохие вещи, но без использования API, которые вы изучаете. Если вы ничего не сделаете, чтобы обнаружить или предотвратить это, тогда произойдет что-то плохое, и внедрение этого кода в ваше приложение тоже приведет к появлению плохого.

Как вы узнаете, когда вы сделали достаточно предположений и тестирования? Ну, поскольку вы отказываетесь изучать 7000 строк кода, на самом деле нет способа быть уверенным. Насколько нам известно, там есть setTimeout скрытый там, который делает что-то действительно интересное через 45 минут. Единственный способ выяснить это — подождать 45 минут.

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


Лучшим подходом было бы использовать отладчик для изучения пути к коду, который вызывается при нажатии, а затем извлечь этот код или написать замену. Переключение некоторого содержимого, как правило, является почти тривиальной задачей. Если вам нужна помощь в этом, в Интернете есть бесчисленное количество руководств, без сомнения, включая некоторые вопросы и ответы здесь, на SO.