Форум программистов, компьютерный форум, киберфорум
jQuery
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/81: Рейтинг темы: голосов - 81, средняя оценка - 4.93
 Аватар для __PION__
960 / 801 / 85
Регистрация: 21.07.2010
Сообщений: 3,522

Закрыть блок при клике по любому месту на странице

31.10.2012, 21:25. Показов 15249. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет!
Есть список, который открывается при нажатии на некоторую ссылку, также и закрывается при повторном нажатии.
Нужно еще, чтобы блок закрывался при нажатии по любому месту страницы, кроме самого блока.
Как такое сделать?
JavaScript
1
$('body').click...
не предлагать, не работает.

Пример - меню этого форума.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.10.2012, 21:25
Ответы с готовыми решениями:

При клике в браузере по любому месту открываются левые сайты
При нажатии по любому месту в браузере открываются сайты по типу джойказино. Появилось много рекламы с которыми адблоки не справляются....

При клике по любому месту на большинстве сайтов открывается рекламная страница
При клике по любому месту на большинстве сайтов открывается рекламная страница. Иногда это происходит при каждом клике, иногда только...

Сделать, чтобы при клике на кнопке, блок #cont исчез, а при повторном клике блок #cont появился
Как сделать, чтобы при клике на кнопке, блок #cont исчез, а при повторном клике блок #cont появился? Вроде это уже устаревший способ и не...

14
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
 Аватар для KOPOJI
