Как я могу вставить код HTML и JavaScript из другого файла?

Это мой первый вопрос о SO. Так что, пожалуйста, будьте терпеливы со мной.

Я создаю очень маленькую веб-страницу с базовой структурой HTML.

<!DOCTYPE html>
<html lang = "en">
<head>
    <title>BootVid</title>
    <meta charset = "utf-8">
    <meta name = "viewport" content = "width=device-width, initial-scale=1">
    <link rel = "shortcut icon" type = "image/png" href = "img/favicon.png" />
    <link href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel = "stylesheet">
    <script src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
    <link href = "https://vjs.zencdn.net/8.3.0/video-js.css" rel = "stylesheet" />
    <script src = "https://vjs.zencdn.net/8.3.0/video.min.js"></script>

    <style>
        .fakeimg {
            height: 200px;
            background: #aaa;
        }
    </style>
</head>
<body>

    <div class = "container mt-5">
        <div id = "pageContent">
            <!--Page Content Goes Here-->
        </div>
    </div>

    <script>

        document.addEventListener("DOMContentLoaded", () => {
            routeTo("videoplayer");
        });

        function routeTo(path) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'components/' + path + '.html', true);
            xhr.onreadystatechange = function () {
                if (this.readyState !== 4) return;
                if (this.status !== 200) return; // or whatever error handling you want
                document.getElementById('pageContent').innerHTML = this.responseText;
            };
            xhr.send();
        }

    </script>

</body>
</html>

Таким образом, это в основном пустая веб-страница с div PAGE CONTENT, которую я загружаю HTML-кодом из отдельного файла .html в div pageContent на «главной» странице.

Базовая маршрутизация работает на 100% хорошо. Но когда я загружаю внешний html из одного из файлов .html, HTML отображается нормально, но код JavaScript никогда не выполняется. Как внедрить HTML-код в div вместе с кодом JavaScript, который должен выполняться при загрузке?

Вот пример страницы, которую мне нужно загрузить в div pageContent, который инициализирует экземпляр VideoJS.

<!--videoplayer.html-->
<div class = "container mt-5" id = "vidPlayer" hidden>
    <div class = "mx-auto col-12 col-md-10 col-lg-8">
        <video id = "my-video" class = "video-js vjs-fluid vjs-default-skin" controls preload = "none">
            <source id = "video-source" src = ".mp4" type = "video/mp4"> <!--video/mp4 application/x-mpegURL-->
        </video>
    </div>
</div>

<script>
    var player = videojs('my-video', {
        repsonsive: true,
        inactivityTimeout: 2000
    });
</script>

Любая помощь будет принята с благодарностью.

Вы можете извлечь файл сценария и добавить его в заголовок текущего документа.

mplungjan 22.07.2023 13:41

Не могли бы вы привести пример того, как это будет достигнуто? Просто базовый пример. Приспособится к моему варианту использования. Спасибо за ваш ответ

Werner Venter 22.07.2023 14:45

Я только что сделала

mplungjan 22.07.2023 18:42
Поведение ключевого слова "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
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вам нужно получить элементы скрипта из div pageContent, клонировать их и добавить в document.head. Вам просто нужно изменить функцию routeTo.

Ваша функция routeTo станет такой:

function routeTo(path) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'components/' + path + '.html', true);
    xhr.onreadystatechange = function () {
        if (this.readyState !== 4) return;
        if (this.status !== 200) return; // or whatever error handling you want
        document.getElementById('pageContent').innerHTML = this.responseText;
        /* Loop For The Scripts Inside The pageCont DIV */
        for (script of document.getElementById('pageContent').querySelectorAll('script')) {
            var scriptElem = document.createElement('script');
            if (script.src !== '' && typeof script.src !== 'undefined') {
                scriptElem.src = script.src;
            } else {
                scriptElem.innerHTML = script.innerHTML;
            }
            
            /* Remove the old script from pageContent div */
            script.parentNode.removeChild(script);
            
            /* Check if scriptElem exists or not */
            var scriptExists = (function() {
                for (elem of document.querySelectorAll('script')) {
                    if (elem.outerHTML === scriptElem.outerHTML) return true;
                }
                return false;
            })();
            
            /* If script doesn't exists, append it to the head */
            if (!scriptExists) {
             document.head.appendChild(scriptElem);
            }
        }
    };
    xhr.send();
}

Это даже поддерживает внешние сценарии (т. е. сценарии с атрибутом src, установленным для другого файла JavaScript).

Теперь это предотвратит дублирование скрипта и удалит скрипт из div pageContent, как только скрипт будет добавлен к заголовку.

document.getElementById('pageContent').querySelectorAll('scr‌​ipt')).forEach(scrip‌​t => { let scriptElem = document.createElement('script'); if (script.src !== '' && typeof script.src !== 'undefined') { scriptElem.src = script.src; } else { scriptElem.textContent = script.textContent; } document.head.appendChild(scriptElem); };
mplungjan 22.07.2023 16:36

@mplungjan, да, forEach был бы короче, но он устарел в Firefox 68 и удален с Firefox 71.

Codemaster United 22.07.2023 16:51

Ух ты! Большое спасибо

Werner Venter 22.07.2023 17:08

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

Werner Venter 22.07.2023 18:17

@CodemasterUnited Вы не правы. ВЫ МОЖЕТЕ думать о for each, о котором я даже не слышал, пока вы не заставили меня посмотреть. Конструкция for each является расширением языка ECMAScript; он определен в спецификации E4X, которая широко не поддерживается. for (script of document.getElementById('pageContent').querySelectorAll('scr‌​ipt')) очень неуклюжий

mplungjan 22.07.2023 18:47

@WernerVenter, я отредактировал код, чтобы предотвратить дублирование скриптов, и теперь он также удаляет скрипты из div pageContent.

Codemaster United 23.07.2023 11:00

@CodemasterUnited Большое спасибо. Это отличное решение.

Werner Venter 23.07.2023 18:31

@WernerVenter, пожалуйста 😉😉

Codemaster United 23.07.2023 19:12

Попробуйте этот скрипт, который проверит, загружен ли JS.

Я не проверял это вживую. Я могу сделать это на днях, так как это интригует

const head = document.querySelector("head");
const scriptIsLoaded = (script, src) => {
  const pageScripts = document.querySelectorAll('script');
  if (src) {
    // this may need some testing (pageScripts src = "jquery.js", script src = "https://....jQuery.js"
    return pageScripts.find(pageScript => pageScript.src.endsWith(script));
  }
  return pageScripts.find(pageScript => pageScript.textContent.replace(/\s+/g, "") === script.textContent.replace(/\s+/g, "")); // compare text with all whitespace removed.
}
const routeTo = (path) => {
  const url = `components/${path}.html`;
  fetch(url)
    .then((response) => response.text())
    .then((html) => {
      // Convert the HTML string into a document object
      var parser = new DOMParser();
      var doc = parser.parseFromString(html, 'text/html');
      document.getElementById('pageContent').innerHTML = html; // load the page
      // Get the script files
      doc.querySelectorAll('script').forEach(script => {
        const src = script.src;
        if (src) {
          if (scriptIsLoaded(src, true)) return; // already loaded
          let scriptObject = document.createElement("script");
          scriptObject.src = src;
          head.appendChild(scriptObject)
        } else {
          const text = script.textContent;
          if (text) {
            if (scriptIsLoaded(scriptObject)) return; // textContent already in a script
            let scriptObject = document.createElement("script");
            scriptObject.textContent = scriptObject.textContent;
            head.appendChild(scriptObject)
          }
        }
      });
    }).catch(function(err) {
      // There was an error
      console.warn('Something went wrong.', err);
    });
};

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