正则表达式:匹配至少有一个非空白字符并且不超过指定长度

最近需要用到一个验证,规则为:至少有一个非空白字符并且不超过指定长度,想用正则表达式来处理,上网搜了一下,发现其他人也有和我一样的需求,并且有高手给了几个很精彩的解决方案,现将网上的解决方案整理一下,以备其他有相同需求的人参考。

chinmo 逆向思维解决方案

<script type="text/javascript">
/**
 * 至少有一个非空白字符并且不超过6个字符的正则表达式
 * 
 * 作者:chinmo
 * 整理:http://www.CodeBit.cn
 * 来源:http://topic.csdn.net/u/20090207/18/ffa003ed-ecd4-40e0-b81f-36aa1fe46d85.html#r_55136904
 */
var pattern = /^[s]{0,}$|^[ws]{7,}$/g;
var str = "";
var str1 = " ";
var str2 = "a";
var str3 = "abcdefgabcdefgabcdefgabcdefgg";
var str4 = " a ";

document.write(!pattern.test(str))
document.write(!pattern.test(str1))
document.write(!pattern.test(str2))
document.write(!pattern.test(str3))
document.write(!pattern.test(str4))
</script>

正则表达式规则分析:

  • ^[s]{0,}$ :整个字符串为空或者都是空白字符
  • ^[ws]{7,}$ : 整个字符串长度大于6

作者采用逆向思维,通过匹配不符合条件的情况,再通过取反(注意每个 document.write 中的感叹号)来实现要求达到的效果。

JK_10000 逆向思维解决方案简化版

<script type="text/javascript">
/**
 * 至少有一个非空白字符并且不超过6个字符的正则表达式
 * 
 * 作者:JK_10000
 * 整理:http://www.CodeBit.cn
 * 来源:http://topic.csdn.net/u/20090207/18/ffa003ed-ecd4-40e0-b81f-36aa1fe46d85.html#rt_55145516
 */
var pattern = /.{7}|^s*$/g;
var str = "";
var str1 = " ";
var str2 = "a";
var str3 = "www.CodeBit.cn";
var str4 = " a ";

document.write(!pattern.test(str))
document.write(!pattern.test(str1))
document.write(!pattern.test(str2))
document.write(!pattern.test(str3))
document.write(!pattern.test(str4))
</script>

正则表达式规则分析:

  • .{7} : 整个字符串长度大于6,注意:这里的 . 匹配任意字符
  • ^s*$ :整个字符串为空或者都是空白字符

JK_10000 正向思维解决方案

<script type="text/javascript">
/**
 * 至少有一个非空白字符并且不超过6个字符的正则表达式
 * 
 * 作者:JK_10000
 * 整理:http://www.CodeBit.cn
 * 来源:http://hi.baidu.com/jkisjk/blog/item/b54a7a3d1c7ce3c09f3d629b.html
 * 来源:http://topic.csdn.net/u/20090207/18/ffa003ed-ecd4-40e0-b81f-36aa1fe46d85.html#rt_55145611
 */
var pattern = /^(?!.{7}|^s*$)/g;
var str = "";
var str1 = " ";
var str2 = "a";
var str3 = "www.CodeBit.cn";
var str4 = " a ";

document.write(pattern.test(str))
document.write(pattern.test(str1))
document.write(pattern.test(str2))
document.write(pattern.test(str3))
document.write(pattern.test(str4))
</script>

正则表达式规则分析:

  • .{7} : 整个字符串长度大于6,注意:这里的 . 匹配任意字符
  • ^s*$ :整个字符串为空或者都是空白字符

作者使用了正则表达式的顺序否定环视 ,指明开始(^)后面不能有7个及以上字符,或者整个字符串为空(s 没有的情况下,^$表示内容为空),或者全部都是空白字符 (s*)。

不过,该正则表达式可以将环视条件中的 ^ 去掉,即 /^(?!.{7}|s*$)/g , 因为规则一开始就已经有了一个 ^ 。

<script type="text/javascript">
/**
 * 至少有一个非空白字符并且不超过6个字符的正则表达式
 * 
 * 作者:JK_10000
 * 整理:http://www.CodeBit.cn
 * 来源:http://hi.baidu.com/jkisjk/blog/item/b54a7a3d1c7ce3c09f3d629b.html
 * 来源:http://topic.csdn.net/u/20090207/18/ffa003ed-ecd4-40e0-b81f-36aa1fe46d85.html#rt_55145611
 */
