JavaScript中layim之整合右键菜单的示例代码


Posted in Javascript onFebruary 06, 2021

一. 效果演示

1.1、好友右键菜单:

JavaScript中layim之整合右键菜单的示例代码

1.2、分组右键菜单:

JavaScript中layim之整合右键菜单的示例代码

1.3、群组右键菜单:

JavaScript中layim之整合右键菜单的示例代码

二. 实现教程

接下来我们以好友右键菜单为例,实现步骤如下:

2.1、绑定好友右击事件:

/* 绑定好友右击事件 */
$('body').on('mousedown', '.layim-list-friend li ul li', function(e){
 // 过滤非右击事件
 if(3 != e.which) {
 	return;
 }
	// 不再派发事件
	e.stopPropagation();
	
	var othis = $(this);
 // 获取好友编号,方便后期实现功能使用(需要修改layim.js源码绑定好友编号;或者直接截取class里的好友编号,可页面F12查看)
	var mineId = $(this).data('mineid');
	var uid = Date.now().toString(36);
	var space_icon = '  ';
	var space_text = '      ';
	var html = [
			'<ul id="contextmenu_'+uid+'" data-id="'+mineId+'" data-index="'+mineId+'" data-mold="1">',
			'<li data-type="menuChat"><i class="layui-icon" ></i>'+space_icon+'发送即时消息</li>',
			'<li data-type="menuProfile"><i class="layui-icon"></i>'+space_icon+'查看资料</li>',
			'<li data-type="menuHistory"><i class="layui-icon" ></i>'+space_icon+'消息记录</li>',
			'<li data-type="menuDelete">'+space_text+'删除好友</li>',
			'<li data-type="menuMoveto">'+space_text+'移动至</li></ul>'
		].join('');
	// 弹出窗体
 layer.tips(html, othis, {
  	tips: 1
  	,time: 0
  	,shift: 5
  	,fix: true
  	,skin: 'ayui-box layui-layim-contextmenu'
 });
});

在这里已经成功绑定了右击事件,但弹框直接挡住了好友的姓名头像,不太友好,如何优化呢,我们接着往下看。

JavaScript中layim之整合右键菜单的示例代码

2.2、重置弹框位置:
接下来我们在层弹出后的成功回调方法里面重置弹框位置,在默认弹框位置的基础上,左移一定的像素,而且根据弹框里li的数量动态向下移动,如果是回话底部弹框,则弹框整体向上移动。

layer.tips(html, othis, {
 	tips: 1
 	,time: 0
 	,shift: 5
 	,fix: true
 	,skin: 'ayui-box layui-layim-contextmenu'
 	,success: function(layero){
 		// -----#开始----------- 重置弹框位置 ----------------
 	var stopmp = function (e) { stope(e); };
 	layero.off('mousedowm',stopmp).on('mousedowm',stopmp);
 	var layerobj = $('#contextmenu_'+uid).parents('.layui-layim-contextmenu');
 		// 获取右击框li的数量
 	 var liCount = (html.split('</li>')).length;
 	 // 获取原来的弹框位置
		var top = layerobj.css('top').toLowerCase().replace('px','');
		var left = layerobj.css('left').toLowerCase().replace('px','');
		// 位置个性调整
		top = getTipTop(1, top, liCount);
		left = 30 + parseInt(left);
 	// 移动弹框位置
		layerobj.css({'width':'150px', 'left':left+'px', 'top':top+'px'});
		$('.layui-layim-contextmenu li').css({'padding-left':'18px'});
 		// -----#结束----------- 重置弹框位置 ----------------
 	}
});

// 获取窗口的文档显示区的高度
var currentHeight = getViewSizeWithScrollbar();
function getViewSizeWithScrollbar(){
	var clientHeight = 0;
	if(window.innerWidth){
		clientHeight = window.innerHeight;
	}else if(document.documentElement.offsetWidth == document.documentElement.clientWidth){ 
		clientHeight = document.documentElement.offsetHeight;
	}else{ 
		clientHeight = document.documentElement.clientHeight + getScrollWith();
	} 
	clientHeight = clientHeight-180;
	return clientHeight;
}

