Закрытие меню по клику вне блока на vanila js

181
04 марта 2019, 22:10

Помогите реализовать закрытие меню по клику вне блока на чистом Java Script везде примеры только на JQ, я стараюсь максимально обходиться без него.

Пока что у меня реализовано закрытие через клик по прозрачному блоку на заднем фоне, но это не подходит.

    <h3 class="open_context" lock="open">Нажми на меня</h3>
    <p>If you could open up to me, oh!
Can't we ever get beyond this wall?
Cause all I want is just once to see you in</p>
    <script>
        function cons(){
            console.log(this);  
        }
        function al(){
            alert(this.innerText);  
        }
        var array = ['первый', 'второй', 'третий' ];
        var funce = [cons, al, cons];

        //ФУНКЦИЯ СОЗДАНИЯ КОНТЕКСТНОГО МЕНЮ
        //БЛОК СОЗДАЕТСЯ ВНУТРИ ФУНКЦИИ
        function context_menu({
                    list_array: list, //массив с элементами списка
                    list_func: func, //массив с функциями для элементов меню
                    id_menu: id_context_menu, //id блока с контекстным меню 
                    position_left: left = 0, //отступ слева (по умолчанию 0)
                    position_top: top = 30,//отступ сверху (по умолчанию 30px
                }){
            this.onclick = function(){
            if(this.getAttribute('lock') == 'open'){
                var div = document.createElement('div');
                    div.classList.add('context');
                    div.id = id_context_menu;
                    div.style.left = left + 'px';
                    div.style.top = top + 'px';
                var that = this;
                var back_div = document.createElement('div');
                    back_div.classList.add('back_div');
                    back_div.onclick = function(){
                        document.getElementById(id_context_menu).remove();
                        that.setAttribute('lock', 'open');
                        this.remove();
                    }
                var ul = document.createElement('ul');
                for(let i = 0; i < list.length; i++){
                    var li = document.createElement('li');
                        li.innerText = list[i];
                        li.onclick = func[i];
                        li.addEventListener('click', function(){
                            document.querySelector('.back_div').remove();
                        });
                    ul.appendChild(li);
                }//end for
                div.appendChild(ul);
                this.appendChild(div);
                this.parentNode.insertBefore(back_div, this);
                this.setAttribute('lock', 'close');
            }else{
                document.getElementById(id_context_menu).remove();
                this.setAttribute('lock', 'open');
            }//end else
            }//end onclick

        }///////////end context_menu
        //вызов функции контекстного меню с настройками 
        context_menu.call(document.querySelector('.open_context'), {
                list_array: array, //массив с элементами списка
                list_func: funce, //массив с функциями для элементов меню
                id_menu:  'task_menu', //id блока с контекстным меню 
        });////////////////
    </script>
    <style>
    body{
        height: 1000px; 
    }
        .open_context{
            cursor:pointer; 
            margin-left: 200px;
            position: relative;
        }
        .context{
            display: inline-blick;
            background-color: white;
            border: 1px solid lightgrey;
            box-shadow: 0 0 5px rgba(0,0,0,0.2);
            position: absolute;
            top:30px;
            left:0;
            z-index: 99998;
        }
        .context ul{
            margin: 0;  
            padding: 0;
        }
        .context li{
            list-style: none;
            padding: 5px 15px;
            border-bottom: 1px solid lightgrey;
        }
        .context li:hover{
            background-color: #F3F3F3;
        }
        .back_div{
            display: block;
            position: fixed;
            opacity: 0.7;
            top:0;
            left:0;
            width: 100%;
            height:100%;
            z-index: 99998;
        }
    </style>
Answer 1

Делал для dropdown клик вне элемента, должно подойти

let select = document.querySelectorAll('.form-wrapper__select');
    document.body.onclick = function (e) {
        if (!e.target.closest('.form-wrapper__select')) {
            select.forEach(item => {
                if (item.classList.contains('on')) {
                    item.classList.remove('on');
                }
            });
        } 
    }
READ ALSO
Асинхронность callback с return и throw

Асинхронность callback с return и throw

Подскажите пожалуйста минусы использования callback (помимо основных лапша в коде), и почему мы не можем использовать return и throw с callbackами (помимо...

178
JavaScript Оператор return

JavaScript Оператор return

Задача: вернуть средний символ словаЕсли длина слова нечетна, верните средний символ

180