JavaScript - функция, возвращающая дважды - PullRequest
1 голос
/ 12 января 2012

Я не знаю много о JavaScript, вот код, который у меня есть:

<script language="JavaScript">
var x = 10

function startClock() {
    if (x !== ' ') {
        x = x - 1
        document.frm.clock.value = x
        setTimeout("startClock()", 1000)
    }
    if (x == 0) {
        x = ' ';
        document.frm.clock.value = x;
        success.location.href = "success.php";
    }
}
</script>
<body onLoad(startClock);>

затронутый iframe:

<input name="clock" size="3" readonly="readonly"

<iframe name="success" src="blank.htm"></iframe>

при отсчете таймера, success.php загружается дважды. Я знаю это, потому что 1.) Он дважды вставляет данные в мою БД, 2.) Я действительно вижу символ загрузки во вкладке, перезагружая секунду.

Когда я изменяю функцию на что-то вроде:

 <script language="JavaScript">

var x = 10
var y = 1

function startClock() {
    if (x !== 'Fin') {
        x = x - y
        document.frm.clock.value = x
        setTimeout("startClock()", 1000)
    }
    if (x == 0) {
        x = 'Fin';
        document.frm.clock.value = x;
        success.location.href = "success.php";
    }
}

</script>

... страница загружается только один раз.

Может кто-нибудь сказать мне, что здесь происходит? Я также попытался использовать '0' вместо '' и получил такое же двойное исполнение ...

Ответы [ 3 ]

1 голос
/ 12 января 2012

В Javascript есть ДВА оператора сравнения:

"==" - значит равно

«===» означает «точно равно» - это означает, что значение и ТИП должны быть одинаковыми

Я подозреваю (хотя я не буду проверять теорию), что если вы используете "===" вместо "==" в своем исходном коде, вы обнаружите, что он работает так, как задумывалось. Однако есть ряд вещей, которые требуют исправления: 1) вы не согласны с использованием «;», 2) код должен быть структурирован так, чтобы на любой данной итерации он мог только «перезапустить» таймер ИЛИ запустить успешное выполнение и НИКОГДА оба. Вот более чистая версия:

<script language="JavaScript">
   // 10 iterations at 1 second intervals
   var x = 10;

   function startClock() {
     document.frm.clock.value = --x;
     if (x <= 0) {
       document.frm.clock.value = x;
       success.location.href = "success.php";
     } else {
       setTimeout("startClock()", 1000);
     }
   } // startClock
</script>
<body onLoad(startClock);> 
0 голосов
/ 12 января 2012

Сначала пара вещей.В вашем примере есть ряд "неаккуратных" методов кодирования (например, пропущенные точки с запятой).Хотя код может выполняться, он может улучшиться с помощью некоторой справки jslint.

Итак, посмотрите на случай, когда x = 1. Вы уменьшаете x, так что теперь x = 0. Затем вы вызываете setTimeout, который будет ждать 1 секунду, а затемвызовите ваш метод с именем startClock.Однако setTimeout не блокирует ваше выполнение.Таким образом, сразу после вызова setTimeout с x = 0 выполняется код ниже, где вы устанавливаете x в '' (и загружаете свою страницу).Теперь, через секунду после запуска этого кода, ваш метод вызывается снова из-за срабатывания таймера.Поскольку x теперь равно '', верхний блок пропускается, и вы попадаете в блок x == 0 во второй раз.

0 голосов
/ 12 января 2012

Измените его на:

if (x == 0) {  // note this is now first
    x = ' ';
    document.frm.clock.value = x;
    success.location.href = "success.php";
} else if (x !== ' ') { // note the else/if
    x = x - 1;
    document.frm.clock.value = x;
    setTimeout("startClock()", 1000)
} 

В противном случае, когда x равен 1, будет установлен тайм-аут для startClock (), и местоположение будет загружено. Затем истечет время ожидания, снова загрузив страницу (так как x = ' ' и ' ' == 0 возвращает true).

Вероятно, лучше сказать:

if (x === 0) {  // note the ===
    x = ' ';
    document.frm.clock.value = x;
    success.location.href = "success.php";
} else if (x !== ' ') {
    x = x - 1;
    document.frm.clock.value = x;
    setTimeout("startClock()", 1000)
} 

Потому что вам не нужно преобразование истины, которое == делает для вас.


Ваш пример с 'Fin' вместо ' ' сработал, поскольку при вызове startClock() после загрузки местоположения x был 'Fin', а ('Fin' == 0) - false.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...