16844 / 6724 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
31.10.2012, 21:28
Цитата Сообщение от Love_and_Peace Посмотреть сообщение
JavaScript
1
$('body').click
насколько помню, так надо
JavaScript
1
$(document.body).click(...
но внутри еще нужно проверять куда щелкнули - на ссылку или же в другое место
1
 Аватар для __PION__
960 / 801 / 85
Регистрация: 21.07.2010
Сообщений: 3,522
31.10.2012, 21:31  [ТС]
KOPOJI, когда пишу body, блок не появляется вабще, даже при клике по ссылке, т.к., сама ссылка внутри body.
нет ли у тя готового решения, задача распространенная, но почему то в сети не нашел разумного решения
0
 Аватар для Soldado
901 / 833 / 198
Регистрация: 28.06.2012
Сообщений: 1,607
Записей в блоге: 4
31.10.2012, 21:46
Когда кликаешь по чему-то там чтобы блок раскрылся, то клик происходит и по body, так как кликнутый элемент тоже находится в body и получается, что блок открывается и одновременно закрывается. Есть возможность предотвратить этот, так называемый, bibbling-еффект, чтобы клик касался только верхнего элемента. Для этого используют stopPropagation()
Вот демо-страница, там всё видно
1
 Аватар для __PION__
960 / 801 / 85
Регистрация: 21.07.2010
Сообщений: 3,522
31.10.2012, 23:11  [ТС]
Soldado, все отлично, но вот тока блок закрывается и при клике по блоку (
че делать?

Добавлено через 3 минуты
+ при повторном клике по ссылке блок не закрывается
0
 Аватар для Soldado
901 / 833 / 198
Регистрация: 28.06.2012
Сообщений: 1,607
Записей в блоге: 4
01.11.2012, 02:26
при повторном клике по ссылке блок не закрывается
Я думал, что с этим проблем у Вас нет, вы пишите:
Цитата Сообщение от Love_and_Peace Посмотреть сообщение
Есть список, который открывается при нажатии на некоторую ссылку, также и закрывается при повторном нажатии.
В примере я показал только как кликать по body
Если проблема всё же существует, то давайте полный код или сами используйте .toggle() (есть недостаток - если откроем, а потом закроем кликом по body, то для нового открытия прийдётся кликать дважды) или .click (рекомендую), но тогда анализируйте свойство display.
Как на этом сайте
1
Эксперт JSЭксперт HTML/CSS
2436 / 1115 / 312
Регистрация: 23.06.2011
Сообщений: 3,529
01.11.2012, 06:16
подправляем под реальный поиск конкретного элемента
JavaScript
1
2
3
4
5
6
7
8
9
10
11
var obj=ev?ev.target:event.srcElement;//остальные или ИЕ
//в цикле просматриваем все теги, от тега по которому щёлкнули до тега HTML.
while(obj.parentNode){
if(obj.=='myObj'){break;}//если попался нужный элемент, любая проверка
else{obj=obj.parentNode;}};//иначе ищем дальше
//на выходе из цикла проверяем где вышли
if(obj.=='myObj'){//по элементу
....
return false;
}
else{};//мимо элемента
1
 Аватар для __PION__
960 / 801 / 85
Регистрация: 21.07.2010
Сообщений: 3,522
01.11.2012, 09:06  [ТС]
Цитата Сообщение от Soldado Посмотреть сообщение
Я думал, что с этим проблем у Вас нет, вы пишите:
так с этим проблем не было, проблема появилась, когда вставил код, который вы показали.
Показываю код
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// то что я вписал
$('body').click(function() {
    $('.ulRegionList').css('display','none');
});
 
 
// Вот ссылка (точнее div), которая открывает блок
// Блок открывается, но не закрывается при клике по нему же. раньше закрывал
$('.regionList').live("click", function(ob) {
 
    ob.stopPropagation();   // сюда вписал и это тоже как вы и советовали
 
    var regionListId = $(this).attr('id');
        
    if ($('#ul'+regionListId).is(':visible'))
        $('.ulRegionList').css('display','none');
    else {
        $('.ulRegionList').css('display','none');
        $('#ul'+regionListId).css('display','block');
    }
});
 
 
// И действия в уже открывшемся блоке (просто чекаю чекбоксы)
// Изменение цвета элемента списка при отмеченом чекбоксе
$('input[id*=region]').each(function() {
    $(this).click(function(ob) {
            ob.stopPropagation();
    var thisCheck = $(this).attr('checked');
    if (thisCheck)
         $(this).parent().parent().css('background','#fff2b4');
    else
         $(this).parent().parent().css('background','none');
    });
});
везде я вставил
JavaScript
1
ob.stopPropagation();
, но чето блок все равно сворачивается
0
 Аватар для Soldado
901 / 833 / 198
Регистрация: 28.06.2012
Сообщений: 1,607
Записей в блоге: 4
01.11.2012, 15:01
Дайте ещё и html со стилями, чтобы я мог всё скопировать себе и посмотреть в работе.
0
 Аватар для __PION__
960 / 801 / 85
Регистрация: 21.07.2010
Сообщений: 3,522
01.11.2012, 16:25  [ТС]
вот хтмл (весь не привожу, большой список)
HTML5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<div class="regionListMain" style="/*display: block;*/">
   <div id="regionListOrd" class="regionList">Выберите регион</div>
   <ul id="ulregionListOrd" class="ulRegionList" style="display: none;">
                            
     <li class="okrug" id="okr110">Южный федеральный округ</li>
 
     <li class="regionName">
        <label>
          <input type="checkbox" name="region[]" value="100" id="region110_100" class="region" />
          <span>Республика Адыгея</span>
        </label>
     </li>
     <li class="regionName">
        <label>
           <input type="checkbox" name="region[]" value="107" id="region110_107" class="region" />
           <span>Республика Калмыкия</span>
        </label>
      </li>
      <li class="regionName">
        <label>
          <input type="checkbox" name="region[]" value="108" id="region110_109" class="region" />
          <span>Краснодарский край</span>
        </label>
     </li>
     <li class="regionName">
        <label>
           <input type="checkbox" name="region[]" value="109" id="region110_109" class="region" />
           <span>Астраханская область</span>
        </label>
      </li>
 
   </ul>
   <br />
   <div id="regionsOrd"></div>
</div>
это css
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
.regionListMain { position: relative; margin: 0 0 15px 0; /*height: 40px;*/ }
.regionList {
    background: url(../icons/arrow2_s.png) no-repeat 100% 50%;
    width: 257px;
    height: 18px;
    padding: 3px;
    border: 1px solid #888;
    cursor: pointer;
    position: absolute;
    font-family: Tahoma;
    font-weight: bold;
    padding-left: 10px;
}
ul.ulRegionList {
    width: 270px;
    height: 150px;
    border: 1px solid #888;/**/
    position: absolute;
    top: 25px;
    overflow: scroll;
    background: #fff;
}
ul.ulRegionList li { font-family: Tahoma !important; padding: 3px; display: block; }
ul.ulRegionList li:hover { background: #eee; }
/**/
.regionName { position: relative; }
li.regionName label { display: block; font-family: Tahoma !important; overflow: hidden; }
li.regionName input { position: absolute; top: 5px; left: 7px; }
li.regionName span { width: 210px; display: inline-block; margin-left: 25px; }
 
/**/
li.okrug {
    font-weight: bold;
    cursor: pointer;
    display: block;
    border-bottom: 1px dashed #ccc;
    padding-left: 5px !important;
    margin-left: 0 !important;
    margin-bottom: 5px;
    text-align: left !important;
}
и уже почти работающий js. При повторном клике на div, открывающий блок этот самый блок не закрывается. я понимаю почему, но решения не могу найти
вот js
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
$('body').click(function() { // скрыть блок списка регионов по клику вне блока
        $('.ulRegionList').css('display','none');
    });
    
    $('.ulRegionList').live("click", function() { // показывать блок при действиях внутри блока
        var spanRegionName = '';
        var ulId = $(this).attr('id');
        $('#'+ulId).css('display','block');
        
        // Кол-во выбранных чекбоксов в списке
        var checkRegInput = $('#'+ulId+' input[id*=region]:checked');
        if (checkRegInput.length > 0) { // Если есть выбранные чекбоксы, то вписываем их кол-во к заголовку
            $('#'+ulId).prev().html('Выберите регион ('+checkRegInput.length+')');
            
            // Вывод выбранных регионов в отдельный блок
            $(checkRegInput).each(function() {
                spanRegionName = spanRegionName + $(this).parent().find('span').html() + '<br />';
            });
            $('#'+ulId).next().next().css('padding','20px 0 10px 0').html(spanRegionName);
            
        } else { // иначе, убираем
            $('#'+ulId).prev().html('Выберите регион');
            $('#'+ulId).next().next().css('padding','0').html('');
        }
    });
    
    // Открытие списка <ul> (Клик по div'у "Выбрать регион")
    $('.regionList').live("click", function() {
        var regionListId = $(this).attr('id');
        if ($('#ul'+regionListId).is(':visible'))
            $('.ulRegionList').css('display','none');
        else {
            $('.ulRegionList').css('display','none');
            $('#ul'+regionListId).css('display','block');
        }
    });
    
 
    var oneCheck = false; // показывает число чекнутых и нечекнутых чекбоксов в текущем разделе (округе) <li>
    // выделение чекбоксов в текущем узле
    $('.okrug').live("click", function() {
        // Чтобы не спутать чекбоксы в 2-х списках
        var okrParentId = $(this).parent().attr('id');
        $('#'+okrParentId).css('display','block');
        // 
        var okrugIdInt = $(this).attr('id').substr(3);     // region100_129    a[id*=otzanswer_]
        var okrugRegion = $('#'+okrParentId+' input[id*=region'+okrugIdInt+']');
        // выбранные чекбоксы в списке
        var cntItemCheck = $('#'+okrParentId+' input[id*=region'+okrugIdInt+']:checked');
 
        if (cntItemCheck.length == okrugRegion.length) oneCheck = true;
        else oneCheck = false;
        
        $('#'+okrParentId+' input[id*=region'+okrugIdInt+']').each(function() {
            var thisCheck = $(this).attr('checked');
 
            if (oneCheck) {
                $(this).removeAttr('checked');
                $(this).parent().parent().css('background','none');
            } else {
                $(this).attr('checked','checked');
                $(this).parent().parent().css('background','#fff2b4');
            }
 
        });
    });
    
    // Изменение цвета элемента списка при отмеченом чекбоксе
    $('input[id*=region]').each(function() {
        $(this).live("click", function() {
            var thisCheck = $(this).attr('checked');
            if (thisCheck)
                $(this).parent().parent().css('background','#fff2b4');
            else
                $(this).parent().parent().css('background','none');
        });
    });
не работает потому, что сценарий никогда не попадает вот в это условие
JavaScript
1
if ($('#ul'+regionListId).is(':visible'))
из-за этого действия
JavaScript
1
2
3
$('body').click(function() {
    $('.ulRegionList').css('display','none');
});
и может покомпактней можно все это написать
0
 Аватар для Soldado
901 / 833 / 198
Регистрация: 28.06.2012
Сообщений: 1,607
Записей в блоге: 4
01.11.2012, 16:32
Live устаревший метод от него предполагается отказаться в будущем, используйте on, вот так работает:
Это переделан код из Вашего поста №8, со строки 10.
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
$('body').on("click",".regionList", function(ob) {
 
    ob.stopPropagation();   // сюда вписал и это тоже как вы и советовали
 
    var regionListId = $(this).attr('id');
    
        
    if ($('#ul'+regionListId).is(':visible')){  $('.ulRegionList').css('display','none');}
    else {
        $('.ulRegionList').css('display','none');
        $('#ul'+regionListId).css('display','block');
    }
});
С чекбоксами ещё посмотреть или уже решили?
1
 Аватар для __PION__
960 / 801 / 85
Регистрация: 21.07.2010
Сообщений: 3,522
01.11.2012, 16:47  [ТС]
Цитата Сообщение от Soldado Посмотреть сообщение
Live устаревший метод
я думал это новый метод, пришедший, по-мойму, на место bind
Цитата Сообщение от Soldado Посмотреть сообщение
С чекбоксами ещё посмотреть или уже решили?
а что за проблема, я уже запутался ))

Добавлено через 20 секунд
кстати, у меня работает и без этого
Цитата Сообщение от Soldado Посмотреть сообщение
ob.stopPropagation();
Добавлено через 7 минут
при вставке последнего предложенного метода, блок перестал исчезать при клике по любому месту страницы.
при клике на открывающий div теперь блок закрывается
0
 Аватар для Soldado
901 / 833 / 198
Регистрация: 28.06.2012
Сообщений: 1,607
Записей в блоге: 4
01.11.2012, 16:51
У меня в последней опере не работает без ob.stopPropagation(); в части кода где live на on заменил.
В общем так.
Всё что мне дали объединил, лишь заменил live на on и залил на demo-страницу .

Что работает не так как Вы хотите?
1
 Аватар для __PION__
960 / 801 / 85
Регистрация: 21.07.2010
Сообщений: 3,522
01.11.2012, 17:18  [ТС]
Цитата Сообщение от Soldado Посмотреть сообщение
Что работает не так как Вы хотите?
все заработало!!!!! Ты лучший!
Спасибо большое

Добавлено через 5 минут
замену Live на On стоит везде сделать?
0
 Аватар для Soldado
901 / 833 / 198
Регистрация: 28.06.2012
Сообщений: 1,607
Записей в блоге: 4
01.11.2012, 17:23
Рад что помог.
На счёт упрощения кода. Вы получаете атрибут id у элемента, а затем из него формируете атрибут id элемента ul к которому обращаетесь. Верно? Но если посмотреть на html-код, то заметите что относительно кликнутого элемента необходимый Вам ul является следующим, а значит можно обойтись более простым способом доступа к нему.
И код // Открытие списка <ul> (Клик по div'у "Выбрать регион") может упростится на несколько строчек:
JavaScript
1
2
3
4
5
6
7
8
9
10
11
// Открытие списка <ul> (Клик по div'у "Выбрать регион")
    $('body').on("click",".regionList", function(ob) {
 
    ob.stopPropagation();   // сюда вписал и это тоже как вы и советовали
      
    if ($(this).next().is(':visible')){  $('.ulRegionList').css('display','none');}
    else {
        $('.ulRegionList').css('display','none');
        $(this).next().css('display','block');
    }
});
Лучше отказаться от live сейчас, в новой библиотеке могут быть новые "полезности" Вы их захотите использовать, а live уже не будет
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.11.2012, 17:23
Помогаю со студенческими работами здесь

Почему при двойном клике по любому Label его текст копируется в буфер обмена?
Почему при двойном клике по любому Label его текст копируется в буфер обмена? ЗАЧЕМ это сделано и как это убрать? PS: у меня нет...

Открыть закрыть блок при нажатии по ссылке и закрыть его при нажатии вне этого блока
Здравствуйте, несколько дней уже пытаюсь решить задачу, мне нужно сделать блок с авторизацией. Нужно что бы при нажатии на ссылку блок...

при клике вне виджета закрыть его
подскажите как срыть виджет при клике вне его области?

Закрыть окно (программу) при клике вне ее
Собственно заголовок и содержит вопрос: как/что нужно сделать чтобы программа закрывалась если пользователь кликнул вне ее окна? Наподобие...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru