Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 02.02.2014, 03:34
Аспирант
Отправить личное сообщение для Boolean_Type Посмотреть профиль Найти все сообщения от Boolean_Type
 
Регистрация: 02.02.2014
Сообщений: 48

События / таймеры
Здравствуйте!
Задача: необходимо, чтобы при нажатии на кнопку меню плавно из-под неё выезжало. При повторном нажатии или нажатии НЕ на неё - так же плавно "въезжало" в неё. jQuery по опр. причинам не подходит.
Код ещё не доработан, в нём много шлака, строго его не судите:
<head>
<title> </title>
<meta charset='utf-8'>
<style>
	html, body{
		height:100%;
		margin:0;
		padding:0;
	}
	#right_menu, li{
		margin:0;
		padding:0;
		display:block;
	}
	#right_menu{
		position:absolute;
		width:65px;
		height:125px;
		background-color:#cccccc;
		border:2px solid;
		border-color: #dddddd #bbbbbb #bbbbbb #dddddd;
		padding-left:50px;
	}
	li{
		width:60px;
		height:25px;
		margin:5px;
		line-height:25px;
		font-family:arial, sans-serif;
		font-size:10pt;
		text-indent:5px;
	}
	li:hover{
		background-color:navy;
		color:white;
	}
	#b{
	position:absolute;
	top:50px;
	left:10px;
	}
	
</style>
</head>

<body>
<ul id='right_menu'>
	<li>Effect 1</li>
	<li>Effect 2</li>
	<li>Effect 3</li>
	<li>Effect 4</li>
</ul>
<input type='button' id='b' value = 'Click'>

var flag = false;

var menu=document.getElementById('right_menu');
//меню скрыто при загрузке стр-цы
menu.style.display='none';

var button = document.getElementById('b');

button.onclick=function(event){
//меню будет появл-ся там, где щёлкнули правой кнопкой
menu.style.left=parseInt(getComputedStyle(button).left)+'px';
menu.style.top=parseInt(getComputedStyle(button).top)+'px';

	
	if(flag == false){
		menu.style.display='block';
		intr_show=setInterval(show,1);
		flag = true;
	}else{
		intr_hide=setInterval(hide,1);
		document.body.onclick = setInterval(hide,1); //какой-то бред написан, но и без этой строки работает по-другому
		flag=false;
	}
}

function show(){
//показываем UL
width = parseInt(getComputedStyle(menu).width);
height = parseInt(getComputedStyle(menu).height);
if(width >= 65 && height >= 125) {return}
menu.style.width = (width + 1)+'px';
menu.style.height = (height + 1)+'px';

//показываем LI
var lis = document.querySelectorAll('li');
for(var i=0; i<lis.length;i++){
widthLi = parseInt(getComputedStyle(lis[i]).width);
heightLi = parseInt(getComputedStyle(lis[i]).height);
if (widthLi == 60 && heightLi ==25) {	
	lis[0].innerHTML = 'Effect 1';
	lis[1].innerHTML = 'Effect 2';
	lis[2].innerHTML = 'Effect 3';
	lis[3].innerHTML = 'Effect 4';
return} //чтобы ф-ция не вып-яла лишних действий
	
lis[i].style.width = (widthLi + 1)+'px';
lis[i].style.height = (heightLi + 1)+'px';
}
}
	

function hide(){
//прячем UL
widthUl = parseInt(getComputedStyle(menu).width); /*не обязат-но
глобальная, т.к. перезапись происх-ит в св-ве: menu.style.width,
а width получаем из него же*/
heightUl = parseInt(getComputedStyle(menu).height);
if (widthUl <= 0 && heightUl <=0) {
menu.style.border = 'none';
return} //чтобы ф-ция не вып-яла лишних действий
menu.style.width = (widthUl - 1)+'px';
menu.style.height = (heightUl - 1)+'px';

//прячем LI
var lis = document.querySelectorAll('li');
for(var i=0; i<lis.length;i++){
widthLi = parseInt(getComputedStyle(lis[i]).width);
heightLi = parseInt(getComputedStyle(lis[i]).height);
if (widthLi == 0 && heightLi ==0) {
/*lis[i].innerHTML = '';  не корректно, т.к. if сработает сначала для
i=0, но после "обнуления" innerHTML стоит return, кот-ый выкинет из
ф-ции. При след-ем её запуске цикл опять начнётся с 0 и return опять
выкинет после lis[0].innerHTML = ''; . Выходит, что innerHTML обнулится
лишь у 1го эл-та*/
	for(var j=0; j<lis.length;j++){
	lis[j].innerHTML = '';
	}
return} //чтобы ф-ция не вып-яла лишних действий

lis[i].style.width = (widthLi - 1)+'px';
lis[i].style.height = (heightLi - 1)+'px';
console.log(getComputedStyle(lis[i]).width)
}
}