/**
 * 计算tip定位的高度
 * @param type 类型(1好友、群组,2分组)
 * @param top 原弹框高度
 * @param liCount 弹框层中li数量
 */
var getTipTop = function (type, top, liCount) {
	liCount--;
	if(top > (currentHeight-45*liCount)){
		top = parseInt(top) - 45;
	}else{
		if(type == 1){
			top = parseInt(top) + 30*liCount - 10;
		}else{
			top = parseInt(top) + 30*(liCount - 1);
		}
	}
	return top;
};

重置弹框位置后如图,是否美观大方很多了

JavaScript中layim之整合右键菜单的示例代码

2.3、优化右击弹框事件:
当用户操作其他功能时,右键弹框层依然存在于界面中,为了提高用户体验,以下监听鼠标事件以及鼠标滚轮事件,及时关闭右键弹框层。

// 阻止浏览器默认右键点击事件
document.oncontextmenu = function() {
 return false;
}
// 点击聊天主界面事件
$('body').on('click', '.layui-layim', function(e){
 emptyTips();
});
// 右击聊天主界面事件
$('body').on('mousedown', '.layui-layim', function(e){
 emptyTips();
});
// 监听鼠标滚轮事件
$('body').on('mousewheel DOMMouseScroll', '.layim-tab-content', function(e){
 emptyTips();
});
// 清空所有右击弹框
var emptyTips = function () {
	// 关闭右键菜单
 layer.closeAll('tips');
};

2.4、绑定右击菜单中选项的点击事件:
最后一步,绑定右击菜单中选项的点击事件,以“发送即时消息”为例子。

var $ = layui.jquery, active = {
	menuChat: function(){
		/*发送即时消息*/
	 var mineId = $(this).parent().data('id');
	 var moldId = $(this).parent().data('mold');
		console.log(mineId);
	 layim.chat({
			type: moldId == 1 ? "friend" : "group",
	 	name: '小焕',
			avatar: '好友头像,实际应用动态绑定',
			id: mineId,
			status: '好友当前离线状态'
		});
 },
 menuHistory: function(){
 	/*消息记录*/
		var mineId = $(this).parent().data('id');
	 var moldId = $(this).parent().data('mold');
		console.log(mineId);
 }
};
$('body').on('click', '.layui-layer-tips li', function(e){
 var type = $(this).data('type');
 active[type] ? active[type].call(this) : '';
	// 清空所有右击弹框
 emptyTips();
});

到这里,恭喜您,已经大功告成啦!

三. 最后附上完整代码

// 阻止浏览器默认右键点击事件
document.oncontextmenu = function() {
 return false;
}
// 单击聊天主界面事件
$('body').on('click', '.layui-layim', function(e){
 emptyTips();
});
// 右击聊天主界面事件
$('body').on('mousedown', '.layui-layim', function(e){
 emptyTips();
});
/* 监听鼠标滚轮事件 */
$('body').on('mousewheel DOMMouseScroll', '.layim-tab-content', function(e){
 emptyTips();
});
/* 绑定好友右击事件 */
$('body').on('mousedown', '.layim-list-friend li ul li', function(e){
	// 清空所有右击弹框
 emptyTips();
 if(3 != e.which) {
 	return;
 }
	// 不再派发事件
	e.stopPropagation();
	
	var othis = $(this);
 if (othis.hasClass('layim-null')) return;
 
	// 移除所有选中的样式
 $('.layim-list-friend li ul li').removeAttr("style","");
 // 标注为选中
 othis.css({'background-color':'rgba(0,0,0,.05)'});
 
	var mineId = $(this).data('mineid');
	var uid = Date.now().toString(36);
	var space_icon = '  ';
	var space_text = '      ';
 var html = [
  			'<ul id="contextmenu_'+uid + '" data-id="'+mineId+'" data-index="'+mineId+'" data-mold="1">',
  			'<li data-type="menuChat"><i class="layui-icon" ></i>'+space_icon+'发送即时消息</li>',
  			'<li data-type="menuProfile"><i class="layui-icon"></i>'+space_icon+'查看资料</li>',
  			'<li data-type="menuHistory"><i class="layui-icon" ></i>'+space_icon+'消息记录</li>',
  			'<li data-type="menuDelete">'+space_text+'删除好友</li>',
  			'<li data-type="menuMoveto">'+space_text+'移动至</li></ul>'
  		].join('');
 
 layer.tips(html, othis, {
  	tips: 1
  	,time: 0
  	,shift: 5
  	,fix: true
  	,skin: 'ayui-box layui-layim-contextmenu'
  	,success: function(layero){
  	 var liCount = (html.split('</li>')).length;
  	var stopmp = function (e) { stope(e); };
  	layero.off('mousedowm',stopmp).on('mousedowm',stopmp);
  	var layerobj = $('#contextmenu_'+uid).parents('.layui-layim-contextmenu');
  	// 移动弹框位置
 			var top = layerobj.css('top').toLowerCase().replace('px','');
 			var left = layerobj.css('left').toLowerCase().replace('px','');
 			top = getTipTop(1, top, liCount);
 			left = 30 + parseInt(left);
 			layerobj.css({'width':'150px', 'left':left+'px', 'top':top+'px'});
 			$('.layui-layim-contextmenu li').css({'padding-left':'18px'});
  	}
	});
});

