#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-файл.