Javascript Проблемы с выполнением в одностраничном веб-приложении - PullRequest
0 голосов
/ 02 апреля 2020

Я пытался создать одностраничное веб-приложение (игру), которое будет динамически загружать различные HTML документы в одну веб-страницу.

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

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

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

Кто-нибудь знает решение моей проблемы или есть идеи получше?

Спасибо, Барри

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

Мне удалось написать решение, спасибо.

Описание решения.

  1. Загружается файл JSON , В файле JSON находится список объектов, представляющих мой сайт. Каждая JSON веб-страница имеет один HTML адрес веб-страницы и список всех JavaScript файлов, которые я хочу загрузить. Обратите внимание, что некоторые объекты в этом файле предназначены для использования в будущем моей программой.

  2. Затем он получает первую веб-страницу с использованием данных в файле JSON с использованием XMLhttpRequest и помещает содержимое в индекс . html стр.

  3. В функции load_ javascript (x) он сначала пытается удалить любые ранее динамически добавленные файлы JavaScript, ища атрибут data-jsloader. Это пользовательский атрибут, который моя программа присоединяет к любому динамически добавляемому JavaScript, поэтому его можно найти и удалить, когда пользователь изменяет веб-страницы в моей программе.

  4. В той же функции (load_ javascript) программа затем go просматривает список JavaScript файлов, которые необходимо динамически добавить на текущую страницу, а затем присоединяет к ней data-jsloader.

Почему я это сделал.

Я пишу многопоточную, многопользовательскую игру в покер на Facebook, которая использует веб-сокеты для поговорить с внутренним сервером Node. В этой игре у меня есть несколько веб-страниц, и все они должны были быть подключены через веб-сокеты к моему внутреннему серверу Node. Каждый раз, когда пользователь перемещался между веб-страницами, соединение WebSocket сбрасывалось, и веб-странице приходилось повторно подключаться к серверу.

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

Javascript Файл

let website_data;

(function() {

    let request = new XMLHttpRequest();

    request.open("GET", "/json/mysites.json");

    request.onreadystatechange = function() {
        if(request.readyState === 4 && request.status === 200)
        {       
            website_data = JSON.parse(this.responseText);
            load_webpage(0);
        }
    }

    request.send();
})()


function load_webpage(x)
{
    let xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            document.getElementById("app").innerHTML = xhttp.responseText;   
                load_javascript(x);           
        }
    };

    xhttp.open("GET", website_data[x].html_address);
    location.hash = website_data[x].hash;

    xhttp.send();    
}


function load_javascript(x)
{
    let element;

    // gets a list of all 
    let scripts = document.getElementsByTagName("script");

    let t = scripts.length;
    while (t--)
    {
        if(scripts[t].hasAttribute('data-jsloader') && scripts[t].getAttribute('data-jsloader') != x)
        {
            console.log(scripts[t].getAttribute('data-jsloader')); 
            scripts[t].parentNode.removeChild(scripts[t]);
        }
    }

    console.log(document.getElementsByTagName("script"));

    // load javascript files
    for(let i = 0; i < website_data[x].js_script.length; i++)
    {
        // console.log("Adding Javacscript File: " + website_data[x].js_script[i]);
        element = document.createElement('script');
        element.setAttribute("data-jsloader", x.toString());
        element.setAttribute("type", "text/javascript");
        element.setAttribute("src", website_data[x].js_script[i]);
        document.getElementsByTagName("head")[0].appendChild(element);
    }
}

JSON Файл (Содержит списки веб-сайтов и связанных JS местоположений файлов)

[
{
    "page_number":0,
    "html_address":"/views/splashpage.html",
    "hash": "splashpage.html",
    "js_script":["/js/background.js","/js/splashpage.js"]
},
{
    "page_number":1,
    "html_address":"/views/menu.html",
    "hash": "menu.html",
    "js_script":["/js/menu.js"]
},
{
    "page_number":2,
    "html_address":"/views/lobby.html",
    "hash": "lobby.html",
    "js_script":["/js/lobby.js"]
},
{   
    "page_number":3,        
    "html_address":"/views/kingpin.html",
    "hash": "game.html",
    "js_script":["/js/cards.js", 
                 "/js/chat.js", 
                 "/js/chips.js", 
                 "/js/ws_client.js", 
                 "/js/betting_controls.js", 
                 "/js/kingpin.js",
                 "/js/footer.js", 
                 "/js/ads_and_purchases.js"] 
    }
]

Указатель. html (Куда загружается содержимое веб-страницы)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kingpin</title>

    <!-- index css -->
    <link rel="stylesheet" href="css/index.css">

</head>
<body>
    <div id="app"></div>


</body>
</html>
0 голосов
/ 06 апреля 2020

Как я понимаю ваш вопрос, вы хотели динамически загрузить все в зависимости от определенного сценария, сначала при рендеринге HTML, я рекомендую вам использовать MVC и шаблон наблюдателя, во-вторых, для динамической загрузки сценария, который вы хотели

сцена 1: myScripts.load (['script1', 'script2'])

сцена 2: myScripts.load (['script2', 'script3'])

сцена 3: myScripts.load (['script1'])

Это то, что вы хотели?

...