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 10.09.2012 16:13

хром. на ie у меня нет возможности на линуксе проверить
Вот разметка в сокращенном виде:
<div id="toppanel" tabindex="-1">
	<div id="panel">
		<div class="content_panel clearfix_panel">
			<input type='text' id='fld1' size='10' name='req_username' value=''>
			<input type='password' id='fld2' size='10' name='req_password' value=''>
		</div>
	</div>

	<div class="login_tab">
		<span id="toggle">
			<a id="open" class="open">Открыть панель</a>
			<a id="close" style="display: none;" class="close">Закрыть панель</a>
		</span>
	</div> 
</div>

bes 10.09.2012 16:20

ну в хроме мой пример работает, в IE несколько другое восприятие nextSibling (решаемо)

cyber 10.09.2012 16:24

а ну я понял, попробуйте так
function Focus_and_Blur(opt){
      
      var elem = opt.elem, focusForElem;
        
       var body = document.body;
        
       body.setAttribute('tabindex',-1); 
      
      if (elem.addEventListener){ 
      
      elem.addEventListener('focus' , onFocus,true);
      
      body.addEventListener('focus',onDocumentFocus,true); 
    
      } else {
      
      elem.onfocusin = onFocus;
      body.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)
          }
        }
      
      };

zevilz 10.09.2012 16:54

даже панель просто не открывается

zevilz 10.09.2012 16:58

<!DOCTYPE HTML>
<html>
<head>
<style>
#toppanel {
	position:fixed;
	z-index: 999;
	margin:0px;}
#toppanel a {cursor:pointer;}
#toppanel:focus {outline: none;}
#panel {
	position: relative;
	z-index: 3;
	display: none;}
#toppanel .login_tab {
	position: relative;
	top: 0;
	z-index: 999;}
</style>
</head>
<body>

<div id="toppanel" tabindex="-1">
	<div id="panel">
		<div class="content_panel clearfix_panel">
			<input type='text' id='fld1' size='10' name='req_username' value=''>
			<input type='password' id='fld2' size='10' name='req_password' value=''>
		</div>
	</div>

	<div class="login_tab">
		<span id="toggle">
			<a id="open" class="open">Открыть панель</a>
			<a id="close" style="display: none;" class="close">Закрыть панель</a>
		</span>
	</div> 
</div>

<script>
function Focus_and_Blur(opt){
      
      var elem = opt.elem, focusForElem;
        
       var body = document.body;
        
       body.setAttribute('tabindex',-1); 
      
      if (elem.addEventListener){ 
      
      elem.addEventListener('focus' , onFocus,true);
      
      body.addEventListener('focus',onDocumentFocus,true); 
    
      } else {
      
      elem.onfocusin = onFocus;
      body.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('toppanel'),
        focus:function () {
		$("div#panel").slideDown("slow");
		$("#toggle a").toggle();},
        blur: function () {
		$("div#panel").slideUp("slow");
		$("#toggle a").toggle();},}
      });
</script>
</body>
</html>

cyber 10.09.2012 17:04

хех, а вы функцию вызывать не пробывали?:lol:

zevilz 10.09.2012 17:09

Цитата:

Сообщение от cyber (Сообщение 203980)
хех, а вы функцию вызывать не пробывали?:lol:

Вот так вот:
$(document).ready(function() {...
:)

cyber 10.09.2012 17:10

а в примере выше?

zevilz 10.09.2012 17:33

Отредактировал предыдущий. Не работает. Или я чего забыл?:blink:

cyber 10.09.2012 17:35

короче я понял в чем прикол, когда вернусь с треши покажу, если не засну:)

zevilz 11.09.2012 05:09

