分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

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

发布时间:2023-09-06 01:28责任编辑:董明明关键词:js

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

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

 但是作者应该是已经不再维护了,最后一个版本还是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);

修改之后的效果:

在右下方召唤

在左下方召唤

在左上方召唤

在右上方召唤

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

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

原文地址:http://www.cnblogs.com/xiaozhaoqi/p/7978195.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved