Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Глобальные переменные и остановка таймера



Посмотрите видеоурок https: //youtu.be/uy6Gk-_Ll_o

Метод setTimeout и рекурсия

Хотя метод setTimeout и не предназначен для создания таймеров, однако их все равно можно делать с ее помощью, если воспользоваться рекурсией (это когда функция вызывает сама себя).

В данном примере значение атрибута value каждую секунду увеличивается на единицу. Сделано это хитрым образом: нажатие на кнопку start запускает функцию timer, которая увеличивает значение инпута на 1 и после этого вызывает саму себя с задержкой в 1 секунду. Получится, что через 1 секунду функция timer опять начнет работать, опять увеличит значение инпута и опять вызовет саму себя с задержкой. И так до бесконечности:

< input type=" text" value=" 1" id=" test" >

< input type=" submit" value=" start" onclick=" timer()" >

function timer() {

    var elem = document.getElementById('test');

    elem.value = parseInt(elem.value) + 1;

 

    window.setTimeout(timer, 1000); //рекурсия

}

Остановить такой таймер можно просто не дав запуститься методу setTimeout, например, через if.

В следующем примере таймер остановится, когда значение инпута станет равно 10-ти:

< input type=" text" value=" 1" id=" test" >

< input type=" submit" value=" start" onclick=" timer()" >

function timer() {

    var elem = document.getElementById('test'); //получаем наш инпут

    elem.value = parseInt(elem.value) + 1; //увеличиваем значение атрибута на единицу

 

    if(elem.value < 10) { //если в инпуте меньше 10-ти - то работаем дальше

            //Функция timer запускает саму себя с задержкой в 1 секунду:

            window.setTimeout(timer, 1000);

    }

}

Доп. уроки

Слайдер текста: https: //youtu.be/I-_DkOqZPNo,

Простой слайдер картинок: https: //youtu.be/I5pVspOUquU,

 


Урок 23. Продвинутая работа с событиями в JavaScript

В данном уроке мы с вами разберем все способы работы с событиями в JavaScript.

События через атрибуты

Вы уже хорошо знаете первый способ привязать событие к элементу - с помощью атрибута, например onclick (если вы не помните этого или пропустили - см. урок основы работы с событиями JavaScript).

Напомню еще раз этот способ на примере: сейчас по клику на кнопку сработает функция func, которая выводит на экран alert:

< input type=" submit" onclick=" func()" >

function func() {

    alert('! ');

}

Задания события через атрибут имеет свои недостатки: если, к примеру, я хочу ко всем инпутам на странице привязать определенное событие - мне придется полазить по HTML странице, найти все инпуты и каждому добавить атрибут с событием. Это не очень удобно и хотелось бы иметь под рукой более продвинутый способ работы с событиями.

Поэтому давайте посмотрим, что еще нам может предложить JavaScript при работе с событиями.

События через работу с атрибутами

По сути атрибут onclick является таким же атрибутом, как, к примеру, value. И, если мы могли менять атрибут value таким образом - elem.value, то точно также мы можем менять атрибут onclick.

Если мы сделаем так: elem.onclick = func, то привяжем к элементу elem функцию func. Посмотрите пример и под ним мы обсудим все нюансы этого способа:

< input type=" submit" id=" test" >

var elem = document.getElementById('test');

elem.onclick = func;

function func() {

    alert('! ');

}

Теперь я должен открыть вам страшную тайну JavaScript: если функция написана без круглых скобок, например func, то она возвращает свой исходный код, а если с круглыми скобками, например func(), то возвращает результат работы функции.

Я уверен, что прочитав это, вы не до конца поймете то, что я хотел вам донести, поэтому запустите пример и еще раз перечитайте предыдущий абзац. Вот пример:

< input type=" submit" id=" test" >

//Функция возвращает строку '! '

function func() {

    return '! ';

}

 

alert(func()); //вы увидите строку '! '

alert(func); //а сейчас вы увидите исходный код функции func!

Теперь, зная эту страшную тайну, вернемся к строке elem.onclick = func - в данном случае я в атрибут onclick записываю исходный код функции, а не ее результат - и все работает. Если вы сделаете так - elem.onclick = func() - то запишите результат функции и ничего не будет работать.

Кстати, результатом функции func() будет undefined, так как у нее нет команды return. Напомню код функции, о которой идет речь:

< input type=" submit" id=" test" >

function func() {

    alert('! ');

}

Давайте вспомним метод setInterval (см. урок работа с таймерами в JavaScript), когда мы использовали его таким образом window.setInterval(timer, 1000) - в этом случае мы также писали функцию timer без круглых скобок, потому что нас интересовал не результат работы функции, а ее код.

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

Достоинства и недостатки такого способа

Давайте теперь обсудим достоинства и недостатки этого способа.

Достоинства

Достоинства такие: теперь, если мы захотим задать одновременно одно событие всем инпутам на странице, нет нужды вручную прописывать каждому из них атрибут с событием. Можно просто получить все инпуты, перебрать их циклом и каждому привязать событие.

Давайте сделаем это. Получим все инпуты с помощью getElementsByTagName и в цикле привяжем каждому такое событие: пусть по клику каждый инпут выдает алертом текст '! ':

< input type=" submit" value=" 1" >

< input type=" submit" value=" 2" >

< input type=" submit" value=" 3" >

< input type=" submit" value=" 4" >

< input type=" submit" value=" 5" >

/*

    Этот код будет запускаться по загрузке страницы.

    Напоминаю, что писать его нужно после HTML кода.

*/

 

var elems = document.getElementsByTagName('input');

