2016-07-19 2 views
0

Я начинаю с одного элемента в стеке ar.Переменная не получает повторную инициализацию при повторном вызове функции

Я хотел бы использовать код: Если пользователь нажимает на правильную ссылку (один случайный выбор компьютера), переходим к следующему «уровню», где добавляем еще один элемент в стек.

На следующем уровне пользователь должен выбрать 2 правильные ссылки в том порядке, в котором они находятся в стеке. Как только пользователь это сделает, он должен перейти на следующий уровень и так далее. Это похоже на игру Саймона, и я просто пытаюсь подражать голой логике игры с этим.

HTML:

<a href="javascript:void(0);" id="l1">Link 1</a> 
<a href="javascript:void(0);" id="l2">Link 2</a> 
<a href="javascript:void(0);" id="l3">Link 3</a> 
<a href="javascript:void(0);" id="l4">Link 4</a> 
<div id="log"></div> 

Javascript

function check() { 
    var index = 0; 
    $('body').click(function(event) { 
    var log = $('#log'); 
    alert(index); 

    if ($(event.target).is(ar[index])) { 
     log.html(index + ' ' + event.target.id + ' was clicked.'); 
     index++; 

     if (index === ar.length) { 
     //if all clicked elements corresponded to correct 
     //order in array and reached end of array 
     level +=1; 
     console.log("Passing to next level. ", level); 
     randomId(); 
     console.log(ar); 
     log.html(ar); 
     check(); 
     } 
    } 
    else { 
     log.html(index + ' ' + event.target.id + ' was clicked. Is wrong'); 
     index = 0; 
    } 
    }); 
} 

var ar = []; 
divIds = ["#l1", "#l2", "#l3", "#l4"]; 
level = 1; 
randomId(); 
check(); 

function randomId() { 
    var min = 0; 
    var max = 3; 
    var id = Math.floor(Math.random() * (max-min+1)) + min; 
    var selectedId = divIds[id]; 

    ar.push(selectedId); 
    alert(ar); 
} 

Однако, когда я звоню check() функцию второй раз (когда мы переходим на уровень 2, где есть 2 элемента в стеке) значение индекса не является 0, несмотря на то, что var index = 0 является первой строкой функции check().

Я использую console.log и предупреждаю, чтобы зафиксировать значение индекса, но их простое число меня сбивает с толку. И, посмотрев на количество всплывающих окон, моя функция проверки работает как петля. Почему мы не получаем чистый список, когда мы вызываем функцию второй раз?

+3

Каждый раз, когда вы звоните' чек() 'вы добавляете ** дополнительный * * обработчик события ''. Обработчики из предыдущего вызова 'check()' не волшебным образом исчезают. То есть после двойного вызова 'check()', нажатие '' выполнит два обработчика событий. Если это проблема, удалите существующие обработчики событий, прежде чем связывать новую. –

+0

Зачем прикреплять обработчик кликов снова и снова? – LGSon

ответ

0

Обновлено - удален параметр index как он был не нужен

Если я понял ваш пример кода правильно, вы могли бы сделать, как этот

  • добавить index и level как параметр check
  • передать стартовое значение index/ level когда называем check() (сам вызывается)
  • заменить удалить внутреннюю check() с index = 0;

Таким образом, параметр check функций, index и level, будет работать, как, не глобальный статики переменная, которая, скорее всего, вам нужна.

Я также рекомендую объект приложения для ваших переменных и т. Д., А не глобальные переменные.