var pattern = /^(?!.{7}|s*$)/g;
var str = "";
var str1 = " ";
var str2 = "a";
var str3 = "www.CodeBit.cn";
var str4 = " a ";

document.write(pattern.test(str))
document.write(pattern.test(str1))
document.write(pattern.test(str2))
document.write(pattern.test(str3))
document.write(pattern.test(str4))
</script>

wc 发布在 JK 博客评论中的方案

<script type="text/javascript">
/**
 * 至少有一个非空白字符并且不超过6个字符的正则表达式
 * 
 * 作者:wc
 * 整理:http://www.CodeBit.cn
 * 来源:http://hi.baidu.com/jkisjk/blog/item/b54a7a3d1c7ce3c09f3d629b.html
 */
var pattern = /^(?=.*?S)[sS]{0,6}$/g;
var str = "";
var str1 = " ";
var str2 = "a";
var str3 = "www.CodeBit.cn";
var str4 = " a ";

document.write(pattern.test(str))
document.write(pattern.test(str1))
document.write(pattern.test(str2))
document.write(pattern.test(str3))
document.write(pattern.test(str4))
</script>

正则表达式规则分析:

  • (?=.*?S) :肯定顺序环视,指定任意多个任意字符后面有个非空白字符
  • [sS]{0,6} : 6个以内的空白或者非空白字符

在 Javascript 中使用全局匹配修饰符 g 的时候要特别注意,可参考本站的另外一篇文章:Javascript 中使用 exec 进行正则表达式全局匹配时的注意事项

Javascript 中使用 exec 进行正则表达式全局匹配时的注意事项

在 Javascript 中使用 exec 进行正则表达式全局匹配时,有一个非常容易犯的错误,这是因为 exec() 在全局模式下的行为稍微有点复杂。本文就是介绍在使用 Javascript 中使用 exec 进行正则表达式全局匹配时的注意事项。

先看一下常见的用法:

 
<script type="text/javascript">
 
var pattern = /http://([^/s]+)/;
alert(pattern.exec('http://www.codebit.cn')); // http://www.codebit.cn,www.codebit.cn
alert(pattern.exec('http://YITU.org')); // http://YITU.org,YITU.org
 
// 也可以直接写成 /http://([^/]+)/.exec('http://www.codebit.cn');
 
</script>

接下来看一下全局模式下的诡异事件:

 
<script type="text/javascript">
 
var pattern = /http://([^/s]+)/g;   // 使用了 g 修饰符
alert(pattern.exec('http://www.codebit.cn')); // http://www.codebit.cn,www.codebit.cn
alert(pattern.exec('http://YITU.org')); // 并没有返回期望的 http://YITU.org,YITU.org ,而是返回了 null
 
</script>

第二个语句并没有返回期望的结果,而是返回了 null ,这是因为:


在全局模式下,当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把正则表达式对象的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。

下面是正常的全局模式下的匹配方式:

 
<script type="text/javascript">
 
var pattern = /http://([^/s]+)/g;
var str = "CodeBit.cn : http://www.codebit.cn | YITU.org : http://YITU.org"; 
var result;
while ((result = pattern.exec(str)) != null)  {
	alert("Result : " + result + "  LastIndex : " + pattern.lastIndex);
}
 
//Result : http://www.codebit.cn,www.codebit.cn  LastIndex : 34
//Result : http://YITU.org,YITU.org  LastIndex : 67
 
</script>

从上面的代码我们可以看到,之所以出现第二段代码中的问题,影响因素是 lastIndex ,所以我们可以通过将 lastIndex 手动置 0 的方式来解决这个问题。

 
<script type="text/javascript">
 
var pattern = /http://([^/s]+)/g;   // 使用了 g 修饰符
alert(pattern.exec('http://www.codebit.cn')); // http://www.codebit.cn,www.codebit.cn
pattern.lastIndex = 0;
alert(pattern.exec('http://YITU.org')); // http://YITU.org,YITU.org 
 
</script>

总结:

在全局模式下,如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0。

Javascript 中阻止浏览器默认操作

在浏览器事件中,会触发一些默认动作,比如:点击一个链接时,执行完捕获/冒泡动作后,会触发链接的默认事件:跳转到指定链接地址。

在很多时候,我们需要改变这些默认操作,比如:点击一个链接时,我们执行一些 ajax 操作,但是我们并不希望执行跳转动作,于是,就有了本文:阻止浏览器默认操作。

其实这并不是一个非常难的课题,单独拿出来的原因还是浏览器兼容问题:

 
<script type="text/javascript">
 
// 说明:Javascript 中阻止浏览器默认操作
// 作者:John Resig
// 来源:CodeBit.cn ( http://www.CodeBit.cn )
 
function stopDefault( e ) {
	// Prevent the default browser action (W3C)
	if ( e && e.preventDefault )
		e.preventDefault();
	// A shortcut for stoping the browser action in IE
	else
		window.event.returnValue = false;
	return false;
}
</script>

使用示例:

 
<a href="http://www.google.com" id="testLink">Google</a>
 
<script type="text/javascript">
var test = document.getElementById('testLink');
test.onclick = function(e) {
	alert('我的链接地址是:' + this.href + ', 但是我不会跳转。');
	stopDefault(e);
}
</script>

用 Javascript 实现检测、添加、移除样式(className)

在前台脚本中,我们经常要操作页面元素的样式,比如标签页切换时,将当前标签加上一个样式,当切换到其他标签时,再将样式还原,本文介绍的是直接添加和移除 className 的方法。

 
<script type="text/javascript">
 
// 说明:添加、移除、检测 className
// 整理:CodeBit.cn ( http://www.codebit.cn )
 
function hasClass(element, className) {
	var reg = new RegExp('(\s|^)'+className+'(\s|$)');
	return element.className.match(reg);
}
 
function addClass(element, className) {
	if (!this.hasClass(element, className))
	{
		element.className += " "+className;
	}
}
 
function removeClass(element, className) {
	if (hasClass(element, className)) {
    	var reg = new RegExp('(\s|^)'+className+'(\s|$)');
		element.className = element.className.replace(reg,' ');
	}
}
 
</script>

Javascript 中 String.replace( ) 的妙用

String.replace( ) 简介

语法:

 
string.replace(regexp, replacement)

regexp :您要执行替换操作的正则表达式,如果传入的是一个字符串,那就会当作普通字符来处理,并且只会执行一次替换操作;如果是正则表达式,并且带有 global (g) 修饰符,则会替换所有出现的目标字符,否则,将只执行一次替换操作。

replacement :您要替换成的字符。

返回值是执行替换操作后的字符串。

String.replace( ) 的简单用法

 
var text = "javascript 非常强大 !";
text.replace(/javascript/i, "JavaScript");
// 返回:JavaScript 非常强大 !

String.replace( ) 替换所有出现的目标字符

 
var text= "javascript 非常强大 !JAVASCRIPT 是我最喜欢的一门语言 !";
text.replace(/javascript/ig, "JavaScript");
// 返回:JavaScript 非常强大 !JavaScript 是我最喜欢的一门语言 !

String.replace( ) 实现调换位置

 
var name= "Doe, John";
name.replace(/(w+)s*,s*(w+)/, "$2 $1");
// 返回:John Doe

String.replace( ) 实现将所有双引号包含的字符替换成中括号包含的字符

 
var text = '"JavaScript" 非常强大!';
text.replace(/"([^"]*)"/g, "[$1]");
// 返回:[JavaScript] 非常强大!

String.replace( ) 将所有字符首字母大写

 
var text = 'a journey of a thousand miles begins with single step.';
text.replace(/bw+b/g, function(word) {
                           return word.substring(0,1).toUpperCase( ) +
                                  word.substring(1);
                         });
 
// 返回:A Journey Of A Thousand Miles Begins With Single Step.

Javascript 中截取小数位并实现四舍五入的方法

在 CodeBit.cn 的论坛中,有人问 Javascript 中如何截取小数位并实现四舍五入,这是一个很常用的 js 技术,帖子中也有网友热心回复,因为觉得比较典型,可能很多新手都会遇到此问题,所以将帖子整理了一下,以备新手查阅。

round 方法