for (var i = 0; i < elems.length; i ++ ) {

    elems[i].onclick = func;

}

 

function func() {

    alert('! ');

}

Теперь нажатие на любой инпут будет приводить к тому, что будет срабатывать функция func, которая алертом выводит '! '.

Использование this

Давайте усложним задачу и сделаем так, чтобы alert выводил содержимое атрибута value того инпута, на который кликнули мышкой.

Для этого нужно воспользоваться this, только не так, как мы это делали раньше. Раньше, когда мы писали событие прямо в атрибут, мы делали так: onclick=" func(this)" , однако сейчас вот так - elems[i].onclick = func(this) - мы сделать не можем.

Во-первых, потому, что функцию func здесь нужно писать без круглых скобок, иначе будет не исходный код, а результат работы функции.

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

Вы можете спросить, почему тут - onclick=" func()" - в функции написаны круглые скобки, хотя по логике там тоже требуется исходный код, а не результат. Об этом вы узнаете в уроке про анонимные функции чуть позже.

Так как правильно использовать this в нашей конструкции elems[i].onclick = func? На самом деле тут this доступен внутри функции func и он ссылается на тот элемент, в котором возникло событие, вызвавшее эту функцию. То есть, если я делаю клик по первому инпуту - в this будет лежать ссылка на него, а если по второму - то на него.

В данном случае считайте, что this - это будто переменная elem, полученная через getElementById. К примеру, elem.value позволяет обратиться к атрибуту value, значит this.value будет делать то же самое.

Итак, давайте все-таки решим нашу задачу - сделаем так, чтобы alert выводил содержимое атрибута value того инпута, на который кликнули мышкой:

< input type=" submit" value=" 1" >

< input type=" submit" value=" 2" >

< input type=" submit" value=" 3" >

< input type=" submit" value=" 4" >

< input type=" submit" value=" 5" >

var elems = document.getElementsByTagName('input');

for (var i = 0; i < elems.length; i ++ ) {

    elems[i].onclick = func;

}

 

function func() {

    alert(this.value); //изменение только здесь

}

Учтите, что если вы попытаетесь воспользоваться this внутри функции, которая была прописана прямо в атрибуте (то есть первым способом задать событие) - у вас ничего не выйдет. Смотрите пример неправильного кода:

< input type=" submit" value=" Кнопка! " onclick=" func()" >

function func() {

    alert(this.value); //не выведет ожидаемого

}

В данном случае контекст выполнения таков, что this ссылается на window, а не на текущий элемент. Почему так - поговорим, когда вы разберете анонимные функции.

Напоминаю правильный вариант:

< input type=" submit" value=" Кнопка! " onclick=" func(this)" >

function func(elem) {

    alert(elem.value); //выведет содержимое атрибута value

}

Недостатки

Теперь поговорим о недостатках. Недостатком такого способа будет то, что мы можем привязать к событию только одну функцию. Если попытаться сначала записать одну функцию, а потом другую - у нас ничего не получится.

В следующем примере мы пытаемся привязать к событию onclick сразу две функции func1 и func2. Однако по клику на элемент сработает только вторая функция, так как она затрет первую:

< input type=" submit" id=" test" >

var elem = document.getElementById('test');

elem.onclick = func1; //тут мы сначала привязали func1

elem.onclick = func2; //а теперь func2 и func1 уже не привязана

 

function func1() {

    alert('1');

}

 

function func2() {

    alert('2');

}

В принципе, эту проблему легко обойти, если ввести еще и третью функцию func3. Привяжем к атрибуту onclick только func3, а она пусть вызывает func1 и func2 у себя внутри:

< input type=" submit" id=" test" >

var elem = document.getElementById('test');

 

elem.onclick = func3; //тут привязывается только функция func3

 

//func3 вызывает func1 и func2:

function func3() {

    func1();

    func2();

}

 

function func1() {

    alert('1');

}

 

function func2() {

    alert('2');

}

Как вы видите, этот недостаток не слишком существенный и его легко обойти. Только что вводится лишняя функция, что немного неудобно.

Однако, есть еще один недостаток - мы не можем легко отвязать от onclick, к примеру, только функцию func1, оставив func2 привязанным. Можно, конечно же, накрутить большие конструкции кода, однако это не нужно, если пользоваться еще более продвинутым способом привязать событие - через addEventListener. Давайте посмотрим, как с работать с этой функцией:

Работа с addEventListener

Метод addEventListener первым параметром принимает название события, а вторым - функцию, которую нужно привязать к этому событию. При этом имя события пишется без 'on': 'click' вместо 'onclick', 'mouseover' вместо 'onmouseover' и так далее. Имя функции (второй параметр) пишется без кавычек и без круглых скобок (зачем это нужно, мы с вами уже разобрали выше).

Давайте сделаем так, чтобы по клику на кнопку вызывалась функция func:

< input type=" submit" id=" test" >

var elem = document.getElementById('test');

elem.addEventListener('click', func);

 

function func() {

    alert('! ');

}

Привяжем теперь одновременно два события. При этом таких проблем, как в предыдущем случае у нас не возникнет - события не будут затирать друг друга, сколько бы их не объявили:

< input type=" submit" id=" test" >

var elem = document.getElementById('test');

elem.addEventListener('click', func1);

elem.addEventListener('click', func2);

 

function func1() {

    alert('1');

}

function func2() {

    alert('2');

}

Если вы скопируете этот код и запустите его у себя - сработает и функция func1, и функция func2.


Поделиться:



Последнее изменение этой страницы: 2019-10-24; Просмотров: 183; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.053 с.)
Главная | Случайная страница | Обратная связь