Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   единожды выполнить callback после .hide() нескольких элементов. (https://javascript.ru/forum/jquery/73292-edinozhdy-vypolnit-callback-posle-hide-neskolkikh-ehlementov.html)

winch 04.04.2018 14:56

единожды выполнить callback после .hide() нескольких элементов.
 
здравствуйте.
Столкнулся с такой проблемой:
при выполнении jquery функции
.hide(duration, callback)
callback выполняется для каждого скрываемого элемента, (это подтверждается документацией и моими экспериментами).
А как быть, если необходимо чтобы callback выполнился строго 1 раз, после скрытия всех элементов?

laimas 04.04.2018 15:43

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

winch 04.04.2018 15:55

понял! спасибо за наводку, попробую воспользоваться.
А я прочитал здесь: http://jquery.page2page.ru/index.php...ементов
что в callback не передается параметров. или там устаревшая инфа?

Nexus 04.04.2018 16:04

Цитата:

Сообщение от winch
что в callback не передается параметров

Это так.

laimas 04.04.2018 16:04

Цитата:

Сообщение от winch
в callback не передается параметров

А да, все верно, но это не проблема:

var obj = $(selector).hide(300, function() {
здесь можно узнать является ли this последним в наборе obj
})

Nexus 04.04.2018 16:04

Можно так: https://jsfiddle.net/7dtre9gL/

winch 04.04.2018 16:22

Воспользовался вариантом по ссылке от Nexus. так работает.
А как узнать через this последний ли это элемент, я так и не понял.

j0hnik 04.04.2018 16:30

Цитата:

Сообщение от winch (Сообщение 482281)
Воспользовался вариантом по ссылке от Nexus. так работает.
А как узнать через this последний ли это элемент, я так и не понял.

сравнить this == с последним элементом набора.

winch 04.04.2018 16:40

Цитата:

Сообщение от j0hnik (Сообщение 482283)
сравнить this == с последним элементом набора.

а чтобы получить последний элемент, надо ещё раз делать запрос по этому же селектору?
как-то не очень лаконично получается.

j0hnik 04.04.2018 16:43

winch, самый короткий вариант вам написал Nexus.

winch 04.04.2018 16:43

хотя можно конечно сохранить полученный набор в переменную, а потом уже с ней работать...

Ладно, всё понятно, вопрос решен. всем спасибо!

laimas 04.04.2018 16:47

Цитата:

Сообщение от winch
а чтобы получить последний элемент, надо ещё раз делать запрос по этому же селектору?
как-то не очень лаконично получается.

Зачем, набор уже сохранен в переменной, получайте в наборе последний и сравнивайте с this.

Но если это для - выполняем что-то для элементов набора, а если последний в наборе, то ... Иначе вам нужно то, что писал Nexus. Правда уже скрытый скрывать за время Т ни к чему, корректней такая тогда запись
$('div').not(':last').hide(300).end().last().hide( 300,function() ....

PS. Если выполнить раз, не важно в какой последовательности, то

$(selector).hide(time).last().hide(function() {....})

так как скрытый уже не будет вновь скрываться, просто функция выполнится после скрытия всех.

Nexus 05.04.2018 07:54

Цитата:

Сообщение от laimas
Правда уже скрытый скрывать за время Т ни к чему, корректней такая тогда запись
$('div').not(':last').hide(300).end().last().hide( 300,function()

Можно просто очистить очередь анимации для последнего элемента, так короче будет.
$('div').hide(300).last().stop(true).hide(300,callback);

Белый шум 05.04.2018 08:48

Усложним задачу: а если на некоторых из этих элементов уже висят какие-то анимации (поэтому они скроются позже последнего), а колбэк надо выполнить только когда все элементы будут скрыты? ;-)

Nexus 05.04.2018 09:25

Белый шум, как вариант
var counter = 0,
    callback = () => {
        ++counter >= len && alert('Complete');
    },
    len = $('div').hide(300, callback).length;

laimas 05.04.2018 12:32

Цитата:

Сообщение от Nexus
Можно просто очистить очередь анимации

Да можно как угодно. )

winch 05.04.2018 20:59

Цитата:

Сообщение от Белый шум (Сообщение 482363)
Усложним задачу: а если на некоторых из этих элементов уже висят какие-то анимации (поэтому они скроются позже последнего), а колбэк надо выполнить только когда все элементы будут скрыты? ;-)

Да, в моем случае так и получилось. Некоторые пункты заканчивали анимацию позже последнего. (заметил это когда я стал отлаживать)
Окончательный код я сделал такой:
var sel = $(".menu1 .MenuItem > div");
var i = 1;  
sel.slideUp(700, function(){
   if (sel.length == i++) 
	DoCallback();
});

laimas 06.04.2018 04:56

var sel = $(".menu1 .MenuItem > div").slideUp(700, function(){
   if (sel.last() == this) DoCallback();
});


и считать ничего не надо.

winch 06.04.2018 05:17

Цитата:

Сообщение от laimas (Сообщение 482542)
var sel = $(".menu1 .MenuItem > div").slideUp(700, function(){
   if (sel.last() == this) DoCallback();
});

и считать ничего не надо.

Это будет неправильно работать, потому что последний элемент в выборке и элемент последним заканчивающий свою анимацию - это могут быть разные элементы.

laimas 06.04.2018 05:24

Ну если строго так нужно, тогда да.


Часовой пояс GMT +3, время: 16:41.