Ф-ция show не работает, а hide срабатывает, но некорректно.
Сказать по правде, я пока слаб в событиях и таймерах, а задание срочное. Поэтому даже не знаю, что тут можно сделать.

Последний раз редактировалось Boolean_Type, 02.02.2014 в 16:14.
Ответить с цитированием
  #2 (permalink)  
Старый 02.02.2014, 10:29
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,118

Сообщение от Boolean_Type
задание срочное. Поэтому даже не знаю, что тут можно сделать
Как вариант, предложить оплату, может кого-то это заинтересует...
Ответить с цитированием
  #3 (permalink)  
Старый 02.02.2014, 10:51
Профессор
Отправить личное сообщение для kostyanet Посмотреть профиль Найти все сообщения от kostyanet
 
Регистрация: 23.10.2010
Сообщений: 2,718

http://candpgeneration.com/toys/CSS3-dropdown-tut.php

без js
Ответить с цитированием
  #4 (permalink)  
Старый 02.02.2014, 15:47
Аспирант
Отправить личное сообщение для Boolean_Type Посмотреть профиль Найти все сообщения от Boolean_Type
 
Регистрация: 02.02.2014
Сообщений: 48

Сообщение от ksa Посмотреть сообщение
Как вариант, предложить оплату, может кого-то это заинтересует...
:-)))
Полностью согласен)))
Да только это не от заказчика, а на курсах задали.
Ответить с цитированием
  #5 (permalink)  
Старый 02.02.2014, 15:50
Аспирант
Отправить личное сообщение для Boolean_Type Посмотреть профиль Найти все сообщения от Boolean_Type
 
Регистрация: 02.02.2014
Сообщений: 48

Сообщение от kostyanet Посмотреть сообщение
http://candpgeneration.com/toys/CSS3-dropdown-tut.php

без js
Спасибо большое, со св-вом CSS transition знаком, но нужно именно JS.

Мне кажется, мой алгоритм в общем верен, просто из-за нехватки теор. знаний я где-то лажаю...
Ответить с цитированием
  #6 (permalink)  
Старый 02.02.2014, 18:01
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Boolean_Type,
Вариант на основе темы Дёрганье при смене анимации
<!DOCTYPE HTML>

<html>

<head>

<title> </title>
<meta charset='utf-8'>
<style>
	html, body{
		height:100%;
		margin:0;
		padding:0;
	}
	#right_menu, li{
		margin:0;
		padding:0;
		display:block;
	}
	#right_menu{
        overflow: hidden;
		width:70px;
		height:125px;
		background-color:#cccccc;
		border:2px solid;
		border-color: #dddddd #bbbbbb #bbbbbb #dddddd;
		padding-left:50px;
	}
	li{
		width:65px;

		margin:5px;

		font-family:arial, sans-serif;
		font-size:10pt;
		text-indent:5px;
	}
	li:hover{
		background-color:navy;
		color:white;
	}
	#b{
	top:50px;
	left:10px;
	}

</style>
<script>
   function animate(opts) {
  clearInterval(opts.el.timer);
  var start = new Date;
  var delta = opts.delta || linear;
  var height = parseFloat(opts.el.style.height);
  opts.el.timer = setInterval(function() {
    var progress = (new Date - start) / opts.duration;

    if (progress > 1) progress = 1;

    opts.step( delta(progress),height );

    if (progress == 1) {
      clearInterval(opts.el.timer);
      opts.complete && opts.complete();
    }
  }, opts.delay || 20);


}
function elastic(progress) {
  return Math.pow(2, 10 * (progress-1)) * Math.cos(20*Math.PI*1.5/3*progress)
}
function linear(progress) {
  return progress
}
function quad(progress) {
  return Math.pow(progress, 2)
}