Видимо проблема в том, что у меня инпуты находятся в одном контейнере (#panel), кнопки открыть/закрыть - в другом (.login_tab), оба они находятся в #toppanel, в котором при событий $('#toppanel').blur должен закрываться контейнер находящийся в нем (#panel), а не сам #toppanel

cyber 12.09.2012 12:36

zevilz, чет я забыл про вас=)
<!DOCTYPE HTML>
<html>
  <head>
  <style>
    #block {
      width:200px;
      height:200px;
      border:4px solid red;
      display:none;
    
    } 
    
    
    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><br/>    
<a href='#' id='open'>open/close</a>
<br><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:_('#block'),
        focus:function () {
         
          _("#inform").innerHTML = 'focus on '+ this.id;

        },
        blur: function () {
        
         _("#inform").innerHTML = 'blur  '+ this.id;
          _('#block').style.display = 'none';
        }
      });
      
      
      _('#open').onclick = function () {
      
        _('#block').style.display = 'block';
        _('#block').focus();// ставим фокус на блок
        
        return false;
      
      }
    </script>

  </body>
</html>

вот

zevilz 12.09.2012 14:17

Что-то не хочет открываться
<!DOCTYPE HTML>
<html>
<head>
<style>
#toppanel {
	position:fixed;
	z-index: 999;
	margin:0px;}
#toppanel a {cursor:pointer;}
#toppanel:focus {outline: none;}
#panel {
	position: relative;
	z-index: 3;
	display: none;}
#toppanel .login_tab {
	position: relative;
	top: 0;
	z-index: 999;}
</style>
</head>
<body>

<div id="toppanel" tabindex="-1">
	<div id="panel">
		<div class="content_panel clearfix_panel">
			<input type='text' id='fld1' size='10' name='req_username' value=''>
			<input type='password' id='fld2' size='10' name='req_password' value=''>
		</div>
	</div>

	<div class="login_tab">
		<span id="toggle">
			<a id="open" class="open">Открыть панель</a>
			<a id="close" style="display: none;" class="close">Закрыть панель</a>
		</span>
	</div> 
</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:_('#panel'),
        focus:function () {
                 

      //      $("#toggle a").toggle();


        },
        blur: function () {
                   

     //        $("#toggle a").toggle();
$("div#panel").slideUp("slow");
         //  _('#panel').style.display = 'none';
        }
      });
      
      
      _('#open').onclick = function () { $("div#panel").slideDown("slow");
      $("#toggle a").toggle();
        _('#panel').style.display = 'block';
        _('#panel').focus();// ставим фокус на блок
        
        return false;}

      _('#close').onclick = function () { $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
       // _('#panel').style.display = 'none';
      //  _('#panel').blur();// ставим фокус на блок
        
        return false;}
</script>
</body>
</html>

cyber 12.09.2012 14:30

оно и не должно работать, потому что нужно либо копировать полностью с функцией
function _(selector) {//функия для удобства написания примера, копипастить не нужно:)
      
      return document.querySelectorAll(selector)[0];
      
      }

либо ее не использовать

zevilz 12.09.2012 15:30

В посте выше изменил код - не открывается.
На сайте http://yellow-duck.net/ с тем же самым кодом открывается, закрывается. Но по blur не закрывается. Выделяется только один из инпутов. При выделении второго панель закрывается и при этом не работает toggle

cyber 12.09.2012 15:38

если честно то не знаю у вас там такая камасутра получилась из за пери мешки чистого js и jquery..

zevilz 12.09.2012 15:45

Может легче будет мой переделать?
$(document).ready(function() {

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

	// Сворачиваем панель при снятии фокуса
	$("#toppanel").blur(function(){
		$("div#panel").slideUp("slow");
		$("#toggle a").toggle();
	});

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

	// Переключаем кнопки "Войти | Регистрация" на "Закрыть панель" при нажатии кнопки мыши
	$("#toggle a").click(function () {
		$("#toggle a").toggle();
	});		
		
});

