Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   убрать при клике в другом месте (https://javascript.ru/forum/events/66204-ubrat-pri-klike-v-drugom-meste.html)

VGreen 01.12.2016 04:41

убрать при клике в другом месте
 
всем доброго времени суток
выручайте, начал изучать js и столкнулся с проблемой, не могу реализовать такую фишку
есть блок который по умолчанию не виден, при клике скажем на ссылку этот блок появляется, но и закрывается он тоже по клику на данную ссылку. Как организовать так чтобы он закрывался не только по клику на ссылку но и по любой другой области КРОМЕ самого блока и его дочерних элементов???
а тут все имеющиеся коды http://codepen.io/v-green/pen/LbOvKM

PS если можно еще и комментарии добавьте пожалуйста

ksa 01.12.2016 09:24

Цитата:

Сообщение от VGreen
Как организовать так чтобы он закрывался не только по клику на ссылку но и по любой другой области КРОМЕ самого блока и его дочерних элементов?

Цитата:

обычно все это делают так
function openPopup(e)
{
//показываем попап
}
function closePopup (e)
{
// скрываем поп-ап
    $('body').off('click', closePopup);
}

$('button').on(
    'click',
    function (e)
    {
        e.preventDefault();
        openPopup(e);
        setTimeout(
            function ()
            {
                 $('body').on('click', closePopup)
            }
        );
        return false;
    }
);

setTimeout в данном случае приводит все реализации "всплытия" событий к единообразию. Он откладывает выполнение привязки закрытия события на время, когда событие закончится.
Взято тут...

Dilettante_Pro 01.12.2016 11:24

ksa,
А если дивов и кнопок несколько, как в примере ТС?

ksa 01.12.2016 11:36

Цитата:

Сообщение от Dilettante_Pro
А если дивов и кнопок несколько

Их не давят одновременно...
Всплывающие ДИВы можно свести к одному, заполняя его разным контентом...
Зная дочерний элемент, всегда можно проверить "нет ли родителя с определенным классом или еще чем-то"...

Т.о. используя, описанный выше, подход можно решить данную проблему.

VGreen 01.12.2016 12:32

ksa, это конечно хорошо, но немного не то, поскольку дивов много, а скрипт надо один, да и использоваться он будет не как поп-ап окно, а нечто вроде подсказки но с возможностью донести до пользователя информацию, например сделать мини-профиль, форму входа, форму поиска, блок сортировки файлов и тд и тп

ksa 01.12.2016 13:20

Цитата:

Сообщение от VGreen
использоваться он будет не как поп-ап окно, а нечто вроде подсказки

Те же груши, только боком...

ksa 01.12.2016 13:22

VGreen, если не понимаешь принцип "закрывания вне элемента" - просто сделай кнопочку "Х" в правом верхнем углу твоей "подсказки".
Нажимая на ту кнопочку элемент будет исчезать... ;)

VGreen 01.12.2016 13:45

это уже велосипед, кликай ссылку она и закроет. А так да, я не понимаю принцип закрытия вне элемента, потому и написал с просьбой помочь :(

ksa 01.12.2016 14:22

Как вариант...

<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251' />
<script src='http://code.jquery.com/jquery-latest.js'></script>
<!--
<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.9/angular-route.js"></script>
-->
<style type='text/css'>
div {
	display: none;
	border: 1px solid;
}
.on {
	display: block;
}
a {
	display: block;
	margin-top: 20px;
}
a:first-child {
	margin-top: auto;
}
</style>
<script type='text/javascript'>
$(function(){
	$('a').click(function(){
		$(this).next().addClass('on');
		setTimeout(function(){
			$(document).on('click', closePopup);
		},500);
	});
	function closePopup (){
		$('.on').removeClass('on')
		$(document).off('click', closePopup);
	}
});
</script>
</head>
<body>
<a href="#">Открыть</a>
<div id="box1">Наш блок 1</div>
<a href="#">Открыть</a>
<div id="box2">Наш блок 2</div>
<a href="#">Открыть</a>
<div id="box3">Наш блок 3</div>
<a href="#">Открыть</a>
<div id="box4">Наш блок 4</div>
<a href="#">Открыть</a>
<div id="box5">Наш блок 5</div>
</body>
</html>

Dilettante_Pro 01.12.2016 14:36

ksa,
Все замечательно, за исключением одного момента:
Цитата:

Сообщение от VGreen
по любой другой области КРОМЕ самого блока и его дочерних элементов???


ksa 01.12.2016 14:38

Цитата:

Сообщение от Dilettante_Pro
КРОМЕ самого блока и его дочерних элементов?

Так ты и начинай проверять на чем кликнули...
Или это опять мне делать нужно? :D

Dilettante_Pro 01.12.2016 14:39

Как вариант, с тем же недостатком
<style>
.popup {
  position:fixed;
  top:40%;
  left:40%;
  display:none;
  background-color:lightgreen
}
</style>
<button id='i1' value='0'>Mess1</button>
<button id='i2' value='1'>Mess2</button>
<button id='i3' value='2'>Mess3</button>
<button id='i4' value='3'>Mess4</button>
<div class='popup'>ntcy</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
messages =['Сообщение 1','Сообщение 2','Сообщение 3','Сообщение 4'];
$('button').on( "click" , function(e) {
     e.preventDefault();
    $('.popup').css('display','block');
    $('.popup').text(messages[$(this).val()]);
       setTimeout(
            function ()
            {
                 $('body').on('click', closePopup)
            }
        );
        return false;    
});
function closePopup() {
  $('.popup').css('display','none');
  $('body').off('click', closePopup);
};

</script>

Dilettante_Pro 01.12.2016 14:42

ksa,
Цитата:

Сообщение от ksa
Так ты и начинай проверять на чем кликнули...
Или это опять мне делать нужно?

Да нет, никто не обязан ничего делать... Просто в вопросе ТС был и этот момент.

ksa 01.12.2016 14:43

Цитата:

Сообщение от Dilettante_Pro
Просто в вопросе ТС был и этот момент.

Ну хоть что-то он должен сделать сам! :D

ksa 01.12.2016 14:49

Цитата:

Сообщение от Dilettante_Pro
Как вариант, с тем же недостатком

Без недостатка... :)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=windows-1251' />
<script src='http://code.jquery.com/jquery-latest.js'></script>
<!--
<script src="https://code.angularjs.org/1.3.9/angular.min.js"></script>
<script src="https://code.angularjs.org/1.3.9/angular-route.js"></script>
-->
<style type='text/css'>
div {
	display: none;
	border: 1px solid;
}
.on {
	display: block;
}
a {
	display: block;
	margin-top: 20px;
}
a:first-child {
	margin-top: auto;
}
</style>
<script type='text/javascript'>
$(function(){
	$('a').click(function(){
		$(this).next().addClass('on');
		setTimeout(function(){
			$(document).on('click', closePopup);
		},500);
	});
	function closePopup (event){
		var obj=event.target||event.srcElement;
		if ($(obj).hasClass('on') || ($(obj).parents('.on').length>0)) {
			return;
		};
		$('.on').removeClass('on')
		$(document).off('click', closePopup);
	}
});
</script>
</head>
<body>
<a href="#">Открыть</a>
<div id="box1">Наш блок 1</div>
<a href="#">Открыть</a>
<div id="box2">Наш блок 2</div>
<a href="#">Открыть</a>
<div id="box3">Наш блок 3</div>
<a href="#">Открыть</a>
<div id="box4">Наш блок 4</div>
<a href="#">Открыть</a>
<div id="box5">Наш блок 5</div>
</body>
</html>

Dilettante_Pro 01.12.2016 15:28

ksa,
Ну вот, дело завершено:dance:
А ТС молчит...

ksa 01.12.2016 15:44

Цитата:

Сообщение от Dilettante_Pro
А ТС молчит...

Деньги поди считает... :D

Dilettante_Pro 01.12.2016 15:51

ksa,
Цитата:

Сообщение от ksa
Без недостатка...

срабатывает только один раз:( или по двойному

ksa 01.12.2016 15:52

Цитата:

Сообщение от Dilettante_Pro
срабатывает только один раз

Это тут...
Ты копирни текст и сохрани локально, потом запусти.

Тут на форуме структура документа более сложная... ;)

Dilettante_Pro 01.12.2016 16:02

Мой вариант без недостатка вроде живой
<style>
.popup {
  position:fixed;
  top:40%;
  left:40%;
  display:none;
  font-size: 20pt;
  background-color:lightgreen
}
</style>
<button id='i1' value='0'>Mess1</button>  <!-- value - индекс для сообщения -->
<button id='i2' value='1'>Mess2</button>
<button id='i3' value='2'>Mess3</button>
<button id='i4' value='3'>Mess4</button>
<div class='popup'></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script>
messages =['Сообщение 1','Сообщение 2','Сообщение 3','Сообщение 4'];  // набор сообщений
$('button').on( "click" , function(e) {              // клик по кнопке
                
    $('.popup').css('display','block');               // показ блока
    $('.popup').text(messages[$(this).val()]);   // вставка нужного сообщения в блок
       setTimeout(                                       // ksa сказал зачем 
            function ()
            {
                 $('body').on('click', closePopup)  // включение закрытия по клику везде
            }
        );
        return false;    
});
function closePopup(event) {           // описание закрытия по клику везде
  var obj=event.target||event.srcElement; // кликнутый элемент
  if ($(obj).hasClass('popup'))  return;      // кроме клика по popup
  $('.popup').css('display','none');            // закрытие блока
  $('body').off('click', closePopup);           // выключение закрытия по клику везде
};

</script>

VGreen 01.12.2016 16:26

спасибо за помощь, а молчал, занят был

VGreen 01.12.2016 16:28

а можете свои коды прокомментировать? стыдно просить, итак помогли, но хоть понять что и как тут сделано, и в будущем отталкиваться от этого

Dilettante_Pro 01.12.2016 16:43

VGreen,
Комментарии добавлены в последний вариант

Rise 01.12.2016 22:41

VGreen, ksa, Dilettante_Pro, .closest()

ksa 02.12.2016 08:27

Цитата:

Сообщение от Rise
.closest()

За всеми новинками не угонишься... :no:


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