function quint(progress) {
  return Math.pow(progress, 5)
}
function makeEaseInOut(delta) {
  return function(progress) {
    if (progress < .5)
      return delta(2*progress) / 2
    else
      return (2 - delta(2*(1-progress))) / 2
  }
}
function makeEaseOut(delta) {
  return function(progress) {
    return 1 - delta(1 - progress)
  }
}

window.onload = function() {
var input = document.getElementById("b");
var menu = document.getElementById("right_menu");
var body =  document.body;
var n = 0;
				input.onclick = function(){
				    n ^= 1;
                    var to = n ? 0 : 125,
                        display = n ? "none" : "block";
                     !n &&   (menu.style.display = display)
					animate({
					    el : menu,
						duration: 1000,
						delta: makeEaseInOut(linear),
						step: function(delta,height) {
							menu.style.height = delta*(to-height)+height+"px";
						},
                        complete :  function() {menu.style.display = display}
					})

				};

               body.onclick = function(event){
                 var event = event || window.event;
                 var target = event.target || event.srcElement;
                 if(target!=input && target!=menu &&!n && target.tagName != 'LI') input.onclick()

               }
}

</script>
</head>

<body>
<input type='button' id='b' value = 'Click'>
<ul id='right_menu' style="height: 125px">
	<li>Effect 1</li>
	<li>Effect 2</li>
	<li>Effect 3</li>
	<li>Effect 4</li>
</ul>

</body>

</html>
Ответить с цитированием
  #7 (permalink)  
Старый 02.02.2014, 20:39
Аватар для ksa
ksa ksa вне форума
CacheVar
Отправить личное сообщение для ksa Посмотреть профиль Найти все сообщения от ksa
 
Регистрация: 19.08.2010
Сообщений: 14,118

Сообщение от Boolean_Type Посмотреть сообщение
это не от заказчика, а на курсах задали.
Какая разница чьи деньги?
Главное чтобы они кого-от заинтересовали...
Ответить с цитированием
  #8 (permalink)  
Старый 03.02.2014, 15:51
Аспирант
Отправить личное сообщение для Boolean_Type Посмотреть профиль Найти все сообщения от Boolean_Type
 
Регистрация: 02.02.2014
Сообщений: 48

Сообщение от рони
Вариант на основе темы
Рони, спасибо большое! В изучении пока не дошёл до анимации, поэтому пока не всё понятно в Вашем коде, но, как только дойду, обязательно подробно изучу каждую строку.
Кстати, пусть оффтоп, но: уже неоднократно на форуме сталкиваюсь в разл. темах с Вашими комментариями - и всегда с удовольствием их читаю. Честно, Вы круты!)
Насчёт задачи - кое-что таки наклепал сам:
<!DOCTYPE html>
<html>
<head>  
<meta charset=utf-8>
<title>JS Bin</title>
  <style>
 html, body{
		height:100%;
		margin:0;
		padding:0;
	}
	#right_menu, li{
		margin:0;
		padding:0;
		display:block;
	}
	#right_menu{
		position:absolute;
		width:65px;
		height:125px;
		background-color:#cccccc;
		border:2px solid;
		border-color: #dddddd #bbbbbb #bbbbbb #dddddd;
		padding-left:50px;
	}
	li{
		width:60px;
		height:25px;
		margin:5px;
		line-height:25px;
		font-family:arial, sans-serif;
		font-size:10pt;
		text-indent:5px;
	}
	li:hover{
		background-color:navy;
		color:white;
	}
	#b{
	position:absolute;
	left:10px;
	}
	  
  </style>
</head>
<body>
<ul id='right_menu'>
	<li></li>
	<li></li>
	<li></li>
	<li></li>
</ul>
<input type='button' id='b' value = 'Click'>
  
<script>
//запишем ссылку на объект-кнопку в перем-ую
var button = document.getElementById('b');

