一. 效果演示
1.1、好友右键菜单:
1.2、分组右键菜单:
1.3、群组右键菜单:
二. 实现教程
接下来我们以好友右键菜单为例,实现步骤如下:
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' }); });
在这里已经成功绑定了右击事件,但弹框直接挡住了好友的姓名头像,不太友好,如何优化呢,我们接着往下看。
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; };
重置弹框位置后如图,是否美观大方很多了
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] "htmlcode">// 阻止浏览器默认右键点击事件 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] "htmlcode">/* 绑定分组右击事件 */ $('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'}); } }); });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'}); } }); });五. 总结
出于兴趣,对即时通讯挺好奇的,然后就开始接触layim,一开始每做一个功能都会遇到各种小问题,对于我来说,遇到问题若是不能及时解决,当晚便会一夜未眠,只能不断寻找资料,阅读源码,最终还是能摘到蜜甜的果实。实现功能时参考过网上大牛的博文,因此如有类同请提醒一下晚辈!
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新动态
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]