// 清空所有右击弹框
var emptyTips = function () {
	// 移除所有好友选中的样式
 $('.layim-list-friend li ul li').removeAttr("style", "");
	// 移除所有群组选中的样式
 $('.layim-list-group li').removeAttr("style","");
	// 关闭右键菜单
 layer.closeAll('tips');
};

// 获取窗口的文档显示区的高度
var currentHeight = getViewSizeWithScrollbar();
function getViewSizeWithScrollbar(){
	var clientHeight = 0;
	if(window.innerWidth){
		clientHeight = window.innerHeight;
	}else if(document.documentElement.offsetWidth == document.documentElement.clientWidth){ 
		clientHeight = document.documentElement.offsetHeight;
	}else{ 
		clientHeight = document.documentElement.clientHeight + getScrollWith();
	} 
	clientHeight = clientHeight-180;
	return clientHeight;
}

/**
 *计算tip定位的高度
 * @param type 类型(1好友、群组,2分组)
 * @param top 原弹框高度
 * @param liCount 弹框层中li数量
 */
var getTipTop = function (type, top, liCount) {
	liCount--;
	if(top > (currentHeight-45*liCount)){
		top = parseInt(top) - 45;
	}else{
		if(type == 1){
			top = parseInt(top) + 30*liCount - 10;
		}else{
			top = parseInt(top) + 30*(liCount - 1);
		}
	}
	return top;
};

// 绑定右击菜单中选项的点击事件
var $ = layui.jquery, active = {
	menuChat: function(){
		/*发送即时消息*/
	 var mineId = $(this).parent().data('id');
	 var moldId = $(this).parent().data('mold');
		console.log(mineId);
	 layim.chat({
			type: moldId == 1 ? "friend" : "group",
	 	name: '小焕',
			avatar: '好友头像,实际应用动态绑定',
			id: mineId,
			status: '好友当前离线状态'
		});
 },
 menuHistory: function(){
 	/*消息记录*/
		var mineId = $(this).parent().data('id');
	 var moldId = $(this).parent().data('mold');
		console.log(mineId);
 }
};
$('body').on('click', '.layui-layer-tips li', function(e){
 var type = $(this).data('type');
 active[type] ? active[type].call(this) : '';
	// 清空所有右击弹框
	emptyTips();
});

四. 其他右击菜单代码扩展

4.1、分组右键菜单:

/* 绑定分组右击事件 */
$('body').on('mousedown', '.layim-list-friend li h5', function(e){
	// 清空所有右击弹框
 emptyTips();
 if(3 != e.which) {
 	return;
 }
	// 不再派发事件
	e.stopPropagation();
	
	var othis = $(this);
 if (othis.hasClass('layim-null')) return;
 
 var groupId = othis.data('groupid');
	var uid = Date.now().toString(36);
	var space_icon = '  ';
	var space_text = '      ';
	
	var html = [
  			'<ul id="contextmenu_'+uid+'" data-id="'+groupId+'" data-index="'+groupId +'">',
  			'<li data-type="menuReset"><i class="layui-icon" ></i>'+space_icon+'刷新好友列表</li>',
  			// '<li data-type="menuOnline"><i class="layui-icon">စ</i>'+space_icon+'显示在线好友</li>',
  			'<li data-type="menuInsert">'+space_text+'添加分组</li>',
  			'<li data-type="menuRename">'+space_text+'重命名</li>',
  			'<li data-type="menuRemove" data-mold="1">'+space_text+'删除分组</li></ul>',
  		].join('');
	
 layer.tips(html, othis, {
 	tips: 1
 	,time: 0
 	,shift: 5
 	,fix: true
 	,skin: 'ayui-box layui-layim-contextmenu'
 	,success: function(layero){
 	 var liCount = (html.split('</li>')).length;
	  	var stopmp = function (e) { stope(e); };
	  	layero.off('mousedowm',stopmp).on('mousedowm',stopmp);
	  	var layerobj = $('#contextmenu_'+uid).parents('.layui-layim-contextmenu');
	  	// 移动弹框位置
			var top = layerobj.css('top').toLowerCase().replace('px','');
			var left = layerobj.css('left').toLowerCase().replace('px','');
			top = getTipTop(2, top, liCount);
			left = 30 + parseInt(left);
			layerobj.css({'width':'150px', 'left':left+'px', 'top':top+'px'});
			$('.layui-layim-contextmenu li').css({'padding-left':'18px'});
 	}
 });
});

4.2、好友列表空白地方右键菜单:

/* 绑定好友列表空白地方右击事件 */
$('body').on('mousedown', '.layim-list-friend', function(e){
	// 清空所有右击弹框
 emptyTips();
 if(3 != e.which) {
 	return;
 }
	// 不再派发事件
	e.stopPropagation();

	var othis = $(this);
 if (othis.hasClass('layim-null')) return;
  
	var uid = Date.now().toString(36);
	var space_icon = '  ';
	var space_text = '      ';
	var html = [
  			'<ul id="contextmenu_'+uid+'">',
  			'<li data-type="menuReset"><i class="layui-icon" ></i>'+space_icon+'刷新好友列表</li>',
  			'<li data-type="menuInsert">'+space_text+'添加分组</li></ul>',
  		].join('');
  
 layer.tips(html, othis, {
 	tips: 1
 	,time: 0
 	,shift: 5
 	,fix: true
 	,skin: 'ayui-box layui-layim-contextmenu'
 	,success: function(layero){
 	 var liCount = (html.split('</li>')).length;
	  	var stopmp = function (e) { stope(e); };
	  	layero.off('mousedowm',stopmp).on('mousedowm',stopmp);
	  	var layerobj = $('#contextmenu_'+uid).parents('.layui-layim-contextmenu');
	  	var top = e.pageY;
	  	var left = e.pageX;
	  	var screenWidth = window.screen.width;
	  	// 根据实体情况调整位置
	  	if(screenWidth-left > 150){
	  		left = left - 30;
	  	}else if(screenWidth-left < 110){
	  		left = left - 180;
	  	}else{
	  		left = left - 130;
	  	}
	  	if(top > 816){
				top = top - 140;
	  	}else{
				top = top - 60;
	  	}
			layerobj.css({'width':'150px', 'left':left+'px', 'top':top+'px'});
			$('.layui-layim-contextmenu li').css({'padding-left':'18px'});
 	}
 });
});

JavaScript中layim之整合右键菜单的示例代码

4.3、群组右键菜单:

