弹出菜单

开课吧开课吧锤锤2021-04-23 19:19

    从在这里找到的代码开始,我开发了一个非常简单的上下文弹出菜单。

    它只有一个级别(没有嵌套菜单),但可能适合90%的Web项目。在弹出菜单与JavaScript的“执行功能的对象”,“老时尚”的发展风格,以保持代码(使用)尽可能简单。

web

    背景

    要了解此代码就足够了:

    知道如何object在JavaScript中实现“”

    具有jQuery的基本知识

    有CSS的基础知识

    使用代码

    该图显示了菜单的外观。这只是一个示例,您可以做自己想做的事情,唯一的限制就是使用标签<ul><li>。您可以使用不同的标签,但是必须修改函数“PopupMenu”中的代码。

web

    查看代码,您可以找到两种不同的使用对象的方法。

    jQuery方式

    第214行创建了'PopupMenu'对象的实例,其中'GroupB'是图片中两个灰色区域的选择器(因此它们都有相同的弹出菜单),而jQuery将事件(来自菜单项)与管理功能绑定在一起。216-219行

web

    下图显示了上面的JavaScript代码所引用的HTML。

web

    “在线”方式:

    这是使用该对象的最简单方法:创建'PopupMenu:第266行的实例就足够了,它提供了要向其添加弹出菜单的元素的选择器和菜单的选择器(<ul>)。在第248-250行中,有'onclick'事件的在线定义,在第268-268行中有事件的功能。

web

    整页代码

    您还可以将下面的代码“复制并粘贴”到HTML文件中,您还将获得一个完全运行的示例,其中包含图像(编码为base64)。

    标记<script>可以链接到e:http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js,也可以在计算机中引用jQuery的副本。

<!DOCTYPE html>

<html ><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
 
    <title>jQuery contextMenu</title>
        
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script>        

    <script type="text/javascript">    
        try{
            
            if (typeof jQuery != 'undefined') {  
                document.write
                ('<label style="color:green;">jQuery running version: </label><b>' + 
                jQuery.fn.jquery + '</b>');
            }
            else{
                document.write('<label style="color:red;"> ** ATTENTION ** </label>' + 
                               ' jQuery is not running!');
            }    
        }
        catch(jse){
            document.write(' ** ATTENTION **  ' + jse.message);
        }        
        
        document.write(' - "PopupMenu" is based on code found 
            <a href="https://stackoverflow.com/questions/4495626/
            making-custom-right-click-context-menus-for-my-web-app" 
            target="_blank">HERE</a>');
        
         
    </script>
    
    <!--<span class="code-comment"> CSS that makes popup menu run--></span>
    <style>        
        .custom-menu {
            /* structural css */
            display: none;
            z-index: 1000;
            position: absolute;
            overflow: hidden;
        }        
    </style>

    <!--<span class="code-comment"> the custom CSS with the custom style --></span>
    <style>    
        .custom-style{
            /* stylistical css */
            white-space: nowrap;
            font-family: verdana;
            font-size:13px;
            color: #333;
            border-radius: 2px;
            
            border: solid 1px #ddd;        
            background-color: #FFF;            
            padding: 0;            
            margin: 0;
            -webkit-box-shadow: 10px 10px 20px 0px rgba(119,119,119,1);
            -moz-box-shadow: 10px 10px 20px 0px rgba(119,119,119,1);
            box-shadow: 10px 10px 20px 0px rgba(119,119,119,1);            
        }

        .custom-style li {
            padding: 3px 15px 5px 30px;
            cursor: pointer;
            list-style-type: none;
        }

        .custom-style li:hover {
            background-color: #EEE; /* DEF */
        }
        
        .custom-style li.image{
            background-repeat: no-repeat;
            background-position: 8px 5px;
        }    
        
        .custom-style li.delete{
            background-image: url('data:image/png;base64,
            iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/
            xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+
            wAAABESURBVDhPY/j//z9FGEOgubn5Pz6Mrh6FA8JQRVgB0Qbgw+jqidKEC1PPABiGCoIBATZcz6gBw9MAY
            jCyHhQDSMf/GQAPPgrAR+lEmQAAAABJRU5ErkJggg==')
        }        
        .custom-style li.edit{
            background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/
            9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0ID
            QuMC4xMkMEa+wAAAEMSURBVDhPnZOhkoNAEETzxzgUDofCITE4HAoFDouiUFQh+AYMoo83y3JJLrkj11VvgWWmm
            ZlNbpI+Zp7n/eLubVmWReM4vmWapjMBuq7TMAy2d260bfuWvu8t2BvyQTgN6roWbNvG5g+t62pfJKZpmjMZbKmq
            SvBKmFKBj6GiXZYHtpRlKXgl2vPvqYB5YOIHaQZFUQieRen+HQY8k8gzxrucQZ7ngmfRK/skHH1bBez5Vswgyz
            LBveidgTH1++FiQCzt7HIGaZoKrggDYh8MkiQRXBEVEXucmjOI41hwRfweiD1OzRlEUSRgyn/B9Il9MAjDUOBP4
            zcon9jj2L9nEATBR/g/mBn8H92+AMRlSI4HRnCNAAAAAElFTkSuQmCC')
        }        
        .custom-style li.refresh{
		background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/
        9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC
		4xMkMEa+wAAACSSURBVDhPtZJLDsAgCEQ9tRfQw3gir0MziyEjxaafdPESeFCKxmJmn0jlEzxorVmEtVqr9d49V5ZkN0
		DdnNM98ABoI6AfY6QeeIAVtSk2Ano9zqmIvzFnjegmdF6MhR3/D+ARFH5weQS9RDpCT9JLBNqkm6gH9MADgEeSNapTDz
		xQsCKeL/M4QIcsH74hlfexcgDQkdsLtKMLtAAAAABJRU5ErkJggg==')
        }        
        .custom-style li.add{
            background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/
            9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwgAADsIBFShKgAAAABl0RVh0U29mdHdhcmUAcGFpbn
            QubmV0IDQuMC4xMkMEa+wAAABkSURBVDhPpc1bCkAhCEXR5j8qZ+ZFoTjCLsT7sSTNx3L3XzKYmXfpcCj
            JRAa6dKPDoSQTGejSjQ6HkkxkoEubNhMs3tDS8kG0mWrn8aILVfw9G0JrQZcObuWDaDPVzmMKi32+
            PhgFEhDFFe1qAAAAAElFTkSuQmCC')
        }
    </style>
    
    <!--<span class="code-comment"> /* CSS for the page */ --></span>
    <style>
        body{
            color: #444;
            font-family: verdana;
            font-size:13px;    
            padding: 20px;            
        }        
        
        span{ 
            border: dotted 1px #ccc; 
            background-color: #eee;
            margin: 10px 10px;
            width:140px;
            height:40px;
            padding-top:10px;
            display: inline-block;
            text-align:center;
        }
        
        div{
            border: dotted 1px #ccc; 
            margin: 30px 0px;
            padding:10px;
        }
        
    </style>
    
    <script type="text/javascript">
        // The code that implements the PopupMenu 'class'.
    
        // contextElement: the element we want have assigned a context popup menu.
        // popupElement:   the popping up menu.
        // both parameters are used by jQuery. 
        // They can be any valid selector or any jQuery element or any DOM element,
        // (the only thing this class expects id that the menu is made using 'ul'/'li' tags).
        function PopupMenu(contextElement, popupElement){
        
            // In that way, the "this" object is 'persisted'.
            var THIS = this;
            
            // Sends to the 'outside world' the DOM element that is using the popup menu 
            this.currentTarget;

            // The main purpose of this time is to maintain the menu visible also 
            // if the user leaves it accidentally (for a very short time)
            this.fadeLeaveTime = 300; // The time the menu takes to close after 
                                      // the user leaves without performing any click.
            this.fadeOpenTime  = 100; // The time the menu takes to open after a right click.        
            this.delayTime     = 300; // The time the menu remains visible if non used 
                                      // (no mouse_over on it) and before start to the fadeOut
            this.fadeCloseTyme = 100; // The time the menu takes to close after a click on a menu item.
            
            // this element is evaluated once (is used in many places)
            this.$popupElement = $(popupElement);
            
            // START =============================================================================== //
            // Manages the context menu for the provided element.
            // The actions to be performed (on the popup element) every time a contextmenu raises.
            
            $(contextElement)
            .contextmenu(function (jqEvent){
            
                // prevent the custom popup menu if the 'ctrl' key is pressed.
                if (jqEvent.ctrlKey){ return; }

                // Avoids the real one contextmenu
                jqEvent.preventDefault();
                
                // assigns the element that called the current popup.
                THIS.currentTarget = jqEvent.currentTarget;
                    
                THIS.$popupElement
                .stop(true, false)           // stops any pending effect            
                .fadeIn(THIS.fadeOpenTime)   // makes the menu visible.                    
                .delay(THIS.delayTime)       // waits before call the hover_in function.            
                .fadeOut(THIS.fadeLeaveTime) // close the menu if not used.        
                .css({                         // places the popup menu in the right position 
                    top:  (jqEvent.pageY - 0) + "px",
                    left: (jqEvent.pageX - 0) + "px"
                });
            });                
            // END  =============================================================================== //
            
            // START ============================================================================== //
            // The actions to be assigned once.
            
            function hover_in($element){        
                $element
                .stop(true, false)
                .fadeIn(THIS.fadeOpenTime);
            }    
            
            function hover_out($element){
                $element.delay(THIS.delayTime).fadeOut(THIS.fadeLeaveTime);
            }        
            
            // stops the context menu for the items of the popup menu and triggers the click event.
            function menuItem_contextmenu(jqEvent, $li){
                jqEvent.preventDefault();
                $li.trigger('click');
            }            
            
            this.$popupElement
            .hover(
                function(){hover_in ($(this))}, 
                function(){hover_out($(this))}
            )
            .find('li')
            .click(function(){                        
                $(this).closest('ul').fadeOut(THIS.fadeCloseTyme);
            })
            .contextmenu( function(jqEvent){
                menuItem_contextmenu(jqEvent, $(this));
            })
            // END  ================================================================================ //
            
            
        }
    </script>        
    
    <script type="text/javascript">
        
        // -------------------------------------------------------------------------- \\        
        
        // full jQuery use of the 'PopupMenu'
        jQuery(document).ready(function (){            

            var groupB = new PopupMenu('.groupB', "#pumB");            

            jQuery('#pumB li').click(function (){
                $(groupB.currentTarget)
                .text($(this).text());
            });            
        });    
        
        // look at the end of the page for the simplest use of the 'PopupMenu'
         
    </script>
    </head>
    <body>        
        
        <!--<span class="code-comment"> 
        =================================================================================== --></span>
        
        <!--<span class="code-comment"> the click event is managed by jQuery --></span>        
        <ul class='custom-menu custom-style' id="pumB">
          <li class="image edit"   >Edit B</li>
          <li class="image delete" >Delete B</li>
          <li class="image refresh">Refresh B</li>
          <li class="image add"    >Add new B</li>
        </ul>
        
        <div>            
            <p>These two elements share the same context popup menu, 
            the click event is managed by jQuery (look at the javascript code).</p>
            <span class="groupB" id="spnB1">Right click me</span>
            <span class="groupB" id="spnB2">Right click me</span>    
        </div>    
        
        <!--<span class="code-comment"> 
        ----------------------------------------------------------------------------------- 
        --></span>
        
        <!--<span class="code-comment"> on-line management of the click event --></span>
        <ul class='custom-menu custom-style' id="pumA">
          <li class="image edit"   onclick="liEditA_onclick()"  >Edit A</li>
          <li class="image delete" onclick="liDeleteA_onclick()">Delete A</li>
          <li class="image add"    onclick="liAddA_onclick()"   >Add new A</li>
        </ul>

        <div>
            <p>This element has its own, different, context popup menu and 
            the click event is managed on line (look at the HTML code).</p>
            <span id="spnA">Right click me</span> 
        </div>
        
        <!--<span class="code-comment"> 
        ======================================================================================== 
        --></span>
        
        <p>Hit the '<b>Ctrl</b>' key (while right click) 
        to show the 'real' context menu.</p>
        
    </body>
    
    <script type="text/javascript">    
        
        new PopupMenu('#spnA', "#pumA");
        
        function liEditA_onclick(){
            $('#spnA').text("Edit A");
        }
        
        function liDeleteA_onclick(){
            $('#spnA').text("Delete A");
        }

        function liAddA_onclick(){
            $('#spnA').text("Add A");
        }    
         
    </script>    
    
    <script type="text/javascript">    
        
        window.onerror = function() {
            document.write('<label style="color:red;">** ATTENTION ** 
            Something went wrong :-(</label>');
        };
    </script>
</html>

    兴趣点

    代码中有一个重要的“关注点”,它是一种“普遍存在”:onclick针对<li>弹出菜单的每个项目()发生的相同事件'''在两个不同的位置进行管理:

    在对象的实现中,onclick(在其中管理fadeOut弹出菜单的):

web

在“自定义代码”部分(其中管理在单击菜单时执行的操作):

web

    更多的Web教程尽在开课吧广场Web教程频道。

有用
分享