作用:返回与给出的数值表达式最接近的整数。
语法:Math.round(number) ,必选项 number 参数是要舍入到最接近整数的值。
说明:如果 number 的小数部分大于等于 0.5,返回值是大于 number 的最小整数。否则,round 返回小于等于 number 的最大整数。

示例:

 
// 如果取一位则乘以 10 之后再除以 10, 以此类推
Math.round(3.248 * 100) / 100

Javascript 1.5 新增函数

在 Javascript 1.5 (IE5.5+ , NS6+ 以上版本支持)中,新增了2个专门用于货币流通的函数:
Number.toFixed(x) 和 Number.toPrecision(x)。

Number.toFixed(x) 是将指定数字截取小数点后 x 位, Number.toPrecision(x) 是将整个数字截取指定(x)长度。注意,一个是计算小数点后的长度,一个是计算整个数字的长度 。

请看完整示例:

 
<script type="text/javascript">
 
var aa = 2.3362;
 
document.write(aa.toFixed(1)); // 2.3
document.write(aa.toFixed(2)); // 2.34
 
document.write(aa.toPrecision(2)); // 2.3
document.write(aa.toPrecision(3)); // 2.34
 
document.write(Math.round(aa * 10) / 10); // 2.3
document.write(Math.round(aa * 100) / 100); // 2.34
 
</script>

显然,新增的 2 个专用函数使用非常方便,但是因为是新增函数,所以要考虑浏览器支持问题,请根据您的客户群选择对应的方法。

通过 Javascript 实现的 CSS 浏览器选择符(CSS Browser Selector)

CSS 在不同浏览器下的最终显示效果是不同的,因此,出现了很多根据不同浏览器作相应处理的 HACK 技术,本文介绍的是通过 Javascript 检测浏览器和操作平台类型,然后设置特定选择符。设置样式时,通过 CSS 的包含选择符,我们很容易就能根据不同浏览器作出不同处理。

通过 Javascript 实现的 CSS 浏览器选择符(CSS Browser Selector) – 示例

 
<script type="text/javascript">
// 说明 : 通过 Javascript 实现的 CSS 浏览器选择符(CSS Browser Selector)
// 整理 : CodeBit.cn ( http://www.codebit.cn )
 
// CSS Browser Selector   v0.2.5
// Documentation:         http://rafael.adm.br/css_browser_selector
// License:               http://creativecommons.org/licenses/by/2.5/
// Author:                Rafael Lima (http://rafael.adm.br)
// Contributors:          http://rafael.adm.br/css_browser_selector#contributors
var css_browser_selector = function() {
	var 
		ua=navigator.userAgent.toLowerCase(),
		is=function(t){ return ua.indexOf(t) != -1; },
		h=document.getElementsByTagName('html')[0],
		b=(!(/opera|webtv/i.test(ua))&&/msie (d)/.test(ua))?('ie ie'+RegExp.$1):is('gecko/')? 'gecko':is('opera/9')?'opera opera9':/opera (d)/.test(ua)?'opera opera'+RegExp.$1:is('konqueror')?'konqueror':is('applewebkit/')?'webkit safari':is('mozilla/')?'gecko':'',
		os=(is('x11')||is('linux'))?' linux':is('mac')?' mac':is('win')?' win':'';
	var c=b+os+' js';
	h.className += h.className?' '+c:c;
}();
</script>

其原理是:先用 js 检测浏览器类型和操作系统平台,然后给最高节点 “HTML” 赋上对应的 class ,然后在设置样式时,我们就可以通过 css 的包含选择符,根据不同浏览器作出不同处理了。

用 Javascript 验证表单(form)中多选框(checkbox)值

和单选框一样,许多新手在用 Javascript 验证表单(form)中多选框(checkbox)的值时,都会遇到问题,原因是 checkbox 和普通的文本框在获取值的时候有很大不同,本文介绍了一个较为通用的获取 checkbox 值的方法,希望对新手有用。

用 Javascript 验证表单(form)中多选框(checkbox)值 – 示例

 
<script type="text/javascript">
 
// 说明: 用 Javascript 验证表单(form)中多选框(checkbox)的值
// 作者: CodeBit.cn  ( http://www.CodeBit.cn )
 
