10 июля 2013 г.

Вариант дропдаун меню

В своем уголке самописных костылей я хочу представить концепт контекстное меню (дропдаун меню) реализованного на inlin-овых js скриптах с CSS3 переходами. Бэкендеры на работе обратились ко мне с просьбой накастылять нехитрую реализацию контекстного меню, содержимое которого они могли править не сильно погружаюсь в js код. Грубо говоря копипастить на страницу чистым php. Полученную демку я представляю здесь.

Достоинства и недостатки:
+ не требует предварительной инициализации объектов, не требуется ожидания готовности DOM;
+ удобный доступ к содержимому для бэкенда;
- код сложнее для анализа.



html:
<div class="frame">
    <div onclick="CtxInlineController.open(this)" class="menu-target ">
        <div class="ctx-wrapper">
            <div  style="display:none;"  class="ctx-menu" onmouseout="CtxInlineController.out(this,event)" onclick="event.stopPropagation()">
                <span class="line" onclick="alert('12');CtxInlineController.closeCtx(this)">123456</span>
                <span class="line" onclick="alert('ab');CtxInlineController.closeCtx(this)">abcdef</span>
            </div>
        </div>
    </div>
</div>

css:
.frame{
    position:relative;
    width:200px; 
    height:100px;
    border: 1px solid #666;
}
.line{
    display: block;
    width:100%;
    font-size:11px;
    line-height: 16px;
    cursor:pointer;
}

.menu-target{
    position:absolute;
    right:5px;
    top:5px;
    width:24px;
    height:24px;
    border:1px solid #666;
    background-color: #CCC;
}
.menu-target:hover{
    background-color: yellow;
}
.ctx-wrapper{
    position: relative;
    width:100%;
    height:0;
}

.ctx-menu{
    position:absolute;
    top:25px;
    right:-1px; 

    background-color:rgba(0,0,0,.7);
    color:white;
    width:166px;
    margin-top:50px;
    opacity: 0;
    -webkit-transition: all 0.3s ease-in-out;
    -moz-transition: all 0.3s ease-in-out;
    -ms-transition: all 0.3s ease-in-out;
    transition: all 0.3s ease-in-out;
}
.ctx-menu-behavior{
    margin-top:0;
    opacity: 1;
}


js:
var CtxInlineController = {
    // Const for configure:
    MENU_SELECTOR:".ctx-menu",
    TRANSITION_CLASS:"ctx-menu-behavior",
    // Inline methods:
    // @memberOf CtxInlineController - onclick handler
    // @param {HtmlElement} self - target element
    open:function(self){
        var     $self = $(self),
                ctxMenu = $self.find(this.MENU_SELECTOR);
        
        if(ctxMenu.css("display")=="none"){
            ctxMenu.removeClass(this.TRANSITION_CLASS);
            ctxMenu.show();
            ctxMenu.addClass(this.TRANSITION_CLASS);
        }else{
            ctxMenu.removeClass(this.TRANSITION_CLASS);
            setTimeout(function(){
                ctxMenu.css("display","none");
            },300);
        }
    },
    // @memberOf CtxInlineController - onmouseout handler
    // @param {HtmlElement} self - target element
    // @param {MouseEvent} event
    out:function(self,event){
        var e = event.toElement || event.relatedTarget;
        if (e.parentNode == self ||  e == self) {
            return;
        }
        if(self.style.display!='none'){
            $(self).removeClass(this.TRANSITION_CLASS);
            setTimeout(function(){
                self.style.display='none';
            },300);
        }
    },
    // @memberOf CtxInlineController api for closing menu
    // @param {HtmlElement} self - target element
    closeCtx:function(self){
        var ctxMenu = $(self).closest(this.MENU_SELECTOR);
        
        ctxMenu.removeClass(this.TRANSITION_CLASS);
        setTimeout(function(){
            ctxMenu.css("display","none");
        },300);

    }
};

В заключении могу дополнить, что использование jquery не обязательно, все вызовы можно переписать на нативный js. СSS анимацию можно переделать к любому угодному виду.