Функция jQuery ready вызывается дважды в диалоговом окне
Я создаю диалог jQuery с вкладками в PHP script. script использует директиву 'include' внутри цикла, итерация по вкладкам и включение других скриптов. Каждый из включенных файлов имеет данные для вкладки и <script> с помощью функции jQuery document.ready(). Без цикла он по существу делает это:
<div id="tabDialog">
<div id="tabs">
<ul>
<li><a href="#tab1'>Tab1</a></li>
<li><a href="#tab2'>Tab2</a></li>
</ul>
<div id="tabContainer">
<div id="tab1">
<?php include "tab1.php"; ?>
</div>
<div id="tab2">
<?php include "tab2.php"; ?>
</div>
</div>
</div>
</div>
и, например, tab1.php может иметь что-то вроде:
<script type="text/javascript">
$(document).ready (function () {
alert ('tab1 loaded');
});
</script>
Проблема заключается в создании и открытии диалогового окна с использованием диалогового окна < div id = " > как диалог DIV, функция готовности документа называется второй раз. Вот код диалога:
$("#tabDialog").dialog ({
autoOpen: false,
minWidth: 450,
minHeight: 400,
width: 600,
height: 500
}).dialog ('open');
В чем причина этого и какой был бы лучший способ исправить ситуацию? Я пытаюсь сохранить каждую функциональность вкладки в отдельных файлах, потому что они могут использоваться во многих ситуациях, и мне не нужно копировать связанный с ними код.
Спасибо за любую помощь или совет.
Ответы
Ответ 1
Я считаю, что нашел причину и создал достаточно хорошее решение. Когда jQuery создает диалог, он перемещает DIV, который содержит содержимое диалогового окна в DOM (до самого конца документа), и окружает этот div необходимыми строительными лесами, которые требуется для диалога (возможно, с помощью .append( ) или что-то подобное). Поскольку DIV, который динамически содержал Javascript внутри него, jQuery вызывал функцию document.ready() после того, как DIV был перемещен в DOM (т.е. Второй раз). Поэтому перед созданием диалогового окна I.remove() каждый тэг script в диалоговом окне DIV выглядит следующим образом:
$("#tabDialog").find ("script").remove ();
$("#tabDialog").dialog ({
autoOpen: true,
minWidth: 450,
minHeight: 400,
width: 600,
height: 500
});
Выполнение этого удаляет тэг script из DIV, который был изначально загружен, но сам script все еще существует. Я все еще исследую это, потому что я не совсем понимаю, где Javascript-код, который был динамически загружен, фактически "живет", но я подозреваю, что он расположен где-то вне DOM. Я проверил это в Chrome, Firefox и Exploder 8.
Я проверил, что все скрипты, которые изначально содержались в загруженных DIVs, по-прежнему функционируют должным образом, помещая кнопку в DIV и назначая функцию .click(). Вот небольшой тест, демонстрирующий это:
<html>
<head>
<link href="css/redmond/jquery-ui-1.8.1.custom.css" type="text/css" rel="stylesheet" media="screen" />
<link href="css/style.css" type="text/css" rel="stylesheet" media="screen" />
<script src="js/jquery-1.4.2.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.8.1.custom.min.js" type="text/javascript"></script>
</head>
<body>
<div id="dialogContents" style="display: none;">
<div style="border: 1px solid black; height: 98%;">
<form id="testForm">
<input type="text">
</form>
<button id="testButton">Test</button>
<script type="text/javascript">
$(document).ready (function () {
alert ("ready");
$("#testButton").click (function () {
alert ('click');
});
});
</script>
</div>
</div>
</body>
<script type="text/javascript">
$(document).ready (function () {
//
// Remove all the scripts from any place in the dialog contents. If we
// do not remove the SCRIPT tags, the .ready functions are called a
// second time. Removing this next line of Javascript demonstrates this.
//
$("#dialogContents").find ("script").remove ();
$("#dialogContents").dialog ({
width: 300,
height: 300,
title: 'Testing...'
});
});
</script>
</html>
Я ценю помощь, предоставленную в этой теме!
Ответ 2
Я не использовал .dialog()
слишком много, но вам нужно использовать метод jQuery ready()
в script?
Похоже, что .dialog()
имеет параметры обратного вызова, которые вы могли бы использовать.
Script в закладке:
<script type="text/javascript">
function onOpen() { alert('tab1 loaded') };
</script>
диалог:
$(this).dialog ({
autoOpen: false,
minWidth: 450,
minHeight: 400,
width: 600,
height: 500,
open: function(event, ui) { onOpen(); } // call function in script
}).dialog ('open');
Ответ 3
Итак, я должен сказать, что я не уверен на 100%, почему это происходит, хотя я понимаю, что диалог действительно поддерживает его собственное состояние, так что это может быть одной из причин. Но я мог бы уйти. Но способ обойти это - использовать что-то вроде этого:
$(document).one('ready', function () {
alert ('tab1 loaded');
});
Это гарантирует, что он будет работать только один раз, когда страница загружается.
Ответ 4
У меня также была эта проблема, но причина в моем случае была чем-то другим. У меня был самозакрывающийся элемент div внутри div, который использовался как держатель диалога. Когда я заменил самозакрывающийся элемент закрывающим тегом, функция готовности документа прекратила стрельбу дважды и выстрелила только один раз, как и ожидалось.
Например, это привело к тому, что функция готовности документа дважды срабатывала:
$("#foo").dialog({
// ...
});
...
<div id="foo" title="My Dialog">
<div id="bar" />
</div>
В то время как это только однократно активировало функцию документа:
$("#foo").dialog({
// ...
});
...
<div id="foo" title="My Dialog">
<div id="bar"></div>
</div>
Ответ 5
Вам, вероятно, не нужен вызов .dialog('open'); используйте опцию autoOpen: true вместо.
Ответ 6
Здесь результирующий текст страницы. Я сделал источник просмотра, а затем удалил все лишние вещи со страницы, чтобы попытаться сделать это проще.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<head>
<link href="css/redmond/jquery-ui-1.8.1.custom.css" type="text/css" rel="stylesheet" media="screen" />
<link href="css/style.css" type="text/css" rel="stylesheet" media="screen" />
<script src="js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.8.1.custom.min.js" type="text/javascript"></script>
</head>
<body>
<div id="tabDialog" style="position: relative; display: none;" title="Test Dialog">
<div id="tabs" style="position: absolute; top: 5px; bottom: 40px; left: 3px; right: 3px;">
<ul>
<li><a href='#tab1'>Tab #1</a></li><li><a href='#tab2'>Tab #2</a></li>
</ul>
<div class="tab_container" style="position: absolute; top: 35px; bottom: 0px; left: 1px; right: 1px; overflow: auto;">
<div id='tab1' class='tabPage ui-dialog-content'>
<form id="tab1Form">
More testing... <input class="keypressMonitor" type="text">
</form>
Testing...<br/>
Testing...<br/>
<script type="text/javascript">
$(document).ready (function () {
alert ('tab1 loaded');
$("#tab1Form").bind ('save', function () {
alert ("in tab1Form.save ()");
});
});
</script>
</div>
<div id='tab2' class='tabPage ui-dialog-content'>
<form id="tab2Form">
<div style="position: absolute; left: 1px; right: 1px; top: 1px; bottom: 1px;">
Testing: <input class="keypressMonitor" type="text">
<textarea id="testArea" class="keypressMonitor tinymce" style="position: absolute; top: 30px; bottom: 2px; left: 2px; right: 2px;"></textarea>
</div>
</form>
<script type="text/javascript">
$(document).ready (function () {
$("#tab2Form").bind ('save', function () {
alert ("in tab2Form.save ()");
});
});
</script>
</div>
</div>
</div>
<div id="dialogButtons" style="position: absolute; bottom: 3px; left: 3px; right: 15px; text-align: right; height: 32px;">
<button class="applyButton" disabled>Apply</button>
<button class="okButton" disabled>Ok</button>
<button class="cancelButton">Cancel</button>
</div>
</div>
<script type="text/javascript">
$(document).ready (function () {
$("#tabs").tabs ();
$("button").button ();
/**
* Pressing the cancel button simply closes the dialog.
*/
$(".cancelButton").click (function () {
$("#tabDialog").dialog ("close");
});
$("#tabDialog").dialog ({
open: function () {
},
autoOpen: true,
minWidth: 450,
minHeight: 400,
width: 600,
height: 500,
height: 'auto'
});
});
</script>
</body>
</html>
Ответ 7
Помещает ваш метод script в create
:
$.dialog({
<your parameters>
create: function() {
<your script>
}
}
С помощью этого метода ваш script вызывается один раз, только вы создаете диалог, а не дважды!