function getCheckboxValue(checkbox)
{
	if (!checkbox.length && checkbox.type.toLowerCase() == 'checkbox')
	{ return (checkbox.checked)?checkbox.value:'';  }
	
	if (checkbox[0].tagName.toLowerCase() != 'input' || 
		checkbox[0].type.toLowerCase() != 'checkbox')
	{ return ''; }
 
	var val = [];
	var len = checkbox.length;
	for(i=0; i<len; i++)
	{
		if (checkbox[i].checked)
		{
			val[val.length] = checkbox[i].value;
		}
	}
	
	return (val.length)?val:'';
}
 
</script>

和 radio 一样,都是 name 相同,值有多个,在获取 checkbox 值的时候,我们不能按照普通文本框 .value 的方式,而是要判断哪个被选中了。

当一组 checkbox 有多个选项时,我们可以通过循环,以 checkbox[i] 的方式判断某个选项是否被选中来返回值,但是当一组 checkbox 只有一个选项时,获取值的方式又有变化,代码中以 (checkbox.checked)?checkbox.value:”; 的方式直接判断是否选中,然后返回对应值。

上面的代码传入的参数是 checkbox 对象,如:

var checkboxTest = document.forms[‘testForm’].elements[‘checkboxTest’];
if (getCheckboxValue(checkboxTest) == ”)
{ …… }

根据判断结果执行你想要的操作。

用 Javascript 验证表单(form)中的单选(radio)值

在用 Javascript 验证表单(form)中的单选框(radio)是否选中时,很多新手都会遇到问题,原因是 radio 和普通的文本框在获取值的时候有很大不同,本文介绍了一个较为通用的获取 radio 值的方法,希望对新手有用。

用 Javascript 验证表单(form)中的单选(radio)值 – 示例

 
<script type="text/javascript">
 
// 说明: 用 Javascript 验证表单(form)中的单选(radio)值
// 作者: CodeBit.cn  ( http://www.CodeBit.cn )
 
function getRadioValue(radio)
{
	if (!radio.length && radio.type.toLowerCase() == 'radio') 
	{ return (radio.checked)?radio.value:'';  }
 
	if (radio[0].tagName.toLowerCase() != 'input' || 
		radio[0].type.toLowerCase() != 'radio')
	{ return ''; }
 
	var len = radio.length;
	for(i=0; i<len; i++)
	{
		if (radio[i].checked)
		{
			return radio[i].value;
		}
	}
	return '';
}
 
</script>

radio 和 checkbox 一样,都是 name 相同,值有多个,在获取 radio 值的时候,我们不能按照普通文本框 .value 的方式,而是要判断哪个被选中了。

当一组 radio 有多个选项时,我们可以通过循环,以 radio[i] 的方式判断某个选项是否被选中来返回值,但是当一组 radio 只有一个选项时,获取值的方式又有变化,代码中以 return (radio.checked)?radio.value:”; 这样的方式直接判断是否选中,然后返回对应值。

上面的代码传入的参数是 radio 对象,如:

var radioTest = document.forms[‘testForm’].elements[‘radioTest’];
if (getRadioValue(radioTest) == ”)
{ …… }

根据判断结果执行你想要的操作。

滑动式折叠菜单 - Slashdot’s Menu

折叠菜单让你在尽可能小的地方放置尽可能多的内容,同时加大了操作的简便性,因此,深受前台设计师的喜爱。随着大家对动画效果的钟爱,折叠菜单也开始“动”起来了,本文介绍的就是 DimX 制作的滑动式折叠菜单效果-Slashdot’s Menu。

