Возврат в исходное положение при клике на стороннюю область

437
26 января 2017, 04:28

Здравствуйте! Есть два блока - второй появляется при клике на первый и должен исчезать при клике на любую область кроме своей собственное.

Мой скрипт работает некорректно - выпадающий блок появляется и сразу исчезает... Я понимаю, что должна быть определенная последовательность, т.к. обе функции выполняются одновременно, но как её задать не знаю. Просьба помочь

Плюс мне не понятно, почему при клике на блок .header появляющийся блок как-бы моргает. По идее он должен получить opacity: 1, а потом его значение сразу должно измениться на opacity: 0

$(function() { 
  var searchformBlock = $('.menu'); 
 
  $('body').click(function() { 
    if ($(searchformBlock).hasClass('active')) { 
      $(searchformBlock).fadeOut().removeClass('active'); 
    } 
  }) 
 
  $('.header').click(function () { 
    $(searchformBlock).toggleClass('active'); 
 
    if ($(searchformBlock).hasClass('active')) { 
      $(searchformBlock).fadeIn(); 
    } else { 
      $(searchformBlock).fadeOut(); 
    } 
  }); 
});
.header { 
  position: fixed; 
  top: 0; 
  left: 0; 
  right: 0; 
  height: 60px; 
  background-image: -webkit-linear-gradient(top, #fecf5e, #ffcc50); 
  background-image: linear-gradient(to bottom, #fecf5e, #ffcc50); 
  z-index: 101; 
} 
.menu { 
  position: absolute; 
  top: 60px; 
  left: 0; 
  right: 0; 
  width: 300px; 
  background: #a7a7a7; 
  height: 30px; 
  margin: 0 auto; 
  z-index: 100; 
  display: none; 
   
  -moz-transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
  -o-transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
  -webkit-transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
  transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="header"></div> 
<div class="menu"></div>

Answer 1

document.querySelector('.header').addEventListener('click', function () { 
  var menu = document.querySelector('.menu'); 
  var handler; 
   
  if (menu.hidden) { 
    menu.hidden = false; 
     
    menu.addEventListener('click', handler = function (event) { 
      event.stopPropagation(); 
    }, true); 
     
    document.addEventListener('click', function hide(event) { 
      menu.hidden = true; 
      menu.removeEventListener('click', handler, true); 
      document.removeEventListener('click', hide, true); 
    }, true); 
  } 
})
[hidden] { 
  display: none !important; 
} 
 
.header { 
  position: fixed; 
  top: 0; 
  left: 0; 
  right: 0; 
  height: 60px; 
  background-image: -webkit-linear-gradient(top, #fecf5e, #ffcc50); 
  background-image: linear-gradient(to bottom, #fecf5e, #ffcc50); 
  z-index: 101; 
} 
 
.menu { 
  position: absolute; 
  top: 60px; 
  left: 0; 
  right: 0; 
  width: 300px; 
  background: #a7a7a7; 
  height: 30px; 
  margin: 0 auto; 
  z-index: 100; 
   
  animation: opacity-0-to-1 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
} 
 
@keyframes opacity-0-to-1 { 
  from { opacity: 0; } 
  to   { opacity: 1; } 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="header"></div> 
<div class="menu" hidden="hidden"></div>

Answer 2

Ваше событие - клик по .header всплывает до body, из-за чего блок тут же скрывает. Предотвращаем всплытие с помощью e.stopPropagation

$(function() { 
  var searchformBlock = $('.menu'); 
 
  $('body').click(function() { 
    if (searchformBlock.hasClass('active')) { 
      searchformBlock.fadeOut().removeClass('active'); 
    } 
  }) 
 
  $('.header').click(function(e) { 
    e.stopPropagation(); 
    searchformBlock.toggleClass('active'); 
 
    if (searchformBlock.hasClass('active')) { 
      searchformBlock.fadeIn(); 
    } else { 
      searchformBlock.fadeOut(); 
    } 
  }); 
 
  searchformBlock.click(function(e) { 
    e.stopPropagation(); 
  }); 
});
.header { 
  position: fixed; 
  top: 0; 
  left: 0; 
  right: 0; 
  height: 60px; 
  background-image: -webkit-linear-gradient(top, #fecf5e, #ffcc50); 
  background-image: linear-gradient(to bottom, #fecf5e, #ffcc50); 
  z-index: 101; 
} 
.menu { 
  position: absolute; 
  top: 60px; 
  left: 0; 
  right: 0; 
  width: 300px; 
  background: #a7a7a7; 
  height: 30px; 
  margin: 0 auto; 
  z-index: 100; 
  display: none; 
  -moz-transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
  -o-transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
  -webkit-transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
  transition: all 0.4s cubic-bezier(0.2, 0.57, 0.36, 0.8); 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="header"></div> 
<div class="menu"></div>

READ ALSO
Второй вопрос по абстракции

Второй вопрос по абстракции

Доброго вечера всемЯ уже писал тут, что изучаю JS по книге "Выразительный JS" и тема опять проходит по абстракциям

479
Как задать координаты массива в input-е Js

Как задать координаты массива в input-е Js

Написал функцию, которая рисует таблицу и передал в нее массивС помощью input можно рисовать строки и столбцы

529
Как объединить фигуры на canvas?

Как объединить фигуры на canvas?

Мне нужно прикрутить графическое редактирование к текущему проектуНе могу найти решение по обледенению фигур

440
Парсинг html в json

Парсинг html в json

Я спарсил информацию с сайта и у меня есть около 1000 div на подобии

471