Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Проблема с панелью пользователя (https://javascript.ru/forum/events/31461-problema-s-panelyu-polzovatelya.html)

zevilz 08.09.2012 17:08

Проблема с панелью пользователя
 
Есть панель пользователя наверху страницы.
<div id="toppanel">
	<div id="panel"></div>
	<div class="login_tab">
             <span id="toggle">
	         <a id="open" class="open" href="#">Открыть</a>
	         <a id="close" style="display: none;" class="close" href="#">Закрыть</a>			
             </span>
        </div>
</div>

По умолчанию она скрыта на login_tab висит кнопка "открыть", при нажатии на нее панель открывается, кнопка открыть меняется на "закрыть". Выполняется это при помощи скрипта:

$(document).ready(function() {

	// Сворачиваем панель
	$("#close").click(function(){
		$("div#panel").slideUp("slow");	
	});		

	// Разворачиваем панель
	$("#open").click(function(){
		$("div#panel").slideDown("slow");
	
	});

	// Переключение кнопок при нажатии кнопки мыши
	$("#toggle a").click(function () {
		$("#toggle a").toggle();
	});		
		
});

Хочу реализовать закрытие панели при нажатии на любой области страницы кроме области панели. Никак не получается написать работоспособный код.
Попробовал написать так:
$("div#body").click(function(){
      $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
});

Вроде работает, но только при клике на блоке #body
$("body").not("a#open").click(function(){
      $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
});

Открывается и сразу закрывается
$("a").not("a#open").click(function(){
      $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
});

Нормально открывается, но при попытке подставить еще условия отрывается и закрывается либо вообще не открывается.
Как правильно составить код? Заранее спасибо за ответы

cyber 08.09.2012 18:06

используйте события focus /blur

zevilz 08.09.2012 19:12

Не работает. Где косяк?
$("#toppanel").blur(function(){
	$("div#panel").slideUp("slow");
	$("#toggle a").toggle();
});

bes 08.09.2012 19:27

tabindex

zevilz 08.09.2012 19:34

всмысле? это то мне зачем?

bes 08.09.2012 19:37

чтобы div смог получать фокус, тогда и onblur будет

zevilz 08.09.2012 19:49

Спасибо, работает) Только вот рамка появилась при фокусе

bes 08.09.2012 19:53

outline-style: none

zevilz 08.09.2012 19:55

Рамку убрал, но сейчас если клавишей tab перемещаться по элементам кнопка "открыть" меняется на "закрыть"

cyber 08.09.2012 20:00

есть такая штука, поставьте tabindex = -1

zevilz 09.09.2012 17:40

Цитата:

Сообщение от cyber (Сообщение 203684)
есть такая штука, поставьте tabindex = -1

Спасибо, работает)

zevilz 09.09.2012 17:52

Есть еще такой вопрос. Панель у меня фиксирована к верху экрана(position:fixed). Если я нахожусь, например, в центре страницы, то при закрытии/открытии панели автоматом идет перемещение к верху страницы. Реально ли сделать открытие/закрытие панели без перемещения к верху страницы?
И, кстати, сейчас при клике на любом месте страницы не происходит перемещения наверх, только при нажатии на кнопку "открыть"/"закрыть"

cyber 09.09.2012 18:04

желательно страницу с примером сделать ...

zevilz 09.09.2012 18:08

Много печатать)
http://yellow-duck.net/ (сайт на тестировании, доступ открыт на время)

cyber 09.09.2012 18:20

по пробуйте вместо ссылок использовать div к примеру

bes 09.09.2012 18:38

либо отменить действие ссылки по умолчанию (return false)

zevilz 09.09.2012 18:42

Цитата:

Сообщение от cyber (Сообщение 203804)
по пробуйте вместо ссылок использовать div к примеру

Не срабатывает переключение дивов. Открывается нормально без перехода в начало. Но не закрывается, т.к. остается кнопка "открыть"
$("#toggle div").click(function () {
		$("#toggle div").toggle();
	});

zevilz 09.09.2012 18:43

Цитата:

Сообщение от bes (Сообщение 203810)
либо отменить действие ссылки по умолчанию (return false)

А можно подробнее как это сделать?

bes 09.09.2012 18:50

<a href="#" style="position: fixed; left: 0px; top: 0px">link</a>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<script>
document.body.children[0].onclick = function () {
	alert('ha');//сначала код
	return false;
}
</script>

cyber 09.09.2012 18:52