а именно в:
// Сворачиваем панель при снятии фокуса
	$("#toppanel").blur(function(){...}

реально засунуть условие что-нибудь типа такого
if ("#toppanel input:focus") {$("div#panel").slideUp("slow");
		$("#toggle a").toggle();}
else {}
?

cyber 12.09.2012 15:48

не, я ненавижу jquery особенно после моего прошлого проекта.
Могу расписать алгоритм как у меня работает а вы уже сами переделаете

zevilz 12.09.2012 15:50

А от чего такая ненависть? можно и как у вас

cyber 12.09.2012 15:58

не знаю просто не люблю я jquery.
Алгоритм:
-ставим событие focus(у меня стоит focus для норм браузеров и focusin для тех которые не поддерживают addEventListener) на element и на body
-при получение фокуса элементом , переменная focusForElem ставится в true
-при получение фокуса на body проверяется focusForElem если true то значить фокус ушел с element

zevilz 17.09.2012 11:03

Принцип понял, но не понял как сделать. Переделал свой скрипт:
$(document).ready(function() {

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

      // Сворачиваем панель при снятии фокуса с #toppanel
  $("#toppanel").blur(function(){
    $("*").not("#panel input").focus(function(){
      $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
    });
  });

      // Сворачиваем панель при снятии фокуса с input
  $("#toppanel input").blur(function(){
    $("*").not("#panel input").focus(function(){
      $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
    });
  });

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

});

Сдесь добавил следующее:
1.При снятии фокуса с панели панель сворачивается. Но только если фокус получает не input на этой панели. На панели 4 инпута: для логина, пароля, чекбокс и submit.
2. При снятии фокуса с любого инпута панель сворачивается. Но если фокус получает не другой инпут на этой панели.

При снятии фокуса с панели она закрывается нормально, кнопка закрытия меняет свое содержимое. Но при повторном открытии при первом и втором клике выполняется только $("#toggle a").toggle();. И только при третьем клике панель открывается. То же самое происходит и при снятии фокуса с инпутов. И заметил еще косяк: если после фокуса на инпутах кликнуть на чекбокс, то панель закроется, а если наоборот, то панель не закроется.

Может кто вкурсе, почему происходит такая хрень и как исправить?

devote 17.09.2012 12:47

Цитата:

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

в ИЕ6-7 вдруг внезапно появился Selectors API ???

Цитата:

Сообщение от cyber
return document.querySelectorAll(selector)[0];

интересный способ, а что одиночный селектор отменили?
return document.querySelector(selector);

cyber 17.09.2012 13:30

Цитата:

Сообщение от devote (Сообщение 205114)
в ИЕ6-7 вдруг внезапно появился Selectors API ???


интересный способ, а что одиночный селектор отменили?
return document.querySelector(selector);

что бы не писать каждый раз getElementById(), ClassName я просто (для себя сделал функцию)
и этот коммент там не зря!
Цитата:

//функия для удобства написания примера, копипастить не нужно:)

cyber 17.09.2012 13:34

Цитата:

Сообщение от zevilz (Сообщение 205095)
Принцип понял, но не понял как сделать. Переделал свой скрипт:
$(document).ready(function() {

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

      // Сворачиваем панель при снятии фокуса с #toppanel
  $("#toppanel").blur(function(){
    $("*").not("#panel input").focus(function(){
      $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
    });
  });

      // Сворачиваем панель при снятии фокуса с input
  $("#toppanel input").blur(function(){
    $("*").not("#panel input").focus(function(){
      $("div#panel").slideUp("slow");
      $("#toggle a").toggle();
    });
  });

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

});

Сдесь добавил следующее:
1.При снятии фокуса с панели панель сворачивается. Но только если фокус получает не input на этой панели. На панели 4 инпута: для логина, пароля, чекбокс и submit.
2. При снятии фокуса с любого инпута панель сворачивается. Но если фокус получает не другой инпут на этой панели.

При снятии фокуса с панели она закрывается нормально, кнопка закрытия меняет свое содержимое. Но при повторном открытии при первом и втором клике выполняется только $("#toggle a").toggle();. И только при третьем клике панель открывается. То же самое происходит и при снятии фокуса с инпутов. И заметил еще косяк: если после фокуса на инпутах кликнуть на чекбокс, то панель закроется, а если наоборот, то панель не закроется.

Может кто вкурсе, почему происходит такая хрень и как исправить?

этот код поломается, если на панель добавить textarea или кнопку button и вы его забудете добавить...
Короче решение хреновое плохое

zevilz 17.09.2012 14:07

я ничего там переделывать не буду. Заново не хочется скрипт писать. А мой работает, но с небольшими косяками. Мне всего лишь надо как то их исправить

cyber 17.09.2012 14:20

я сказал, а вы как хотите (мне все равно!)

zevilz 18.09.2012 06:15

Если следующее в консоли
$("a#open:visible");

выдает пустой результат
[]
, то как это прописать в условии вместо звездочек:
if ("a#open:visible" == ***) {}
?
"", "[]", null, false не срабатывают

devote 18.09.2012 06:26

if ( $("a#open:visible").length === 0 ) {}

zevilz 18.09.2012 17:41

Цитата:

Сообщение от devote (Сообщение 205256)
if ( $("a#open:visible").length === 0 ) {}

Спасибо, как раз именно то, что нужно. Только один знак "=" лишний.

cyber 18.09.2012 17:48

Цитата:

Сообщение от zevilz (Сообщение 205326)
Спасибо, как раз именно то, что нужно. Только один знак "=" лишний.

Нет не лишний

bes 18.09.2012 17:53

Цитата:

Сообщение от cyber
Нет не лишний

:lol: язык надо было ещё показать :p

UPD:

var str = '0';
alert((str == 0) + '; ' + (str === 0));

разницу в алгоритмах см. в спецификации п. 11.9.1- 11.9.6
http://es5.javascript.ru/x11.html#x11.9.3
http://es5.javascript.ru/x11.html#x11.9.6

UPD:cyber, typeof($("a#open:visible").length) покажет правду

cyber 18.09.2012 18:28

Цитата:

Сообщение от bes (Сообщение 205329)
:lol: язык надо было ещё показать :p

:p

zevilz 18.09.2012 20:05

у меня и 2 и 3 нормально работают:)