/* 绑定群聊右击事件 */
$('body').on('mousedown', '.layim-list-group li', function(e){
	// 清空所有右击弹框
 emptyTips();
 if(3 != e.which) {
 	return;
 }
	// 不再派发事件
	e.stopPropagation();
	
	var othis = $(this);
 if (othis.hasClass('layim-null')) return;
  
	// 移除所有选中的样式
 $('.layim-list-group li').removeAttr("style","");
 // 标注为选中
 othis.css({'background-color':'rgba(0,0,0,.05)'});
	
	var mineId = $(this).data('mineid');
	var uid = Date.now().toString(36);
	var space_icon = '  ';
	var space_text = '      ';
	var html = [
			'<ul id="contextmenu_'+uid+'" data-id="'+mineId+'" data-index="'+mineId+'" data-mold="2">',
			'<li data-type="menuChat"><i class="layui-icon" ></i>'+space_icon+'发送群消息</li>',
			'<li data-type="menuProfile"><i class="layui-icon"></i>'+space_icon+'查看群资料</li>',
			'<li data-type="menuHistory"><i class="layui-icon" ></i>'+space_icon+'消息记录</li>',
			'<li data-type="menuUpdate">'+space_text+'修改群图标</li>',
			'<li data-type="menuRemove" data-mold="2">'+space_text+'解散该群</li>',
			'<li data-type="menuSecede">'+space_text+'退出该群</li></ul>',
		].join('');
layer.tips(html, othis, {
 	tips: 1
 	,time: 0
 	,shift: 5
 	,fix: true
 	,skin: 'ayui-box layui-layim-contextmenu'
 	,success: function(layero){
 	 var liCount = (html.split('</li>')).length;
 	var stopmp = function (e) { stope(e); };
 	layero.off('mousedowm',stopmp).on('mousedowm',stopmp);
 	var layerobj = $('#contextmenu_'+uid).parents('.layui-layim-contextmenu');
 	// 移动弹框位置
		var top = layerobj.css('top').toLowerCase().replace('px','');
		var left = layerobj.css('left').toLowerCase().replace('px','');
		top = getTipTop(1, top, liCount);
		left = 30 + parseInt(left);
		layerobj.css({'width':'150px', 'left':left+'px', 'top':top+'px'});
		$('.layui-layim-contextmenu li').css({'padding-left':'18px'});
 	}
});

4.4、群组列表空白地方右键菜单:

/* 绑定群聊空白地方右击事件 */
$('body').on('mousedown', '.layim-list-groups', function(e){
	// 清空所有右击弹框
 emptyTips();
 if(3 != e.which) {
 	return;
 }
	// 不再派发事件
	e.stopPropagation();

	var othis = $(this);
 if (othis.hasClass('layim-null')) return;
 
	var uid = Date.now().toString(36);
	var space_icon = '  ';
	var space_text = '      ';
	var html = [
  			'<ul id="contextmenu_'+uid+'">',
  			'<li data-type="menuResetGroup"><i class="layui-icon" ></i>'+space_icon+'刷新群聊列表</li>',
  			'<li data-type="menuInsertGroup">'+space_text+'创建群聊</li></ul>',
  		].join('');
  
	layer.tips(html, othis, {
		tips: 1
		,time: 0
		,shift: 5
		,fix: true
		,skin: 'ayui-box layui-layim-contextmenu'
		,success: function(layero){
		 var liCount = (html.split('</li>')).length;
			var stopmp = function (e) { stope(e); };
			layero.off('mousedowm',stopmp).on('mousedowm',stopmp);
			var layerobj = $('#contextmenu_'+uid).parents('.layui-layim-contextmenu');
			var top = e.pageY;
			var left = e.pageX;
			var screenWidth = window.screen.width;
			if(screenWidth-left > 150){
				left = left - 30;
			}else if(screenWidth-left < 110){
				left = left - 180;
			}else{
				left = left - 130;
			}
			if(top > 816){
				top = top - 140;
			}else{
				top = top - 60;
			}
			layerobj.css({'width':'150px', 'left':left+'px', 'top':top+'px'});
			$('.layui-layim-contextmenu li').css({'padding-left':'18px'});
		}
	});
});

JavaScript中layim之整合右键菜单的示例代码

五. 总结

出于兴趣,对即时通讯挺好奇的,然后就开始接触layim,一开始每做一个功能都会遇到各种小问题,对于我来说,遇到问题若是不能及时解决,当晚便会一夜未眠,只能不断寻找资料,阅读源码,最终还是能摘到蜜甜的果实。实现功能时参考过网上大牛的博文,因此如有类同请提醒一下晚辈!
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。

到此这篇关于JavaScript中layim之整合右键菜单的示例代码的文章就介绍到这了,更多相关layim整合右键菜单内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
document.documentElement &amp;&amp; document.documentElement.scrollTop
Dec 01 Javascript
Javascript异步编程模型Promise模式详细介绍
May 08 Javascript
JavaScript中用getDate()方法返回指定日期的教程
Jun 09 Javascript
使用Jasmine和Karma对AngularJS页面程序进行测试
Mar 05 Javascript
javascript实现仿百度图片的瀑布流加载效果
Apr 20 Javascript
easyui messager alert 三秒后自动关闭提示的实例
Nov 07 Javascript
jQuery操作json常用方法示例
Jan 04 Javascript
Vue2.0用户权限控制解决方案
Nov 29 Javascript
vuejs router history 配置到iis的方法
Sep 20 Javascript
小程序视频或音频自定义可拖拽进度条的示例代码
Sep 30 Javascript
代码实例ajax实现点击加载更多数据图片
Oct 12 Javascript
微信小程序 确认框的实现(附代码)
Jul 23 Javascript
vue 根据选择的月份动态展示日期对应的星期几
Feb 06 #Vue.js
解决vue项目本地启动时无法携带cookie的问题
Feb 06 #Vue.js
如何封装Vue Element的table表格组件
Feb 06 #Vue.js
Vue实现圆环进度条的示例
Feb 06 #Vue.js
javascript实现数字时钟效果
Feb 06 #Javascript
JavaScript WeakMap使用详解
Feb 05 #Javascript
JavaScript 声明私有变量的两种方式
Feb 05 #Javascript
You might like
php面向对象全攻略 (十二) 抽象方法和抽象类
2009/09/30 PHP
PHP函数之error_reporting(E_ALL ^ E_NOTICE)详细说明
2011/07/01 PHP
php Smarty初体验二 获取配置信息
2011/08/08 PHP
PHP使用ob_start生成html页面的方法
2014/11/07 PHP
PHP发送邮件确认验证注册功能示例【修改别人邮件类】
2019/11/09 PHP
雄兵连第三季海报曝光,艾妮熙德成主角,蔷薇新造型
2021/03/09 国漫
JavaScript实现统计文本框Textarea字数增强用户体验
2012/12/21 Javascript
javascript判断机器是否联网的2种方法
2013/08/09 Javascript
JQuery操作单选按钮以及复选按钮示例
2013/09/23 Javascript
Javascript中call和apply函数的比较和使用实例
2015/02/03 Javascript
Bootstrap按钮下拉菜单组件详解
2016/05/10 Javascript
使用JS批量选中功能实现更改数据库中的status状态值(批量展示)
2016/11/22 Javascript
jQuery设置图片等比例缩小的方法
2017/04/29 jQuery
vue中for循环更改数据的实例代码(数据变化但页面数据未变)
2017/09/15 Javascript
基于iScroll实现内容滚动效果
2018/03/21 Javascript
使用vue2.0创建的项目的步骤方法
2018/09/25 Javascript
js实现随机点名程序
2020/09/17 Javascript
Vue+Vuex实现自动登录的知识点详解
2020/03/04 Javascript
[07:08]2014DOTA2西雅图国际邀请赛 小组赛7月11日TOPPLAY
2014/07/11 DOTA
Python基于scapy实现修改IP发送请求的方法示例
2017/07/08 Python
Python实现按学生年龄排序的实际问题详解
2017/08/29 Python
修复 Django migration 时遇到的问题解决
2018/06/14 Python
django中账号密码验证登陆功能的实现方法
2019/07/15 Python
python实现3D地图可视化
2020/03/25 Python
Django实现微信小程序支付的示例代码
2020/09/03 Python
Footshop乌克兰:运动鞋的最大选择
2019/12/01 全球购物
JBL加拿大官方商店:扬声器、耳机等
2020/10/23 全球购物
幼儿园庆六一游园活动方案
2014/01/29 职场文书
师范教师专业大学生职业生涯规划范文
2014/03/02 职场文书
购房协议书范本
2014/04/11 职场文书
面试自我介绍演讲稿
2014/04/29 职场文书
素质教育标语
2014/06/27 职场文书
个人主要事迹材料
2014/08/26 职场文书
公司中层管理培训心得体会
2016/01/11 职场文书
CSS3通过var()和calc()函数实现动画特效
2021/03/30 HTML / CSS
Mysql中 unique列插入重复值该怎么解决呢
2021/05/26 MySQL