Цитата:

Сообщение от bes (Сообщение 203814)
<a href="#" style="position: fixed; left: 0px; top: 0px">link</a>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<script>
document.body.children[0].onclick = function () {
	alert('ha');//сначала код
	return false;
}
</script>

но либо так, но для этого нужно лезть в код=)

bes 09.09.2012 18:55

Цитата:

Сообщение от cyber
но либо так, но для этого нужно лезть в код=)

переделывая div под ссылку, тоже нужно лезть в код :)

zevilz 09.09.2012 19:14

Сделал по другому.
Вернул весь код в прежнее состояние, удалил
href="#"
у ссылок в коде. Сейчас все работает отлично:) Всем большое спасибо за помощь

zevilz 09.09.2012 20:25

Блин, опять косяк нашел. На панели есть форма входа. При фокусе на инпутах закрывается панель

cyber 09.09.2012 21:28

Цитата:

Сообщение от bes (Сообщение 203818)
переделывая div под ссылку, тоже нужно лезть в код :)

ну так в хтмл проще=)

bes 09.09.2012 21:35

Цитата:

Сообщение от cyber
ну так в хтмл проще=)

исправить html, css + js, когда обращение идёт по имени тега

cyber 09.09.2012 22:47

как то так
UP подправил код
<!DOCTYPE HTML>
<html>
  <head>
  <style>
    #block {
      width:200px;
      height:200px;
      border:4px solid red;
    
    
    } 
    body {
    
      border:2px solid black;
    
    
    }
    
    </style>
  </head>
  <body tabindex='-1'>
    
    <div tabindex='-1' id='block'>
      wereasrwer
    <input type='text'>
      <div>
       <input type='text'> 
      </div>
    </div>
    
    <div id='inform'></div>
    <script>
      function _(selector) {//функия для удобства написания примера, копипастить не нужно:)
      
      return document.querySelectorAll(selector)[0];
      
      }
      
      !function (){
      
      var elem = _("#block"), focusForElem;
      
      if (elem.addEventListener){ 
      
      elem.addEventListener('focus' , onFocus,true);
      
      document.addEventListener('focus',onDocumentFocus,true); 
    
      } else {
      
      elem.onfocusin = onFocus;
      document.onfocusin = onDocumentFocus;
    
      }
      
      function onFocus(e) {
      
       _("#inform").innerHTML = 'focus on '+ this.id;
        
        
        focusForElem = true;
        event.cancelBubble = true;
      }
      
        function onDocumentFocus () {
        
          if (focusForElem) {
            focusForElem = false;
            onBlur();
          }
        }
      function onBlur() {
      
      
      _("#inform").innerHTML = 'focus on '+ this;
      
      }
      }();
    </script>

  </body>
</html>

Работает в ие 6+ без функции _() (должно ,не пробывал), в ие8+ точно работает

П.с более гуманного решение не придумал, но может оно и есть так как код писал после того как проснулся=)

zevilz 10.09.2012 03:04

а как насчет инпутов, которые находятся внутри панели. Можно ли сделать условие, если берет на себя фокус любой из инпутов панели, то закрытие панели по blur не происходит, а если теряет фокус один из инпутов панели, то панель приобретает фокус для нормального закрытия панели по blur? Пробовал через if() написать выполнение функции закрытия панели по blur, но не могу сформулировать условие 'если берет фокус тег input панели #toppanel, то...'. Пробовал через $('#toppanel').not('#toppanel input').blur() - тоже ничего не выходит. Либо панель не открывается либо панель закрывается при фокусе на любом из инпутов панели

cyber 10.09.2012 09:37

Цитата:

Сообщение от zevilz (Сообщение 203904)
а как насчет инпутов, которые находятся внутри панели. Можно ли сделать условие, если берет на себя фокус любой из инпутов панели, то закрытие панели по blur не происходит, а если теряет фокус один из инпутов панели, то панель приобретает фокус для нормального закрытия панели по blur? Пробовал через if() написать выполнение функции закрытия панели по blur, но не могу сформулировать условие 'если берет фокус тег input панели #toppanel, то...'. Пробовал через $('#toppanel').not('#toppanel input').blur() - тоже ничего не выходит. Либо панель не открывается либо панель закрывается при фокусе на любом из инпутов панели

можно , но не нужно .
если не нужна поддержка ИЕ меньше 9 , то кож можно сократить;)

zevilz 10.09.2012 11:38

