`
lgx2351
  • 浏览: 175933 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

grid里用右键来实现功能菜单

阅读更多

在自定义grid中,如果一个grid的列很多,窗口无法显示这么长的内容,且我们一般把grid每一行按操作按钮(如编辑删除按钮)放在每一行的最后一列。这时候用户要要操作某一行的数据,如要做“删除”操作时,就要用鼠标拉动水平滚动条,拉动到能看到最后一列的时候再进行点击操作。这就显得比较麻烦了。这时候,右键某一行,把这行最后的按钮内容构造成右键的显示内容,就可以方便地进行操作了。

整体的思路:create一个div,把grid行最后的按钮内容构造成右键的内容,执行最后一行的按钮的onclick事件即可。

主要的代码如下:

/**
 * 构造grid的右键菜单 
 * author:liugx
 */
//orgCellColor存放点击行的原始颜色值
ConRightMenu.orgCellColor = "";
ConRightMenu.clickRow = "";
function ConRightMenu(){
}
ConRightMenu.prototype ={
	cancelRight:function(){
		event.returnValue=false;   
	  	event.cancelBubble=true; 
	},
	getEventElement:function(clickObject){
		var evt = Event.getEvent();
		return (evt)?(event.target || event.srcElement):clickObject;	
	},
	getTrObj:function(){
		var oCh = "";
		try {
			if(DOMModel.type()==1){
				oCh = conRightMenu.getEventElement().parentElement;
			}else if(DOMModel.type()==2){
				oCh = Event.findElement(evt,"tr");
			}
		}catch(e){
			_alert(e.message);
			return "";
		}
		return oCh;
	},
	changeClassForTD:function(trObj){
		//先清空其它的td底色
		if(trObj.parentElement){
			var allTDObj = trObj.parentElement.getElementsByTagName("TD");
			for(var j=0;j<allTDObj.length;j++){
				if(allTDObj[j].style.backgroundColor.toUpperCase()=='#DCDCDC'.toUpperCase()){
					allTDObj[j].style.backgroundColor = ConRightMenu.orgCellColor;
				}
			}
		}
		var trChildNodes =  trObj.childNodes;
		//设置tr的底色
		for(var i=0;i<trChildNodes.length;i++){
			if(i==0){
				ConRightMenu.orgCellColor = trChildNodes[i].style.backgroundColor;
			}
			trChildNodes[i].style.backgroundColor = '#DCDCDC';
		}
	},
	buttonClickFun:function(itemId){
		var trObj = $(ConRightMenu.clickRow);
		if(trObj){
			var childNodes =  trObj.lastChild.childNodes;
			for(var i=0;i<childNodes.length;i++){
				if(childNodes[i].id == itemId){
					childNodes[i].fireEvent("onclick");
				}
			}
		}
	},
	consButtonHtml:function(trObj){
	  	var result = "";
	  	result += "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";
	  	var childNodes = trObj.lastChild.childNodes;
	  	var childNodesLen = childNodes.length;
	  	for(var i=0;i<childNodesLen;i++){
	  		var outerHtml = childNodes[i].outerHTML;
	  		var onclickHtml = outerHtml.substring(outerHtml.indexOf("onclick"),outerHtml.length-1);
	  		var itemId = childNodes[i].id;
	  		result += "<tr onmouseover='this.className=\"mouseOverGrid\";' onmouseout='this.className=\"mouseOutGrid\";'";
	  		result += " onclick='conRightMenu.buttonClickFun(\""+itemId+"\");";
	  		result += "$(\"right_reslut_div\").style.display=\"none\"'><td>";
	  		var tdImg = document.createElement('img');
	  		var tdImgUrl = childNodes(i).currentStyle.backgroundImage.replace("url(\"","");
	  		tdImgUrl = tdImgUrl.replace("\")","");
	  		tdImg.src = tdImgUrl;
	  		result += tdImg.outerHTML;
	  		result += "</td><td>"+childNodes[i].title+"</td></tr>";
	  		if(i<childNodesLen-1){
		  		result += "<tr><td colspan='2'><div class='rowSplit'></div></td></tr>";
	  		}
		}
		result += "</table>";
		return result;
	},
	buildRightMenu:function(){
		conRightMenu.cancelRight();
		var trObj = conRightMenu.getTrObj();
		if(trObj){
			ConRightMenu.clickRow = trObj.id;
	        var buttonHtml = conRightMenu.consButtonHtml(trObj);
			if(!$("right_reslut_div")){
				var right_res_div = document.createElement('div');
				right_res_div.id = "right_reslut_div";
			}else{
				right_res_div = $("right_reslut_div");
			}	
			right_res_div.innerHTML = buttonHtml;
			right_res_div.style.background = '#DCDCDC';
			right_res_div.style.padding = "1 1 1 1";
			right_res_div.style.border  = "solid #C0C0C0 1px";
			right_res_div.style.position = 'absolute';
			right_res_div.style.left = event.clientX  + geometry.getHorizontalScroll() + 'px';
			right_res_div.style.top = event.clientY + geometry.getVerticalScroll() + 'px';
			right_res_div.style.width = 100 +'px';
			right_res_div.style.height = trObj.lastChild.childNodes.length*18 +'px';
			if(!$("right_reslut_div")){
				document.body.appendChild(right_res_div);
			}
			right_res_div.style.display = '';
			
			conRightMenu.changeClassForTD(trObj);
		}
	},
	display_right_div:function(){
		if($("right_reslut_div")){
			if($("right_reslut_div").style.display==''){
				$("right_reslut_div").innerHTML = '';
				$("right_reslut_div").style.display = 'none';
			}
		}
	}
}
var conRightMenu = new ConRightMenu();

 分析以上代码如下:

1、

//orgCellColor存放点击行的原始颜色值
ConRightMenu.orgCellColor = "";
ConRightMenu.clickRow = "";

orgCellColor和clickRow分别存储的是点击行的原始背景颜色值和点击行的id,前者的作用是右键点击某一行设置了这行的背景值后再右键点击另一行时,把之前的那行的原始背景值再赋值给它;后者是得到点击某行的id值,这在设置右键按钮的事件中有很重要的作用。因为右键后显示的div的按钮与grid的按钮是不一样的,如果前者的onclick事件也和后者一样执行一个函数的话,那么是不行的。因为grid的按钮执行的函数里用到的event.srcElement等有关event事件的元素都与右键div的按钮的event事件的元素不一样,如果右键div的按钮执行grid的按钮的函数,就会出错。所以,我们解决方法是执行grid按钮的fireEvent("onclick")方法。这就要求能够取得到右键点击grid那行的按钮元素。通过clickRow得到tr的id,就可以定位到点击grid的那行的每个按钮元素了。可能有些抽象,大家认真看下代码就会明白了。

2、getTrObj()函数得到点击事件的那行tr这个obj。得到它后就可以定位到我们关心的任何东西了。注意这里的:Event.findElement(evt,"tr");和getEventElement()都很好重用。

3、changeClassForTD()用于设置右键某行后的背景颜色,因为右键的行要与其它行区分开来,所以用上背景颜色会比较直观。这里要注意的,右键某行时要把之前右键某行的保存的原始背景色赋值上去,这在前面的第一点的orgCellColor也讨论过了。这里通过trObj.parentElement.得到tr外面的table元素,再通过table元素的getElementsByTagName("TD")得到所有的td元素,如果td的背景色是#DCDCDC时则说明它是之前右键的那行,把它赋值为原始的值。这里要注意用了比较的两方都用了toUpperCase来得到颜色值,还要注意用backgroundColor,而不是background。

4、buttonClickFun()方法指定了右键按钮点击时执行的事件函数。写这个实现时发了挺多时间,走了弯路。本来想通过grid的每个按钮的id来得到每个按钮,但构造每个grid按钮的id名发了好多时间。后来想到,用如之前第一点说的用clickRow得到右键的那行,保存下来后。就可以得到这行下面的每个grid按钮了。

5、consButtonHtml()主要是通过自定义grid的按钮解析它们的html来得到右键内容。为什么要那样解析,其中前台jsp的自定义的写法如下:

<self:tag_grid tag_name='VOU_RECORD_GRID'
			is_right_menu = "true" 
 			custom_button="
			<button title='编辑' class='gridBtnEdit' id='grid_custom_button_edit' onclick='vouRecordJsMgr.preEditVouRec();'>
			<button title='删除' class='gridBtnDel' id='grid_custom_button_del' onclick='vouRecordJsMgr.delVouRec(1);'> 
			"></self:tag_grid>

 上面的custom_button=""的内容就是我们要解析和构造的。

同时,用到的css如下:

.mouseOverGrid{
	background-color:#C0C0C0;
}
.mouseOutGrid{
	background-color:#DCDCDC;
}
.rowSplit {
	height: 3px;
	background: url(Image/m_splitLine.gif) repeat-x;
	font-size: 0px;
	margin: 0 2px;
}
 

6、buildRightMenu()是构建右键菜单的主要生成代码。它主要做了三件事:一是取得右键的行的id即ConRightMenu.clickRow;第二件事是通过consButtonHtml()取得构造右键div的html,并设置这个div的属性,如style属性等;第三件事是设置右键行的背景色。其中设置style属性是为了美观和正确的定位。要注意的是left和top值要加上滚动条的值,因为鼠标的位置取的是文档坐标。代码如下:

function Geometry(){}
Geometry.prototype = {
	getHorizontalScroll:function(){
		var result = 0;
		// All browsers but IE
		if (window.innerWidth) {
			result = window.pageXOffset;
		}
		// for IE 6 when there is a DOCTYPE
		if (document.documentElement && document.documentElement.clientWidth) { 
			result = document.documentElement.scrollLeft;
		}
		// for IE4, IE5, and IE6 without a DOCTYPE
		if (document.body.clientWidth) { 
			result = document.body.scrollLeft;
		}
		return result;
	},
	getVerticalScroll:function(){
		var result = 0;
		// All browsers but IE
		if (window.innerWidth) {
			result = window.pageYOffset;
		}
		// for IE 6 when there is a DOCTYPE
		if (document.documentElement && document.documentElement.clientWidth) {
			result = document.documentElement.scrollTop;
		}
		// for IE4, IE5, and IE6 without a DOCTYPE
		if (document.body.clientWidth) { 
			result = document.body.scrollTop;
		}
		return result;
	}
}
var geometry = new Geometry();

 

7、display_right_div()方法是当右键点击body时把右键隐藏掉。

 

以上大致介绍了自定义grid里用右键来实现功能菜单的操作过程,总体的过程就是那样了,希望对大家会有帮助。

最终的效果如下:

 

  • 大小: 18.1 KB
0
0
分享到:
评论

相关推荐

    WPF分页DataGrid(二)列右键菜单实现

    在"WPF分页DataGrid"中介绍了如何实现分页功能,本文中介绍如果实现右键菜单。点击菜单项Age,将Age列隐藏,再点击则显示;并实现移动列后,同步显示。 详见:...

    纯CSS3实现鼠标右键显示网页功能菜单特效.zip

    本资源“纯CSS3实现鼠标右键显示网页功能菜单特效.zip”就是这样一个例子,它展示了如何仅用CSS3来创建一个在鼠标右键点击时显示的功能性网页菜单。 首先,我们要理解CSS3中的:hover伪类,它是实现鼠标悬停效果的...

    Ext.grid.GridPanel右键菜单

    右键菜单的资料,代码已经详细描写。请仿照文件中所描述即可使用,不限于EXT4.0以上版本使用。

    Silverlight打开右键菜单Demo

    本示例“Silverlight打开右键菜单Demo”旨在展示如何在Silverlight应用中实现右键菜单功能。右键菜单在用户界面上是一种常见的交互元素,通常用于提供额外的操作选项或快捷方式。 首先,我们要理解Silverlight中的...

    WPF添加右键功能

    在Windows Presentation Foundation(WPF)中,为用户界面(UI)元素添加右键功能是常见的需求,这通常涉及到创建上下文菜单(Context Menu)并将其与控件绑定。上下文菜单提供了一种方便的方式来显示与特定UI元素...

    基于FineUI Grid控件添加右键菜单

    总的来说,通过结合FineUI的事件监听和自定义菜单控件,我们可以轻松地为Grid控件添加丰富的右键菜单功能,提升用户体验,同时也增强了应用的交互性和功能性。只要遵循上述步骤并根据项目需求进行适当的调整,你就能...

    ExtJs grid行 右键菜单的两种方法

    在ExtJs中,创建一个Grid并为其添加右键菜单是常见的需求...总的来说,ExtJs提供了灵活的方式来实现Grid的右键菜单功能,为用户提供更丰富的交互体验。通过以上两种方法,你可以根据项目的具体需求选择适合的实现方式。

    创建客户区右键菜单的资源代码

    在Windows API环境下,我们通常使用Windows消息处理和系统级菜单来创建客户区右键菜单。以下是一些关键步骤: 1. **注册窗口类**:首先,我们需要定义一个窗口类,并在其中包含处理右键消息的回调函数。在`WNDCLASS...

    右键菜单Silverlight

    Silverlight,作为微软推出的一种基于浏览器的交互式媒体和应用程序开发平台,同样支持自定义和实现右键菜单功能。在本篇文章中,我们将深入探讨如何在Silverlight中创建和使用右键菜单。 首先,了解Silverlight的...

    wpf mvvm treeview 动态加载(实现重命名与右键添加)

    在本文中,我们将深入探讨如何在WPF应用中利用MVVM模式动态加载并管理TreeView,同时实现节点的重命名和右键菜单功能。WPF(Windows Presentation Foundation)是微软提供的一个用于构建桌面应用程序的框架,而MVVM...

    CxGrid右键增强功能源代码

    //右键菜单 CopyCell:TMenuItem;//复制单元格内容 CopyList:TMenuItem;//复制选中列内容 CopyLine:TMenuItem;//复制选中行内容 PastLine:TMenuItem;//粘贴#9分隔符数据 DerFiles:TMenuItem;//导出文件 ...

    Labview程序树形列表和右键弹出菜单.rar

    在"Labview程序树形列表和右键弹出菜单.rar"这个压缩包中,可能包含了使用LabVIEW实现树形列表和右键菜单的示例程序。通过学习和分析这些示例,你可以了解如何在实际项目中集成和使用这些功能。 总结来说,LabVIEW...

    Jquery EasyUI Datagrid右键菜单实现方法

    最近在学Jquery EasyUI,现在来说一说EasyUI的DataGrid,一般当我们在实现前端界面的时候,经常在DataGrid的上面或者后面加一些按钮,方便用户进行一些添加,删除,编辑等功能 用户在每次使用的时候,都需要去先...

    WPF 托盘显示 右击打开菜单,双击打开软件

    例如,我们可以创建一个名为`TrayIcon`的UserControl,并在其中包含一个`ContextMenu`来模拟右键菜单: ```xml &lt;Grid&gt; 打开软件" Click="OpenSoftware_Click"/&gt; 退出" Click="Exit_Click"/&gt; &lt;/Grid&gt; ``` ...

    silverlight右键

    Silverlight是一种由微软开发的富互联网应用程序(RIA)平台,主要用于构建和运行丰富的交互式...通过这些技术,开发者可以为Silverlight应用提供丰富多样的交互功能,包括右键菜单,从而增强用户界面的易用性和功能。

    Ext grid 添加右击菜单

    总结起来,`Ext Grid`的右键菜单功能是通过监听`rowcontextmenu`事件,创建`Ext.menu.Menu`实例,定义菜单项及其处理函数,并在事件触发时正确显示菜单来实现的。这种技术在开发数据管理界面时非常有用,可以提高...

Global site tag (gtag.js) - Google Analytics