Javascript загружается только в первый раз или при обновлении

#javascript #html #cordova #jquery-mobile

#javascript #HTML #кордова #jquery-мобильный

Вопрос:

Я создаю кроссплатформенное приложение с Cordova и jQuery Mobile 1.4.5, у меня есть простая html страница, которая должна загружать javascript файл.

 <!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">

        <!-- Include jQUERY --->
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="jquery/jquery.mobile-1.4.5.css">
        <link rel="stylesheet" href="css/custom-icons.css">
        <script src="jquery/jquery.js"></script>
        <script src="jquery/jquery.mobile-1.4.5.js"></script>

        <title>myPage</title>
    </head>
    <body>
        <!-- jQUERY HEADER is a navigation bar with multiple options -->
        <div data-role="header">
            <a href="index.html" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
            <h1>my app</h1>
            <div data-role="navbar">
                <ul id="nav-bar">
                    <li><a href="a.html" data-page="a">a</a></li>
                    <li><a href="b.html" data-page="b">b</a></li>
                    <li><a href="c.html" data-page="c">c</a></li>
                </ul>
            </div>
        </div>

       <div role="main" class="ui-content">
           <center><h3><i>A title</i></h3>

           <fieldset data-role="controlgroup" data-type="horizontal" data-mini="true">
                <legend>my legend</legend>
                <input type="checkbox" data-role="flipswitch" name="flip1" id="flip1">
                <input type="checkbox" data-role="flipswitch" name="flip2" id="flip2">
                <input type="checkbox" data-role="flipswitch" name="flip3" id="flip3">
                <input type="checkbox" data-role="flipswitch" name="flip4" id="flip4">
           </fieldset>
           </center>
       </div>

        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="js/home.js"></script>
    </body>
</html>
  

Однако home.js файл загружается только в первый раз (или при обновлении), но если я, например, включен b.html и я перехожу на указанную выше страницу ( index.html ), то home.js не выполняется.

Домашний home.js файл просто содержит console.log("executed"); , который печатается, когда cordova загружает index.html файл, но не тогда, когда я позже вручную перейду на эту страницу через панель навигации.

РЕДАКТИРОВАТЬ: обратите внимание, что другие страницы не показывают такого поведения. Например, на странице ниже всегда загружается файл javascript.

 <!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <!-- <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <link rel="stylesheet" type="text/css" href="css/index.css"> -->

        <!-- Include jQUERY --->
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="jquery/jquery.mobile-1.4.5.css">
        <link rel="stylesheet" href="css/custom-icons.css">
        <script src="jquery/jquery.js"></script>
        <script src="jquery/jquery.mobile-1.4.5.js"></script>

        <title>bla bla</title>
    </head>
    <body>
        <!-- jQUERY HEADER is a navigation bar with multiple options -->
        <div data-role="header">
            <a href="index.html" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
            <h1>smartHub</h1>
            <div data-role="navbar">
                <ul id="nav-bar">
                    <li><a href="a.html" data-page="a">a</a></li>
                    <li><a href="b.html" data-page="b">b</a></li>
                    <li><a href="c.html" data-page="c">c</a></li>
                </ul>
            </div>
        </div>

        <div data-role="collapsible" data-collapsed-icon="carat-d" data-expanded-icon="carat-u">
          <h1>...</h1>
            <ul data-role="listview" data-inset="false">
                ...
            </ul>
        </div>

        <div data-role="collapsible" data-collapsed-icon="carat-d" data-expanded-icon="carat-u">
          <h1>...</h1>
            <ul data-role="listview" data-inset="false">
                ...
            </ul>
        </div>

        <script type="text/javascript" src="js/someOtherFile.js"></script>
    </body>
</html>
  

РЕДАКТИРОВАТЬ: я «исправил» проблему, изменив ссылку на домашнюю страницу в заголовке на эту <a href="#" id="homeButton" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a> , а затем поместив обработчик нажатия кнопки «Домой» следующим образом :

 $("#homeButton").on("click", function() {
    window.location.replace("index.html"); 
});
  

Выполнение этого эквивалентно реальному переходу на страницу. Однако я не считаю это правильным решением. Было бы неплохо, если бы кто-нибудь мог указать, почему моя домашняя страница демонстрирует такое поведение.

Кроме того, на самом деле это вообще не решение, поскольку кажется, что элементы, которые я вставил, localStorage теряются при перенаправлении index.html

РЕДАКТИРОВАТЬ: я воспроизвел проблему как можно проще.Воспроизведение содержит два HTML-файла, которые можно найти здесь . При просмотре на index.html нем печатается On index.html , затем мы можем использовать панель навигации, чтобы перейти к a.html которой будет печатать On page a.html . Если мы затем снова перейдем к индексу, нажав кнопку «Домой», он больше не будет печатать On index.html (следовательно, скрипт не выполняется), в то время как если мы a.html снова перейдем к нему, он будет печатать On page a.html (следовательно, этот скрипт выполняется каждый раз, когда мы переходим на страницу, в то время как скрипт на индексной странице не выполняется).

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

1. b.html Содержит ли тот же HTML?