так в вышенаписанном коде панель не будет сворачиваться при фокусе на инпуте? Я правильно понял? Я просто нифига не понял в этом коде. Разбираюсь еще с js:-)

cyber 10.09.2012 12:46

сделал просто интерфейс, думаю комментарии не нужны
<!DOCTYPE HTML>
<html>
  <head>
  <style>
    #block {
      width:200px;
      height:200px;
      border:4px solid red;
    
    
    } 
    body {
    
      border:2px solid black;
    
    
    }
    
    </style>
  </head>
  <body tabindex='-1'>
    
    <div tabindex='-1' id='block'>
      wereasrwer
    <input type='text'>
      <div>
       <input type='text'> 
      </div>
    </div>
    
 <div id='inform'></div>

    <script>
      function _(selector) {//функия для удобства написания примера, копипастить не нужно:)
      
      return document.querySelectorAll(selector)[0];
      
      }
      
      function Focus_and_Blur(opt){
      
      var elem = opt.elem, focusForElem;
      
      if (elem.addEventListener){ 
      
      elem.addEventListener('focus' , onFocus,true);
      
      document.addEventListener('focus',onDocumentFocus,true); 
    
      } else {
      
      elem.onfocusin = onFocus;
      document.onfocusin = onDocumentFocus;
    
      }
      
      function onFocus(e) {
      
        focusForElem = true;
        event.cancelBubble = true;
        opt.focus.call(this,e);
      }
      
        function onDocumentFocus (e) {
        
          if (focusForElem) {
            focusForElem = false;
            opt.blur.call(elem,e)
          }
        }
      
      };
      
  //пример вызова,  в саму функцию лучше не лезть     
      Focus_and_Blur({
        elem:document.getElementById('block'),
        focus:function () {
         
          _("#inform").innerHTML = 'focus on '+ this.id;

        },
        blur: function () {
        
         _("#inform").innerHTML = 'blur  '+ this.id;
        }
      });
    </script>

  </body>
</html>

cyber 10.09.2012 12:56

а да забыл

Focus_and_Blur({
        elem:document.getElementById('block'),
        focus:function (e) {
          //this == elem
          //e - обьект события
          _("#inform").innerHTML = 'focus on '+ this.id;

        },
        blur: function (e) {
         //this == elem
          //e - обьект события
         _("#inform").innerHTML = 'blur  '+ this.id;
        }
      });

комменты=)

bes 10.09.2012 13:04

<div id="div" style="position: fixed; top: 10px; left: 5px; outline-style: none; z-index: 100">
	<a href="#">open</a>
	<div style="display: none">
		<input><br>
		<input>
	</div>
</div>
<div></div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

<script>
window.onload = function () {
	var div = document.getElementById('div');
	
	div.onclick = function (e)  {
		e = e || event;
		var target = e.target || e.srcElement;
		if (target == this.children[0]) {
			var next = target.nextSibling.nextSibling; 
			if (next.style.display != 'block') {
				next.style.display = 'block';
				target.innerHTML = 'close';
				div.nextSibling.nextSibling.style.cssText = 'position: fixed; left: 0px; top: 0px; height: 100%; width: 100%; z-index: 99';
			} else {
				next.style.display = 'none';
				target.innerHTML = 'open';
				div.nextSibling.nextSibling.style.cssText = '';
			}
		}
	}
	
	div.nextSibling.nextSibling.onclick = function () {
		div.children[1].style.display = 'none';
		div.children[0].innerHTML = 'open';
		this.style.cssText = '';
	}
	
	
	
}
</script>

cyber 10.09.2012 13:16

bes,снала сделай фокус на инпут в блоке , а потом табом переключай
у меня сработает blur
<!DOCTYPE HTML>
<html>
  <head>
  <style>
    #block {
      width:200px;
      height:200px;
      border:4px solid red;
    
    
    } 
    body {
    
      border:2px solid black;
    
    
    }
    
    </style>
  </head>
  <body tabindex='-1'>
    
    <div tabindex='-1' id='block'>
      wereasrwer
    <input type='text'>
      <div>
       <input type='text'> 
      </div>
    </div>
    
 <div id='inform'></div>
