Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Зависание кнопок меню при быстром переключении (onMouseOver) (https://javascript.ru/forum/dom-window/42674-zavisanie-knopok-menyu-pri-bystrom-pereklyuchenii-onmouseover.html)

Kapitan79 05.11.2013 15:29

Зависание кнопок меню при быстром переключении (onMouseOver)
 
Всем привет!

Я пытаюсь сделать вертикальное меню для сайта (в целях самообучения ).
У меня есть три кнопки. По замыслу при наведении, например, на верхнюю кнопку две нижние должный "съехать" вниз и открыть место для подпунктов меню.

Всё вроде бы работает, но имеет место глюк - если быстро передвигать мышку по пунктам меню, нижние кнопки застревают и меню перестаёт нормально работать.
Не могу разобраться почему:-E

Kapitan79 05.11.2013 15:33

function move_obj (id,mt,mts,p)
{	
	//alert ('move_obj (id,mt,mts,p) запущена. ID = '+id+ ' mt = '+mt+' p = ' +p)
	//Ниже получаем координату TOP по элементу HTML
	var obj = document.getElementById (id);
	if (p == 'top'){var top = parseInt (window.getComputedStyle(obj,null).top)}
	else {var top = parseInt (window.getComputedStyle(obj,null).height)}
	//alert ('top =' +top)
	// Ниже проверяем, не достигла ли кнопка нижнего "порога"
	// по координате TOP и если это не произошло сдвигаем её на 1 шаг
	//alert ('Проверяем. ID = '+id+' mt = '+mt+' top ='+top)
	
	if (top != mt)
	{
		//alert ('Условие пройдено')
		top = top+mts;
		if (p == 'top') {obj.style.top = top + 'px'}
		else 
		{
			obj.style.height = top + 'px'
		}		
	//	return (top)		

	} else if (p!= 'height'){ch_stat (id,mts); return ('stop')} // в случае, если кнопка достигла крайнего положения, запускаем функцию ch_stat (id,mts) и после её выполнения возвращем значение 'stop'

};

function ch_stat (id,mts)

{
	//обработка окончания движения вниз
	if (mts > 0)
	{
		//alert ('Спустились. id = '+id)
		//Вотрая кнопка внизу
		if (id == 'id_u22_div')
		{
			//alert ('Для '+ id+ ' m2 = '+m2)
			m2 =2
		}
		//третья кнопка внизу
		if (id == 'id_u23_div')
		{
			//alert ('Для '+ id+ ' m3 = '+m3)
			m3 =2
		}
	}
	if (mts < 0)
	{

		//Вотрая кнопка вверху
		if (id == 'id_u22_div')
		{
			m2 =1
		}
		//Третья кнопка вверху
		if (id == 'id_u23_div')
		{
			m3 =1
		}

	}
}

function move_btn (id)
{
	end = 'stop'
	//alert ('Функция move_btn (id) запущена. ID = '+id+ ' m2 '+m2+ ' m3 '+m3)
	if (id == 'id_u21_div')
	{
		end = 'stop'
		if (m2==1 && m3==1) //Если все кнопки наверху опускаем 2 и 3 кнопку
		{		
			end = move_obj ('id_u22_div', 95, 5, 'top');	
			end = move_obj ('id_u23_div', 125, 5, 'top');
			end = move_obj ('id_u31_div', 60,5,'height');
		}
		else if (m2==1 && m3==2) //Если 3 опущена опускаем вторую кнопку
		{
			end = move_obj ('id_u22_div', 95, 5, 'top');
			end = move_obj ('id_u23_div', 115, -5, 'top');
			end = move_obj ('id_u31_div', 60,5,'height');
		}
					if (end == 'stop')
			{
				obj = document.getElementById ('id_btn21_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn22_img');
				obj.style.display = 'block';
			}
					obj = document.getElementById ('id_btn27_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn28_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn29_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn210_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn211_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn212_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn23_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn24_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn25_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn26_img');
			obj.style.display = 'none';
	} 
	else if (id == 'id_u22_div')
	{
		end = 'stop'
		obj = document.getElementById ('id_btn21_img');
		obj.style.display = 'none';
		obj = document.getElementById ('id_btn22_img');
		obj.style.display = 'none';
		
		if (m2==1 && m3==1) //Если все кнопки наверху опускаем третью
		{
			end = move_obj ('id_u23_div', 200, 5, 'top');
			end = move_obj ('id_u32_div', 60,5,'height');
		}
		else if (m2==2 && m3==2 ) //Если 2 кнопка внизу поднимаем 2 кнопку
		{

			end = move_obj ('id_u22_div', 35, -5, 'top');
			end = move_obj ('id_u23_div', 200, 5, 'top');
			end = move_obj ('id_u32_div', 60,5,'height');

		}
		if (end == 'stop')
			{
				obj = document.getElementById ('id_btn23_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn24_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn25_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn26_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn27_img');
				obj.style.display = 'none';
				obj = document.getElementById ('id_btn28_img');
				obj.style.display = 'none';
				obj = document.getElementById ('id_btn29_img');
				obj.style.display = 'none';
				obj = document.getElementById ('id_btn210_img');
				obj.style.display = 'none';
				obj = document.getElementById ('id_btn211_img');
				obj.style.display = 'none';
				obj = document.getElementById ('id_btn212_img');
				obj.style.display = 'none';
			}
	} 
		else if (id == 'id_u23_div')
	{
		end = 'stop'

		if (m2==1 && m3==1) //Если все кнопки наверху опускаем третью
		{
			end = 'stop';
		}
		else if (m2==2 && m3==2 ) //Если 2 кнопка внизу поднимаем 2 кнопку
		{
			obj = document.getElementById ('id_btn21_img');
			obj.style.display = 'none';
			obj = document.getElementById ('id_btn22_img');
			obj.style.display = 'none';
			end = move_obj ('id_u22_div', 35, -5, 'top');
			end = move_obj ('id_u23_div', 65, -5, 'top');
			end = move_obj ('id_u33_div', 60,5,'height');
		}
		else if (m2==1 && m3==2 ) //Если 2 кнопка внизу поднимаем 2 кнопку
		{
			end = move_obj ('id_u23_div', 65, -5, 'top');
			end = move_obj ('id_u33_div', 60,5,'height');
		}
		if (end == 'stop')
			{
				obj = document.getElementById ('id_btn27_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn28_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn29_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn210_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn211_img');
				obj.style.display = 'block';
				obj = document.getElementById ('id_btn212_img');
				obj.style.display = 'block';

			}
	} 
	//alert ('На круг. End = '+end)	
	if (end != 'stop')
	{			
		//alert ('Перезапуск функции move_btn (id). ID ='+id)
		window.setTimeout (function() { move_btn (id) }, 6);	
	} else {end = '';/*alert('Обработка кнопки завершена. ID = '+id+' M2 = '+m2+' M3 = '+m3)*/ }


};

Kapitan79 05.11.2013 16:09

Событие onMouseOver вызывает функцию move_btn (id).
В зависимости от ID кнопки и состояния глобальных переменных m2 и m3 (они определяют где находится 2 и 3 кнопка сверху - в верхнем или нижнем положении) запускается функция move_obj (id,mt,mts,p).
Эта функция двигает кнопку с указанным id с шагом mts. Когда координата Top кнопки становится равной mt, управление передаётся функции ch_stat (id,mts), которая меняет статус m2 и m3

Kapitan79 06.11.2013 18:18

Решил проблему.

Глюк возникал из за того что для третьей и первой кнопки существовало одинаковое условие if (m2==1 && m3==2 ).
В результате при быстром движении мышкой третья кнопка не успевала приехать в точку назначения и срабатывала первая кнопка что приводило к некорректным параметрам функции move_obj (id,mt,mts,p).
Например при точке назначения для третьей кнопки TOP 80 px она находилась на 110 пикселе с шагом 5 px - то есть двигалась в противоположном направлении от своей точки назначения. Это приводило к цепочке других ошибок в которых я уже разбираться не стал


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