说到这儿,便想起刚学网页的时候,使用 Dreamweaver 的一个按钮翻转的 JS,那是很典型的网页效果,说出函数名字来大伙还记得吗?……MM_preloadImages('images/2.jpg')、MM_swapImage('rotator','','images/2.jpg',1) 呵呵。同样我们也可以在 Ext Core 之中轻松实现,这部分内容放在本文第三小节中为大家介绍。Update 2010.1.2
在自家页面上使用自己的库,自然不是一件稀奇的事,而且 extjs.com 的 JS 特效都不是那么复杂,几个函数足以完成任务了。今天继续昨晚对 widget 余庆,继续 copy and paste 她的代码来看看。当然大家也可以上 extjs.com 直接拿页面回来,但 CSS 背景图片的下载就不好寻址,推荐一下这个 Firefox 插件ScrapBook。感觉而言,所用的 JS 代码,大体上比较鲜明的 JS 特效有菜单及简单的讯息提示(Messages),所谓 Messages,就是只有一两句的提示,但位置醒目,能起到很好的提示作用。下面就打算把这两个 JS 抠出来。
一、菜单
extjs.com 的菜单实际已不是软件定义中的“菜单”了,因为我们看到菜单中所表现的元素更为丰富,其理解方式可以说是在导航栏上添加一个 onmouseover 的事件,触发该事件就会显示“面板”,因为从 HTML 上看到,组成各项菜单的就是一个四四方方的“面板”。 呵呵,这样去实现也倒容易…以最后的 Store 一项为例,其“面板”的 HTML 结构如下:
<div class="flyout-menu" id="store-menu" style="display: none;" mce_style="display: none;">
<div style="width: 200px;">
<h3>
<a href="http://www.extjs.com/store/extjs/" mce_href="http://www.extjs.com/store/extjs/">Ext JS</a></h3>
<ul>
<li><a href="http://www.extjs.com/store/extjs/" mce_href="http://www.extjs.com/store/extjs/">Licenses</a></li>
<li><a href="http://www.extjs.com/store/extjs/#support-table" mce_href="http://www.extjs.com/store/extjs/#support-table">Support Subscriptions</a></li>
</ul>
<br>
<h3>
<a href="http://www.extjs.com/store/gxt/" mce_href="http://www.extjs.com/store/gxt/">Ext GWT</a></h3>
<ul>
<li><a href="http://www.extjs.com/store/gxt/" mce_href="http://www.extjs.com/store/gxt/">Licenses</a></li>
<li><a href="http://www.extjs.com/store/gxt/#support-table" mce_href="http://www.extjs.com/store/gxt/#support-table">Support Subscriptions</a></li>
</ul>
<br>
<h3>
<a href="http://www.extjs.com/store/faq.php" mce_href="http://www.extjs.com/store/faq.php">Help</a></h3>
<ul>
<li><a href="http://www.extjs.com/store/faq.php" mce_href="http://www.extjs.com/store/faq.php">Ordering FAQ</a></li>
</ul>
</div>
</div>
其中,最外层 div 其样式应该是 class="flyout-menu",以归为菜单的一类,而且还要隐藏菜单 style="display: none;",默认状态下隐藏,使用的时候方才显示。介绍完结构之后,我们看看代码,也是比较简单的:
var activeMenu;
function createMenu(name){
var el = Ext.get(name+'-link');
var tid = 0, menu, doc = Ext.getDoc();
var handleOver = function(e, t){
if(t != el.dom && t != menu.dom && !e.within(el) && !e.within(menu)){
hideMenu();
}
};
var hideMenu = function(){
if(menu){
menu.hide();
el.setStyle('text-decoration', '');
doc.un('mouseover', handleOver);
doc.un('mousedown', handleDown);
}
}
var handleDown = function(e){
if(!e.within(menu)){
hideMenu();
}
}
var showMenu = function(){
clearTimeout(tid);
tid = 0;
if (!menu) {
menu = new Ext.Layer({shadow:'sides',hideMode: 'display'}, name+'-menu');
}
menu.hideMenu = hideMenu;
menu.el = el;
if(activeMenu && menu != activeMenu){
activeMenu.hideMenu();
}
activeMenu = menu;
if (!menu.isVisible()) {
menu.show();
menu.alignTo(el, 'tl-bl?');
menu.sync();
el.setStyle('text-decoration', 'underline');
doc.on('mouseover', handleOver, null, {buffer:150});
doc.on('mousedown', handleDown);
}
}
el.on('mouseover', function(e){
if(!tid){
tid = showMenu.defer(150);
}
});
el.on('mouseout', function(e){
if(tid && !e.within(el, true)){
clearTimeout(tid);
tid = 0;
}
});
}
createMenu('products');
createMenu('support');
createMenu('store');
通过以上的几个步骤,就可以创建简单导航菜单,相信代码也很好理解,快点放在你的项目中使用吧!
二、Messages
Messages 就更简单了。Messages 需要定义两个容器,msg = Ext.get('msg') 和 msgInner = Ext.get('msg-inner')。
<div style="position: static; visibility: visible; left: auto; top: auto; z-index: auto;" id="msg">
<div class="" id="msg-inner">
Ext 3.0.0 Release Now Available »</div>
</div>
// messages
var msgs = [
{ text: 'Ext Enterprise Training Now Available »', url: 'http://extjs.com/support/training/' },
{ text: 'Ext GWT 2.0 Release Now Available »', url: 'http://extjs.com/products/gxt/' },
{ text: 'Ext 3.0.0 Release Now Available »', url: 'http://extjs.com/products/extjs/download.php' }
];
var msgIndex = 0;
var msg = Ext.get('msg'),
msgInner = Ext.get('msg-inner'),
active = null;
if (msgInner) {
msgInner.addClassOnOver('msg-over');
}
if (msg) {
msg.on('click', function() {
window.location = active.url;
});
}
function doUpdate() {
if (msgInner) {
msgInner.update(active.text);
}
if (msg) {
msg.slideIn('b');
}
}
function showMsg(index) {
if (msgInner && !msgInner.hasClass('msg-over')) {
active = msgs[index];
if (msg && msg.isVisible()) {
msg.slideOut('b', { callback: doUpdate });
} else {
doUpdate();
}
}
}
setInterval(function() {
msgIndex = msgs[msgIndex + 1] ? msgIndex + 1 : 0;
showMsg(msgIndex);
}, 5000);
showMsg(0);
明显,定义新的 msgs 数组便可以修改要显示的内容。
三、Ext JS 网页特效:翻转菜单。
* 設置反轉菜單。這是一個經典的網頁特效,需要設置如下的 CSS 樣式:
* 註意:!important 是為FF所需的關鍵字;
* 設置步驟:
* 1、HTML 是:
<textarea class="html">
<ul id='gobalMenu'>
<li id="index">
<a href="../" mce_href="" title="首页"><img src="/images/s.gif" mce_src="images/s.gif" /></a>
</li>
……
<ul id='gobalMenu'>
<textarea>
* 2、設置樣式display:line,li的高度,圖片的高度:
* 註意:font-size:18px是為FF所需的關鍵字
<textarea class="css">
#gobalMenu li{
display:inline;
height:22px;
margin-left:10px;
font-size:18px;
background-repeat:no-repeat;
}
#gobalMenu li img{
height:22px;
}
* 3、反轉的樣式必須是“ li元素名稱”+OnHover
<textarea class="css">
li#docs{
background:url(main_15.gif) no-repeat;
}
.docsOnHover{
background:url(index_hover_16.gif) no-repeat !important;
}
执行代码:
callHoverMenu = function(LI_selector){
Ext.onReady(function(){
Ext.select(LI_selector).each(this);
}, function(li){
Ext.get(li.dom.id).addClassOnOver(li.dom.id + 'OnHover');
});
}
四、小结
官方所释出的 DEMO 中 Ext JS Core,除了 LightBox,还有 Carousel、Menu 和 Tabs 新提供的 Widget。在上一讲第一讲中,我们已经谈论过 Ligiht。本文中将会看看:1、Carousel 画册控件;2、Menu 菜单;3、标签页 Tabs。了解 Ext JS 的朋友可能好奇,不是 Ext JS 里面已经有 Menu 和 Tabs 组件了吗,为什么 Ext JS Core 还会提供这两个控件呢?两者的定位明显不同,要求在 Portal 为背景的页面加入 Component/Container 等组件,光是代码足够多的了,而且维护难度大,页面逻辑复杂——吃力不讨好,因此完全没有必要,于是更加轻型的 Widget 应运而生了。
每一个特效背后所组成的 HTML/CSS/JavaScript 都是研究的对象。我们研究 HTML/CSS 是为了我们这些最终用户不断修改,以符合制作的 Widget 符合我们的要求;JS 一般是封装好的逻辑,没有额外的理由我们怎么会花时间研究它呢?而 Ext JS Core 这次释出的 DEMO 却不同,仍有相当可观之处,实在是很好的研究对象。正如首次推介的那样,“find and learn somethingnew”,大大满足了新鲜和求知的冲动,没有比这个更好的理由?
在下一讲中,有机会的话,小弟将会讲讲 Carousel、Menu 和 Tabs,希望大家多留意。
不是小弟我讨好 Ext JS,因为 DEMO 本身所宣扬的 “A minimal amount of elegant and readable code” 似乎是得到印证,——代码中都写成这样了,各位看官可以一睹为快。最后,——祝大家使用 Ext JS 祺顺!
本文所说例子的打包文件,可以从这里点击下载,大小 989KB。