Боковое примечание: я не мог заставить фактический код работать, как он появился, он должен работать. После отказа от использования index и нескольких настроек он начал, хотя. Является ли это, как вы хотели, чтобы работать, или что цель для `index' переменной

var MyApp = {}; 
 
MyApp.ar = []; 
 
MyApp.divIds = ["#l1", "#l2", "#l3", "#l4"]; 
 

 
(function check(level) { 
 
    randomId(); 
 
    $('body').click(function(event) { 
 
    var log = $('#log'); 
 
    if ($(event.target).is(MyApp.ar[level-1])) { 
 
     log.html(event.target.id + ' was clicked.'); 
 
     if (level === MyApp.ar.length) { 
 
     //if all clicked elements corresponded to correct 
 
     //order in array and reached end of array 
 
     level++; 
 
     console.log("Passing to next level. ", level); 
 
     randomId(); 
 
     console.log(MyApp.ar); 
 
     } 
 
    } else { 
 
     log.html(event.target.id + ' was clicked. Is wrong'); 
 
    } 
 
    }); 
 
})(1); 
 

 
function randomId() { 
 
    MyApp.ar.push(MyApp.divIds[Math.floor(Math.random() * MyApp.divIds.length)]); 
 
    alert(MyApp.ar); 
 
}
a { 
 
    padding: 0 10px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<a href="javascript:void(0);" id="l1">Link 1</a> 
 
<a href="javascript:void(0);" id="l2">Link 2</a> 
 
<a href="javascript:void(0);" id="l3">Link 3</a> 
 
<a href="javascript:void(0);" id="l4">Link 4</a> 
 
<div id="log"></div>

+0

Да, спасибо, это именно то, что я хотел, чтобы код делал. Я снова вызывал чек(), думая, что он начал новый запуск функции, сбросив переменные и все остальное. Но, как вы уже упоминали, это повторное присоединение обработчика событий и беспорядок. Как примечание, закрытие поможет мне понять, почему в моем коде было несколько значений индекса, или это было просто из-за нескольких обработчиков событий? – Joan

+0

@Joan Что вы имеете в виду, когда говорите, что затворы помогут вам понять ...? – LGSon

+0

Что я имел в виду, так это то, что на моем уровне (где я не понимал, что я снова и снова добавлял обработчики событий, и это вызывало неустойчивое поведение), пытаясь понять замыкания, помогите мне лучше понять JS или просто смутить меня еще больше (I «Я пробовал читать его раньше и не понял все это хорошо)? Закрытия продолжают появляться на форумах, связанных с javascript, и когда я пытаюсь понять что-то, что не работает, я склонен думать, что это из-за некоторых передовых понятий, о которых я слышал и не понимаю. – Joan

-1

То, что вы используете здесь, называется Closures. В принципе, вы привязываете функцию, определенную в рамках другой функции, к событию click. Все клики относятся к тому же outer index их области действия и изменяют его.

Подробнее here

Если после прочтения, что вы все еще не в состоянии понять, что речь идет здесь, комментировать здесь, и я сделаю все возможное, чтобы помочь, я просто не хочу повторять то, что другие сказали ,

Редактировать: Как указали другие, у вас есть еще одна проблема здесь, то есть вы связываете событие click несколько раз. Вам нужно удалить предыдущую привязку (или даже лучше), просто изменив значения, не связывая несколько событий.

$('body').click(function(event){}) 

Эта строка кода - это то, что заставляет ваш клик работать. Вам не нужно запускать check() несколько раз, потому что, как только вы «привязали» обработчик событий один раз, вам нужно только проверить значения, не повторяя их снова и снова.

Другими словами, запустите check() только один раз и поместите index в функцию click вместо внешней, если вы хотите, чтобы она была сброшена при каждом нажатии. Если вы хотите, чтобы сбросить только после определенного количества кликов вы должны держать его за пределами закрытия работы функции следующим образом:

function check(){ 
    index = 0; 
    $('body').click(function(event){ 
    //NO INDEX HERE 
    }) 
} 

Но в этом случае (что у вас есть сейчас), необходимо вручную сбросить при некотором условии, из функции, которую вы привязали к клику.Например if(ar > neededNumber){index =0;}

+1

На самом деле это хуже, потому что при каждом вызове 'check()' создаются * новые * обработчики кликов и каждый имеет свой собственный закрытый индекс. –

+0

Но он выполняет проверку() только один раз и после этого запускается клик. Если бы он выполнял чек() каждый раз, когда его значение сбрасывалось, то в итоге ему пришлось бы ограничить несколько функций, что еще хуже, но он только вызывает check() один раз, судя по его коду. Это справедливо. – Dellirium

+0

Нет, он запускает чек снова и снова ... хорошо смотрится, и вы найдете его – LGSon