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 相关文章推荐
基于jQuery制作迷你背词汇工具
Jul 27 Javascript
详解JavaScript表单验证(E-mail 验证)
Mar 31 Javascript
JS/jQuery判断DOM节点是否存在的简单方法
Nov 24 Javascript
jQuery实现最简单实用的分秒倒计时
Feb 05 Javascript
JS实现线性表的链式表示方法示例【经典数据结构】
Apr 11 Javascript
从零开始学习Node.js系列教程六:EventEmitter发送和接收事件的方法示例
Apr 13 Javascript
BootStrap表单时间选择器详解
May 09 Javascript
详解webpack和webpack-simple中如何引入css文件
Jun 28 Javascript
js移动端图片压缩上传功能
Aug 18 Javascript
Vue组件和Route的生命周期实例详解
Feb 10 Javascript
微信小程序间使用navigator跳转传值问题实例分析
Mar 27 Javascript
从0到1学习JavaScript编写贪吃蛇游戏
Jul 28 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使用CURL实现对带有验证码的网站进行模拟登录的方法
2014/07/23 PHP
PHP实现登录搜狐广告获取广告联盟数据的方法【附demo源码】
2016/10/14 PHP
php 查找数组元素提高效率的方法详解
2017/05/05 PHP
详解PHP处理字符串类似indexof的方法函数
2017/06/11 PHP
JavaScript入门教程(8) Location地址对象
2009/01/31 Javascript
可以用来调试JavaScript错误的解决方案
2010/08/07 Javascript
js TextArea的选中区域处理
2010/12/28 Javascript
从数组中随机取x条不重复数据的JS代码
2013/12/24 Javascript
JQuery仿小米手机抢购页面倒计时效果
2014/12/16 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
2016/05/31 Javascript
vue mintui-Loadmore结合实现下拉刷新和上拉加载示例
2017/10/12 Javascript
VueJs 将接口用webpack代理到本地的方法
2017/11/27 Javascript
ant design实现圈选功能
2019/12/17 Javascript
如何在JavaScript中创建具有多个空格的字符串?
2020/02/23 Javascript
Python GAE、Django导出Excel的方法
2008/11/24 Python
Web服务器框架 Tornado简介
2014/07/16 Python
Python中的exec、eval使用实例
2014/09/23 Python
Python装饰器decorator用法实例
2014/11/10 Python
Python中pow()和math.pow()函数用法示例
2018/02/11 Python
shell命令行,一键创建 python 模板文件脚本方法
2018/03/20 Python
如何基于python实现脚本加密
2019/12/28 Python
python 获取当前目录下的文件目录和文件名实例代码详解
2020/03/10 Python
python中把元组转换为namedtuple方法
2020/12/09 Python
利用CSS3实现文本框的清除按钮相关的一些效果
2015/06/23 HTML / CSS
纽约通行卡:The New York Pass(免费游览纽约90多个景点)
2017/07/29 全球购物
有趣、实用和鼓舞人心的产品:Inspire Uplift
2019/11/05 全球购物
Ibatis如何使用动态表名
2015/07/12 面试题
SQL Server 2000数据库的文件有哪些,分别进行描述
2013/03/30 面试题
餐饮管理自我介绍信
2014/01/15 职场文书
城建学院毕业生自荐信
2014/01/31 职场文书
战略合作意向书范本
2014/04/01 职场文书
员工激励培训演讲稿
2014/09/16 职场文书
2015年全民国防教育日活动总结
2015/03/23 职场文书
2015年食堂工作总结报告
2015/04/23 职场文书
高中数学教学反思范文
2016/02/18 职场文书
MySQL 数据类型选择原则
2021/05/27 MySQL