<input type='text'>
    <script>
      function _(selector) {//функия для удобства написания примера, копипастить не нужно:)
      
      return document.querySelectorAll(selector)[0];
      
      }
      
      function Focus_and_Blur(opt){
      
      var elem = opt.elem, focusForElem;
      
      if (elem.addEventListener){ 
      
      elem.addEventListener('focus' , onFocus,true);
      
      document.addEventListener('focus',onDocumentFocus,true); 
    
      } else {
      
      elem.onfocusin = onFocus;
      document.onfocusin = onDocumentFocus;
    
      }
      
      function onFocus(e) {
      
        focusForElem = true;
        event.cancelBubble = true;
        opt.focus.call(this,e);
      }
      
        function onDocumentFocus (e) {
        
          if (focusForElem) {
            focusForElem = false;
            opt.blur.call(elem,e)
          }
        }
      
      };
      
  //пример вызова,  в саму функцию лучше не лезть     
      Focus_and_Blur({
        elem:document.getElementById('block'),
        focus:function () {
         
          _("#inform").innerHTML = 'focus on '+ this.id;

        },
        blur: function () {
        
         _("#inform").innerHTML = 'blur  '+ this.id;
        }
      });
    </script>

  </body>
</html>

а у тебя блок не скроется
<!DOCTYPE HTML>
<html>
  <head> </head>
  <body style='border:1px solid black;'>
    <div>
    <div>
<div id="div" style="position: fixed; top: 10px; left: 5px; outline-style: none; z-index: 100">
	<a href="#">open</a>
	<div style="display: none">
		<input><br>
		<input>
	</div>
</div>
<div></div>
    </div>
    </div> 
    
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
 <input type='text'> 
<script>
window.onload = function () {
	var div = document.getElementById('div');
	
	div.onclick = function (e)  {
		e = e || event;
		var target = e.target || e.srcElement;
		if (target == this.children[0]) {
			var next = target.nextSibling.nextSibling; 
			if (next.style.display != 'block') {
				next.style.display = 'block';
				target.innerHTML = 'close';
				div.nextSibling.nextSibling.style.cssText = 'position: fixed; left: 0px; top: 0px; height: 100%; width: 100%; z-index: 99';
			} else {
				next.style.display = 'none';
				target.innerHTML = 'open';
				div.nextSibling.nextSibling.style.cssText = '';
			}
		}
	}
	
	div.nextSibling.nextSibling.onclick = function () {
		div.children[1].style.display = 'none';
		div.children[0].innerHTML = 'open';
		this.style.cssText = '';
	}
	
	
	
}
</script>
  </body>
</html>

bes 10.09.2012 13:45

Цитата:

Сообщение от cyber
bes,снала сделай фокус на инпут в блоке , а потом табом переключай
у меня сработает blur

а оно надо?

cyber 10.09.2012 13:48

Цитата:

Сообщение от bes (Сообщение 203953)
а оно надо?

а хрен его знает, я просто сказал что может не работать и все ..:)

bes 10.09.2012 13:52

вот так без дополнительного клика
<div id="div" style="position: fixed; top: 10px; left: 5px; z-index: 100">
	<a href="#" onclick="return false">open</a>
	<div style="display: none">
		<input><br>
		<input>
	</div>
</div>
<div></div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<input onclick="alert('input')">

<script>
window.onload = function () {
	var div = document.getElementById('div');
	
	div.onclick = function (e)  {
		e = e || event;
		var target = e.target || e.srcElement;
		if (target == this.children[0]) {
			var next = target.nextSibling.nextSibling; 
			if (next.style.display != 'block') {
				next.style.display = 'block';
				target.innerHTML = 'close';
				div.nextSibling.nextSibling.style.cssText = 'position: fixed; left: 0px; top: 0px; height: 100%; width: 100%; z-index: 99';
			} else {
				next.style.display = 'none';
				target.innerHTML = 'open';
				div.nextSibling.nextSibling.style.cssText = '';
			}
		}
	}
	
	div.nextSibling.nextSibling.onclick = function (e) {
		e = e || event;
		div.children[1].style.display = 'none';
		div.children[0].innerHTML = 'open';
		this.style.cssText = '';
		var elem = document.elementFromPoint(e.clientX, e.clientY);
		elem.focus();
		elem.click();
	}
	
}
</script>

cyber 10.09.2012 13:56

Имхо :с фокусом проще=)

zevilz 10.09.2012 15:59

У меня не работает ни один из примеров. Где-то я похоже косячу:-?

bes 10.09.2012 16:02

браузер IE?

cyber 10.09.2012 16:05

Цитата:

Сообщение от bes (Сообщение 203969)
браузер IE?

моя в ие работает 8+ (точно), 6 + (должна, не пробывал)


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