说到这儿,便想起刚学网页的时候,使用 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 需要定义两个容器,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 数组便可以修改要显示的内容。
* 設置反轉菜單。這是一個經典的網頁特效,需要設置如下的 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。