滑动式折叠菜单 - Slashdot’s Menu – 示例

 
<script type="text/javascript">
function SDMenu(id) {
	if (!document.getElementById || !document.getElementsByTagName)
		return false;
	this.menu = document.getElementById(id);
	this.submenus = this.menu.getElementsByTagName("div");
	this.remember = true;
	this.speed = 3;
	this.markCurrent = true;
	this.oneSmOnly = false;
}
SDMenu.prototype.init = function() {
	var mainInstance = this;
	for (var i = 0; i < this.submenus.length; i++)
		this.submenus[i].getElementsByTagName("span")[0].onclick = function() {
			mainInstance.toggleMenu(this.parentNode);
		};
	if (this.markCurrent) {
		var links = this.menu.getElementsByTagName("a");
		for (var i = 0; i < links.length; i++)
			if (links[i].href == document.location.href) {
				links[i].className = "current";
				break;
			}
	}
	if (this.remember) {
		var regex = new RegExp("sdmenu_" + encodeURIComponent(this.menu.id) + "=([01]+)");
		var match = regex.exec(document.cookie);
		if (match) {
			var states = match[1].split("");
			for (var i = 0; i < states.length; i++)
				this.submenus[i].className = (states[i] == 0 ? "collapsed" : "");
		}
	}
};
SDMenu.prototype.toggleMenu = function(submenu) {
	if (submenu.className == "collapsed")
		this.expandMenu(submenu);
	else
		this.collapseMenu(submenu);
};
SDMenu.prototype.expandMenu = function(submenu) {
	var fullHeight = submenu.getElementsByTagName("span")[0].offsetHeight;
	var links = submenu.getElementsByTagName("a");
	for (var i = 0; i < links.length; i++)
		fullHeight += links[i].offsetHeight;
	var moveBy = Math.round(this.speed * links.length);
	
	var mainInstance = this;
	var intId = setInterval(function() {
		var curHeight = submenu.offsetHeight;
		var newHeight = curHeight + moveBy;
		if (newHeight < fullHeight)
			submenu.style.height = newHeight + "px";
		else {
			clearInterval(intId);
			submenu.style.height = "";
			submenu.className = "";
			mainInstance.memorize();
		}
	}, 30);
	this.collapseOthers(submenu);
};
SDMenu.prototype.collapseMenu = function(submenu) {
	var minHeight = submenu.getElementsByTagName("span")[0].offsetHeight;
	var moveBy = Math.round(this.speed * submenu.getElementsByTagName("a").length);
	var mainInstance = this;
	var intId = setInterval(function() {
		var curHeight = submenu.offsetHeight;
		var newHeight = curHeight - moveBy;
		if (newHeight > minHeight)
			submenu.style.height = newHeight + "px";
		else {
			clearInterval(intId);
			submenu.style.height = "";
			submenu.className = "collapsed";
			mainInstance.memorize();
		}
	}, 30);
};
SDMenu.prototype.collapseOthers = function(submenu) {
	if (this.oneSmOnly) {
		for (var i = 0; i < this.submenus.length; i++)
			if (this.submenus[i] != submenu && this.submenus[i].className != "collapsed")
				this.collapseMenu(this.submenus[i]);
	}
};
SDMenu.prototype.expandAll = function() {
	var oldOneSmOnly = this.oneSmOnly;
	this.oneSmOnly = false;
	for (var i = 0; i < this.submenus.length; i++)
		if (this.submenus[i].className == "collapsed")
			this.expandMenu(this.submenus[i]);
	this.oneSmOnly = oldOneSmOnly;
};
SDMenu.prototype.collapseAll = function() {
	for (var i = 0; i < this.submenus.length; i++)
		if (this.submenus[i].className != "collapsed")
			this.collapseMenu(this.submenus[i]);
};
SDMenu.prototype.memorize = function() {
	if (this.remember) {
		var states = new Array();
		for (var i = 0; i < this.submenus.length; i++)
			states.push(this.submenus[i].className == "collapsed" ? 0 : 1);
		var d = new Date();
		d.setTime(d.getTime() + (30 * 24 * 60 * 60 * 1000));
		document.cookie = "sdmenu_" + encodeURIComponent(this.menu.id) + "=" + states.join("") + "; expires=" + d.toGMTString() + "; path=/";
	}
};
</script>

调用方式

 
var myMenu = new SDMenu("main_menu"); // 菜单ID
 
// 默认参数
myMenu.speed = 3;                     // 折叠速度
myMenu.remember = true;               // 是否记录状态
myMenu.oneSmOnly = false;             // 一次只有一个菜单打开
myMenu.markCurrent = true;            // 是否高亮当前菜单
 
myMenu.init();
 
// 附加方法
var firstSubmenu = myMenu.submenus[0];
myMenu.expandMenu(firstSubmenu);      // 打开一个菜单
myMenu.collapseMenu(firstSubmenu);    // 关闭一个菜单
myMenu.toggleMenu(firstSubmenu);      // 当菜单关闭时打开,当菜单打开时关闭
 
myMenu.expandAll();                   // 打开所有菜单
myMenu.collapseAll();                 // 关闭所有菜单