zevilz 18.09.2012 20:35

<!DOCTYPE HTML>
<html>
<head>
<style>
body, #main_wrap {width:100%; margin:0; height:200px; border:1px solid grey;}
#toppanel {
        width:100%;
	position:fixed;
	z-index: 999;
	margin:0px;}
#toppanel a {cursor:pointer;}
#toppanel:focus {outline: none;}
#panel {
        height:50px;
        padding:10px;
        background-color:#ddd;
	position: relative;
	z-index: 3;
	display: none;}
#toppanel .login_tab {
	position: relative;
	top: 0;
	z-index: 999;}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
</head>
<body>

<div id="toppanel">
	<div id="panel">
		<div class="content_panel clearfix_panel">
			<input type='text' id='fld1' size='10' name='req_username' value=''>
			<input type='password' id='fld2' size='10' name='req_password' value=''>
		</div>
	</div>

	<div class="login_tab">
		<span id="toggle">
			<a id="open" class="open">Открыть панель</a>
			<a id="close" style="display: none;" class="close">Закрыть панель</a>
		</span>
	</div> 
</div>
<div id="main_wrap"><p style="font-size:100px; margin:0; text-align:center;">Контент</p></div>
<script>
$(document).ready(function() {

	// Сворачиваем панель
	$("#close").click(function(){
		$("div#panel").slideUp("slow");
		$("#toggle a").toggle();
	});		
        // Сворачиваем при клике на области вне панели
	$("#main_wrap").click(function(){
		if ($("a#open:visible").length === 0) {
			$("div#panel").slideUp("slow");
			$("#toggle a").toggle();
		}
	});

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


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