2. @fzzle b.html содержит тот же заголовок, но, конечно, имеет другое тело и включает в себя другой файл javascript.

3. Может ли избиратель, по крайней мере, быть конструктивным? В чем причина этого?

4. Я прав, когда думаю, что ваше приложение не является одностраничным приложением? Если да, то почему вы не включаете cordova.js на других страницах? (спрашиваю, потому что, похоже, в этом разница между файлами)

5. @RonaldPK Действительно, мое приложение не является одностраничным приложением. Я не уверен, но я думаю, что cordova.js это нужно загружать только один раз, иначе это приводит к ошибке Error: cordova already defined .

Ответ №1:

С jQuery Mobile index.html становится контейнером для всех страниц вашего приложения. Поэтому, когда пользователь переходит к a.html , его содержимое вводится в DOM, уже созданный для index.html . Скрипт index.html остается активным. index.html содержимое остается в DOM, но скрыто. Когда пользователь переходит обратно index.html , содержимое index.html просто снова становится видимым. Содержимое a.html удаляется из DOM.

Когда пользователь снова переходит к a.html нему, его содержимое снова вводится в DOM, снова выполняя любой скрипт внутри него.

Возьмите эти страницы и посмотрите консоль.

index.html:

 <!DOCTYPE html>
<html>
    <head>  
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- Include jQUERY -->
        <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
        <script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
        <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

        <title>Index page</title>
    </head>
    <body>
        <div data-role="page" id="index">
            <div data-role="header">
                <a href="#" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
                <h1>My app title</h1>
                <div data-role="navbar">
                    <ul id="nav-bar">
                        <li><a href="a.html" data-page="a">a</a></li>
                        <li><a href="#" data-page="b">b</a></li>
                        <li><a href="#" data-page="c">c</a></li>
                    </ul>
                </div>
            </div>

           <div role="main" class="ui-content">
               <h3><i>Some title</i></h3>
           </div>

            <script>
                console.log("On index.html");
            </script>
        </div>
        <script>
            $(document).on('pageshow', function() {
                // catch the ID of the active page
                var curID = $('.ui-page-active').attr('id');
                console.log("curID: "   curID);
                switch (curID) {
                    // code here
                    default: break;
                }
            });
        </script>
    </body>
</html>
  

a.html:

 <html>
    <head>  
        <!-- Note: no need to re-include the jQM-files. They're already around. -->
        <title>Other page page</title>
    </head>
    <body>
        <div data-role="page" id="pageA">
            <div data-role="header">
                <a href="index.html" class="ui-btn ui-icon-home ui-btn-icon-left">Home</a>
                <h1>My app title</h1>
                <div data-role="navbar">
                    <ul id="nav-bar">
                        <li><a href="a.html" data-page="a">a</a></li>
                        <li><a href="#" data-page="b">b</a></li>
                        <li><a href="#" data-page="c">c</a></li>
                    </ul>
                </div>
            </div>

           <div role="main" class="ui-content">
               <p>Page a</p>
           </div>
            <script>
                console.log("On page a.html");
            </script>
        </div>
    </body>
</html>
  

Обратите внимание, что я добавил DIVs с data-role="page" уникальными идентификаторами и с уникальными идентификаторами в обоих файлах.

Обработчик pageshow событий является ключевым. Он запускается каждый раз, когда jQM показывает «страницу». (В with может быть несколько элементов index.html data-role="page" , все они обрабатываются как «страницы»).

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

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

Ответ №2:

Это проблема с кэшированием, вы можете использовать управление версиями для вашего JS-файла:

Пример:

 <script type="text/javascript" src="js/home.js?version=1.0.0.5"></script>
  

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

1. Не могли бы вы быть немного более откровенными? Я не занимаюсь веб-разработкой. Что именно это будет делать? Всегда ли мне нужно отправлять новый случайный номер версии, если я не хочу, чтобы файл кэшировался?

2. Если вы разрабатываете и активно редактируете файл, вы можете установить управление версиями (если включено кэширование) или отключить кэширование через .htaccess . Надеюсь, я правильно понял ваш вопрос. Если нет, пожалуйста, поправьте меня

3. Поскольку эти страницы все еще действительно базовые, я могу протестировать их в браузере. Я использую safari и отключил кэширование, чтобы проверить, является ли это проблемой кэширования. Однако проблема сохраняется, и я действительно не понимаю, почему. На других страницах этой проблемы нет, я не понимаю, почему..

4. Я попробовал ваше решение .htaccess, однако обратите внимание, что я использую Cordova, поэтому я не уверен, куда поместить файл? Я поместил его в www папку, в которой находятся мои html файлы, однако это не решило проблему (попробовал это в браузере и на моем телефоне).

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

Ответ №3:

Извините, я пока не могу комментировать. Я пытаюсь предложить, чтобы попытаться поместить ваш необходимый JS в ваш index.html или index. blah blah blah . Или поместите его в загруженный view/page

Приветствия

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

1. Я считаю встроенные скрипты плохой практикой, особенно для больших файлов. В моем случае код javascript составляет около 200 loc, что было бы ужасно, если поместить его встроенным в html-файл.