//получим контейнер UL в перем-ую
var menu=document.getElementById('right_menu');
//меню скрыто при загрузке стр-цы
menu.style.display='none';
//расположим кнопку справа-вверху от меню (позиционируем меню)
if(window.getComputedStyle){
	menu.style.left=parseInt(getComputedStyle(button).left)+'px';
	menu.style.top=parseInt(getComputedStyle(button).top)+'px';
}else{ //для IE8
	menu.style.left=parseInt(button.currentStyle.left)+'px';
	menu.style.top=parseInt(button.currentStyle.top)+'px';
}

var flag = false;

//ф-ция отображ-я меню
function show(){
    menu.style.display='block';
	
    //при выезжании меню текста нет
    var lis = document.querySelectorAll('li');
    for(var i=0; i<lis.length;i++){	
		lis[i].innerHTML = '';
	} 
	
	//ширина и высота меню
	var width = 0;
	var height = 0;
	
	return function frame_show() { // функция для отрисовки
		width++;
		height += 2; 
		menu.style.width = width + 'px';
		menu.style.height = height + 'px';
		
		if (width == 65) {
			clearInterval(timer_show); // завершить анимацию
			  
			//отразить текст в "гот." меню
			setTimeout(function(){
				var lis = document.querySelectorAll('li');    
				lis[0].innerHTML = 'Effect 1';
				lis[1].innerHTML = 'Effect 2';
				lis[2].innerHTML = 'Effect 3';
				lis[3].innerHTML = 'Effect 4';
			},50);
		}
	}
}

//ф-ция сокрытия меню 
function hide(){
	
    //при въезжании меню текста нет (чтоб не "маячил")
    var lis = document.querySelectorAll('li');
    for(var i=0; i<lis.length;i++){	
		lis[i].innerHTML = '';
	}
	
    if(window.getComputedStyle){
           var width = parseInt(getComputedStyle(menu).width);
           var height = parseInt(getComputedStyle(menu).height);
    }else{ //для IE8
	width = parseInt(menu.currentStyle.width);
           height = parseInt(menu.currentStyle.height);
    }

	return function frame_hide() { // функция для отрисовки 
		width--;
		height -= 2;
		menu.style.width = width + 'px';
		menu.style.height = height + 'px';
		
		if (height == 0) {
			clearInterval(timer_hide); // завершить анимацию
			
			//тут же скрыть меню полностью
			setTimeout(function(){
				menu.style.display='none';
			},60);
		}
	}
}

//переключать режим видимости контейнера (кликом по кнопке)
button.onclick=function(event){ 
	if(flag == false){
	timer_show = setInterval(show(),1);
	flag = true;
	}else{
	timer_hide=setInterval(hide(),1);
	flag=false; 
	}       
}

//скрыть контейнер при наж-ии вне кнопки     
button.onblur=function(event){
	timer_hide=setInterval(hide(),1);       
	flag=false;
}

</script>
</body>
</html>

Последний раз редактировалось Boolean_Type, 03.02.2014 в 17:56.
Ответить с цитированием
  #9 (permalink)  
Старый 03.02.2014, 16:21
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Сообщение от Boolean_Type
При отладке выдаёт ошибку в строках 066,067
Цитата:
метод window.getComputedStyle ... Поддерживается всеми браузерами, кроме IE<9.
getComputedStyle и currentStyle
Ответить с цитированием
  #10 (permalink)  
Старый 03.02.2014, 16:47
Аспирант
Отправить личное сообщение для Boolean_Type Посмотреть профиль Найти все сообщения от Boolean_Type
 
Регистрация: 02.02.2014
Сообщений: 48

Сообщение от рони Посмотреть сообщение
getComputedStyle и currentStyle
Да-да, уже исправил код в предыд. сообщении, думал, успею до того, как Вы увидите.)) Спасибо)

Я новичок, поэтому не знаю: как Вы сделали здесь код запускаемым?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание глобального события kez jQuery 1 17.09.2012 11:49
Дебаг js, или как найти обработчик события для тега jimm88 Events/DOM/Window 1 18.04.2012 15:11
Как сделать чтобы клавиатурные события пропускались сквозь флешку? khusamov Общие вопросы Javascript 3 11.02.2012 16:48
Передача параметров в колбэки и дальнейшее их вешанье на события. Gremlin Общие вопросы Javascript 17 13.08.2011 08:54
Явный вызов процедуры обработки события. supchik Общие вопросы Javascript 18 27.01.2009 13:16