JavaScript中layim之整合右键菜单的示例代码
作者:踮脚敲代码 发布时间:2024-04-18 09:42:29
标签:js,layim,右键菜单
一. 效果演示
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] ? 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'});
}
});
});
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,一开始每做一个功能都会遇到各种小问题,对于我来说,遇到问题若是不能及时解决,当晚便会一夜未眠,只能不断寻找资料,阅读源码,最终还是能摘到蜜甜的果实。实现功能时参考过网上大牛的博文,因此如有类同请提醒一下晚辈!
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
来源:https://blog.csdn.net/ii950606/article/details/106216840


猜你喜欢
- 大家好,我是辣条。辣条的一个朋友最近跟我诉苦:女朋友沉迷淘宝抢购无法自拔,大晚上不睡觉都在定时抢购,真是败家。都是好朋友辣条肯定帮忙,不就是
- 最近重温了一下位图分割的相关内容,发现网络上位图分割原理讲得已经很清楚了,但是代码多为C++实现或者Matlab实现,因为需要Python的
- 这篇文档所给出的编码约定适用于在主要的Python发布版本中组成标准库的Python 代码,请查阅相关的关
- 一个写给别人的小代码顺便也贴上来这是一个滑动展示用的小容器通过鼠标移动和离开触发滑动效果<!DOCTYPE html PUBLIC &
- BrowserPlus 到底是什么,又能做什么?BrowserPlus 是 Yahoo! 最近刚发布一个 Web 扩展的平台:终端用户需安装
- 业务场景因为项目刚上线,目前暂不打算引入其他中间件,所以打算通过 mysql 来实现分布式读写锁;而该业务场景也满足分布式读写锁的场景,抽象
- 1,jdk配置由于jdk官网的链接不直接支持wget,可以使用下面的方法下载jdk,其中jdk版本为jdk1.8.0_91:wget --n
- 图片的间隙Q:我有一张大图片,把它切割后在Dreamweaver中进行拼接,可是总是有间隙,不知为什么?A:不知你是否把表格的边距、间距和边
- 多表连接的基本语法多表连接,就是将几张表拼接为一张表,然后进行查询select 字段1, 字段2, ...from 表1 {inner|li
- 1.介绍PDF 格式是与平台无关,它独立于底层操作系统和渲染引擎。事实上,PDF 是基于一种脚本语言—&mdas
- 在js中一切都是对象,连函数也是对象,函数名其实是引用函数定义对象的变量。1、什么是arguments?这个函数体内的arguments非常
- 入职第一家公司做开发的时候使用的项目版本管理工具是svn,公司内部搭建的服务器;在第二、第三家公司做开发的时候,使用的项目版本管理工具是Gi
- 实例如下所示:from pandas import *from random import *df = DataFrame(columns=
- HTTP上传的文件的原理HTTP协议的文件上传是通过HTTP POST请求实现的,使用multipart/form-data格式将待上传的文
- 使用perl连接mysql,这个网上有很多案例了,一般大家都是DBI下的DBD::MySQL这个模块进行.这里做一个mask弄一个TIPS:
- 1. 内部重构#2. 外部重构#website/blog/urls.pywebsite/website/urls.py3. 两种参数处理方式
- 这个是很有用的一个运算,除了本身可以求自然对数,还是求指数函数需要用到的基础函数。实现原理就是泰勒展开,最简单是在x=1处进行泰勒展开:但该
- 今天使用os.path.isdir()判断是否是文件夹的时候发现一个问题:lst = os.listdir(path) &nb
- Mysql现在是大多数公司企业在用的数据库,之所以用Mysql,一点是因为Mysql是开源软件,一些有能力的公司会基于已有的Mysql架构,
- arguments.callee关于callee的解释:callee 是 arguments 对象的一个属性。可以用于引用该函数的函数体内当