Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вопрос для профи про Jquery и setTimeout (https://javascript.ru/forum/misc/49663-vopros-dlya-profi-pro-jquery-i-settimeout.html)

vuler 23.08.2014 00:09

Вопрос для профи про Jquery и setTimeout
 
Доброго времени суток.
Возникла небольшая проблема.
На сайте пользователь может добавлять несколько телефонов, для того, чтобы добавить еще один телефон, ему нужно нажать на кнопку плюсик рядом с самым первым инпутом. В результате добавится еще один инпут для второго телефона и так далее, пока не достигнет максимальное число инпутов(телефонов, которое может ввести пользователь). Максимальное число задано в атрибуте max_copy.
Листинг кода:
обработка события нажатя на кнопку - добавить инпут.
$(document).ready(function() {
  $(".reg_add_input_pole").on('click', reg_add_input);
}


сама функция reg_add_input
function reg_add_input(){
	//elem=$(this);
	$(this).off('click', reg_add_input);
	punct_block=$(this).closest('.punct_block');
	el_col=punct_block.find('input').length;
	max_copy=Number(punct_block.attr('max_copy'));
	if (max_copy<el_col+1) {
		errorka=$("<div>Максимум "+(max_copy)+" записи(ей).</div>").hide();
		errorka.prependTo(punct_block.find('.reg_error_block')).slideDown(500,function rand(){
			setTimeout(function(){
				elem.closest('.punct_block').find('.reg_add_input_pole').on('click', reg_add_input);
				//elem.slideUp_remove();
				elem.remove();
				},600,elem=$(this))
			});
	}
		else
		{
			clone=punct_block.find('input:first').clone().val("").addClass('cloned').css('border-color','').css('color','').css("display","none").css("margin-top","10px").insertAfter(punct_block.find('input:last')).slideDown(300, function(){
				$(this).closest('.punct_block').find('.reg_add_input_pole').on('click', reg_add_input);
				});
		}
	}
Проблема в том, что сообщение об ошибке перестает удаляться, если очень быстро нажать добавить поле(reg_add_input_pole) например для телефона и сразу же для факса. сообщение об ошибке не пропадет, elem.remove(); - не выполнится. Если таймер будет маленький, то все работает как надо. Если вместо 600 поставить например 10000 и повторить те же действия, то сообщение об ошибке так же не будет пропадать.
Пытался решить проблему через рандом - создавал различные имена для setTimeout - не помогло. Получается что при повторном вызове функции(reg_add_input) setTimeout - просто пропадает и не исполняется.
Решение конечно есть коррдинальное - отключать полностью событие вызова этой функции - $(".reg_add_input_pole").off('click', reg_add_input); а после протикивания таймаута включать снова, но не хочется прибегать к этому.
Есть какое-нибудь решение?

vuler 23.08.2014 00:51

Решение нашлось путем выноса безымянной функции в глобальную область видимости и придания ей имени.
Это вообще Баг или какой-то смысл в этом есть?
function remove_erorku(elem){
	setTimeout(function(){
				elem.closest('.punct_block').find('.reg_add_input_pole').on('click', reg_add_input);
				elem.slideUp_remove();
				},600,elem=$(this));
	}


function reg_add_input(){
	//elem=$(this);
	$(this).off('click', reg_add_input);
	punct_block=$(this).closest('.punct_block');
	el_col=punct_block.find('input').length;
	max_copy=Number(punct_block.attr('max_copy'));
	if (max_copy<el_col+1) {
		errorka=$("<div>Максимум "+(max_copy)+" записи(ей).</div>").hide();
		errorka.prependTo(punct_block.find('.reg_error_block')).slideDown(500,remove_erorku);
	}
		else
		{
			clone=punct_block.find('input:first').clone().val("").addClass('cloned').css('border-color','').css('color','').css("display","none").css("margin-top","10px").insertAfter(punct_block.find('input:last')).slideDown(300, function(){
				$(this).closest('.punct_block').find('.reg_add_input_pole').on('click', reg_add_input);
				});
		}
	}

Rise 23.08.2014 08:17

vuler,
errorka.prependTo(punct_block.find('.reg_error_block')).slideDown(500, function(){
	setTimeout(function(elem){
		elem.closest('.punct_block').find('.reg_add_input_pole').on('click', reg_add_input);
		elem.remove();
	}, 600, $(this));
});


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