Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 616|回复: 0

[对smartMenu.js改进] 解决右键菜单栏在边缘弹出后,移出视图区域无法操作的问题

[复制链接]
  • TA的每日心情
    奋斗
    4 天前
  • 签到天数: 802 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726006
    发表于 2021-7-7 09:56:09 | 显示全部楼层 |阅读模式

    当用户在视图边缘(如右下角)右键召唤菜单栏的时候,菜单仍然从选中元素的右下角弹出,这时二级菜单栏一般都离开了视图区域,用户无法进一步操作。

    这个问题挺常见的,原作者的留言板:

     但是作者应该是已经不再维护了,最后一个版本还是2011年10月的。

    我给出的比较初步的解决方案:

    因为作者没有给出鼠标事件的接口,只能在库的源码中修改坐标计算逻辑,以达到根据位置自适应弹出菜单的目的。

    思路:判断右键点击位置,与窗口(我的是iframe窗口)大小作比较,取中心点分为坐标系的四个象限。

      1、在第一象限召唤菜单栏,显示在触发事件元素的左下角

      2、在第二象限召唤菜单栏,显示在触发事件元素的左上角

      3、在第三象限召唤菜单栏,显示在触发事件元素的右上角

      4、在第四象限召唤菜单栏,显示在触发事件元素的右下角

    完整的代码如下:

    /*
     * smartMenu.js 智能上下文菜单插件
     * http://www.zhangxinxu.com/
     *
     * Copyright 2011, zhangxinxu
     *
     * 2011-05-26 v1.0    编写
     * 2011-06-03 v1.1    修复func中this失准问题
     * 2011-10-10 v1.2  修复脚本放在<head>标签中层无法隐藏的问题
     * 2011-10-30 v1.3  修复IE6~7下二级菜单移到第二项隐藏的问题
     */
     
    (function($) {
        var D = $(document).data("func", {});    
        $.smartMenu = $.noop;
        $.fn.smartMenu = function(data, options) {
            var B = $("body"), defaults = {
                name: "",
                offsetX: 2,
                offsetY: 2,
                textLimit: 6,
                beforeShow: $.noop,
                afterShow: $.noop
            };
            var params = $.extend(defaults, options || {});
            
            var htmlCreateMenu = function(datum) {
                var dataMenu = datum || data, nameMenu = datum? Math.random().toString(): params.name, htmlMenu = "", htmlCorner = "", clKey = "smart_menu_";
                if ($.isArray(dataMenu) && dataMenu.length) {
                    htmlMenu = '<div id="smartMenu_'+ nameMenu +'" class="'+ clKey +'box">' +
                                    '<div class="'+ clKey +'body">' +
                                        '<ul class="'+ clKey +'ul">';
                                        
                    $.each(dataMenu, function(i, arr) {
                        if (i) {
                            htmlMenu = htmlMenu + '<li class="'+ clKey +'li_separate">&nbsp;</li>';    
                        }
                        if ($.isArray(arr)) {
                            $.each(arr, function(j, obj) {
                                var text = obj.text, htmlMenuLi = "", strTitle = "", rand = Math.random().toString().replace(".", "");
                                if (text) {
                                    if (text.length > params.textLimit) {
                                        text = text.slice(0, params.textLimit)    + "";
                                        strTitle = ' title="'+ obj.text +'"';
                                    }
                                    if ($.isArray(obj.data) && obj.data.length) {
                                        htmlMenuLi = '<li class="'+ clKey +'li" data-hover="true">' + htmlCreateMenu(obj.data) +
                                            '<a href="javascript:" class="'+ clKey +'a"'+ strTitle +' data-key="'+ rand +'"><i class="'+ clKey +'triangle"></i>'+ text +'</a>' + 
                                        '</li>';
                                    } else {
                                        htmlMenuLi = '<li class="'+ clKey +'li">' +
                                            '<a href="javascript:" class="'+ clKey +'a"'+ strTitle +' data-key="'+ rand +'">'+ text +'</a>' + 
                                        '</li>';
                                    }
                                    
                                    htmlMenu += htmlMenuLi;
                                    
                                    var objFunc = D.data("func");
                                    objFunc[rand] = obj.func;
                                    D.data("func", objFunc);
                                }
                            });    
                        }
                    });
                    
                    htmlMenu = htmlMenu + '</ul>' +
                                        '</div>' +
                                    '</div>';
                }
                return htmlMenu;
            }, funSmartMenu = function() {
                var idKey = "#smartMenu_", clKey = "smart_menu_", jqueryMenu = $(idKey + params.name);
                if (!jqueryMenu.size()) {
                    $("body").append(htmlCreateMenu());
                    
                    //事件
                    $(idKey + params.name +" a").bind("click", function() {
                        var key = $(this).attr("data-key"),
                            callback = D.data("func")[key];
                        if ($.isFunction(callback)) {
                            callback.call(D.data("trigger"));    
                        }
                        $.smartMenu.hide();
                        return false;
                    });
                    $(idKey + params.name +" li").each(function() {
                        var isHover = $(this).attr("data-hover"), clHover = clKey + "li_hover";
                        
                        $(this).hover(function() {
                            var jqueryHover = $(this).siblings("." + clHover);
                            jqueryHover.removeClass(clHover).children("."+ clKey +"box").hide();
                            jqueryHover.children("."+ clKey +"a").removeClass(clKey +"a_hover");
                            
                            if (isHover) {                    
                                $(this).addClass(clHover).children("."+ clKey +"box").show();
                                $(this).children("."+ clKey +"a").addClass(clKey +"a_hover");    
                            }
                            
                        });
                        
                    });
                    return $(idKey + params.name);
                } 
                return jqueryMenu;
            };
            
            $(this).each(function() {
                this.oncontextmenu = function(e) {
                    //回调
                    if ($.isFunction(params.beforeShow)) {
                        params.beforeShow.call(this);    
                    }
                    e = e || window.event;
                    //阻止冒泡
                    e.cancelBubble = true;
                    if (e.stopPropagation) {
                        e.stopPropagation();
                    }
                    //隐藏当前上下文菜单,确保页面上一次只有一个上下文菜单
                    $.smartMenu.hide();
                    var st = D.scrollTop();
                    var jqueryMenu = funSmartMenu();
                    if (jqueryMenu) {
                        /* 2017.12.4修改:根据触发事件的位置,自适应方向弹出 */ if( e.clientX <= (e.view.innerWidth/2) && e.clientY <= (e.view.innerHeight/2))//左上 { jqueryMenu.css({ display: "block", left: e.clientX + params.offsetX , top: e.clientY + st + params.offsetY , }); } if( e.clientX >= (e.view.innerWidth/2) && e.clientY <= (e.view.innerHeight/2))//右上 { jqueryMenu.css({ display: "block", left: e.clientX + params.offsetX -100, top: e.clientY + st + params.offsetY , }); } if( e.clientX <= (e.view.innerWidth/2) && e.clientY >= (e.view.innerHeight/2))//左下 { jqueryMenu.css({ display: "block", left: e.clientX + params.offsetX , top: e.clientY + st + params.offsetY -120, }); } if( e.clientX >= (e.view.innerWidth/2) && e.clientY >= (e.view.innerHeight/2))//右下 { jqueryMenu.css({ display: "block", left: e.clientX + params.offsetX -100, top: e.clientY + st + params.offsetY -120, }); }
                        D.data("target", jqueryMenu);
                        D.data("trigger", this);
                        //回调
                        if ($.isFunction(params.afterShow)) {
                            params.afterShow.call(this);    
                        }
                        return false;
                    }
                };
            });
            if (!B.data("bind")) {
                B.bind("click", $.smartMenu.hide).data("bind", true);
            }
        };
        $.extend($.smartMenu, {
            hide: function() {
                var target = D.data("target");
                if (target && target.css("display") === "block") {
                    target.hide();
                }        
            },
            removeevent: function (event) {
                var target = D.data("target");
                if (target) {
                    target.remove();
                    if ($.isFunction(event)) {
                        event.call(this);
                    }
                }
            },
            remove: function() {
                var target = D.data("target");
                if (target) {
                    target.remove();
                }
            }
        });
    })(jQuery);

    修改之后的效果:

    在右下方召唤

    在左下方召唤

    在左上方召唤

    在右上方召唤

    大概效果就是这样了,经过测试,菜单栏不会弹到视窗外面了。

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-11-15 02:07 , Processed in 3.864107 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表