基于 jQuery 的旗帜效果纵向多级导航菜单


Written on 五月 10, 2009 – 12:55 下午 | by paopao

最近看了一些基于 jQuery 的好玩的导航菜单,然后就想到了这样一个效果的菜单,其实我也不知道该叫它什么效果,就叫旗帜效果 (flag style) 吧。

先来看看最终效果是什么样的: 演示(Demo)

一个导航菜单,最重要的是可访问性,其他的效果都是为了锦上添花的,所以首先我们要做一个纯 CSS 的纵向导航菜单,这样即使用户关闭了 JavaScript 也能无障碍的访问。

第一步: 一个语义化的 HTML 结构

<h2>Flag Navigation</h2>
<ul id="nav" class="nav">
    <li><a href="#">1 HTML</a></li>
    <li><a href="#">2 CSS</a>
        <ul>
            <li><a href="#">2.1 CSS 2</a></li>
            <li><a href="#">2.2 CSS 3</a></li>
        </ul>
    </li>
    <li><a href="#">3 JavaScript</a>
        <ul>
            <li><a href="#">3.1 jQuery</a>
                <ul>
                    <li><a href="#">3.1.1 Download</a></li>
                    <li><a href="#">3.1.2 Tutorial</a></li>
                </ul>
            </li>
            <li><a href="#">3.2 Mootools</a></li>
            <li><a href="#">3.3 Prototype</a></li>
        </ul>
    </li>
</ul>

一般来说,我们都使用一个嵌套的无序列表来表示一个多级导航菜单。

第二步: 给这段 HTML 加上一些样式

body {font: 15px "Arial"}
h2 {font: 18px "Arial"; font-weight: bold; }
.nav, .nav ul{
    width:140px; /* 定义每级菜单的宽度 */
    margin:0;
    padding:0;
    list-style-type:none;
    list-style-position:outside;
    position:relative; /* 采用相对定位,为子菜单的绝对定位提供基准元素 */
    line-height:30px;  /* 定义每条菜单的行高 */
}
.nav a:link, .nav a:visited{ /* 定义链接的基本样式 */
    display:block;
    width:130px; /* 这里的宽度和下面的 padding 加起来是 140px */
    padding:0px 5px;
    color:#fff;
    text-decoration:none;
    background:url(bg.png) no-repeat -261px 0px; /* 背景图片定位,采用 CSS Sprites 技术 */
}
.nav a:hover,a:active{ /* 定义链接的悬停和点击时的样式 */
    background-position:-79px 0px;  /* 修改背景图片定位 */
    color:#333;
}
.nav li{  /* 每条菜单的定位方式为相对定位 */
    position:relative;
}
.nav ul {  /* 子菜单的样式 */
    position:absolute; /* 采用绝对定位 */
    top:0px; /* 子菜单和上一级菜单上部平齐 */
    left:140px; /* 子菜单显示在上一级菜单右侧 */
    display:none; /* 子菜单不显示 */
}
.nav li:hover>ul{
    display:block; /* 当 list 悬停时,显示它的下一级子菜单 */
}

在 “ul” 的样式中使用 line-height 是为了让菜单文字能纵向居中,同时这个值在我们后面的 jQuery flagNav 插件中有使用到。
这样我们就得到了一个纯 CSS 的纵向多级导航菜单,具体效果可以看看 Demo 页面的第一个菜单。
*这个菜单的效果在 IE6 及其之前的浏览器中是表现不出来的,因为 IE6 不支持 “a” 元素之外的其他元素的 hover 伪类,这个可以通过一些复杂的 CSS Hack 来进行兼容,不过我这里就不管它了,感兴趣的同学可以自行 Google 之。

第三步: 用 jQuery 来添加我们的旗帜动画效果

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.easing.1.3.min.js"></script>
<script type="text/javascript" src="jquery.flagNav.min.js"></script>

我们将 jQuery 库和 jQuery Easing 插件载入,并载入自己的 jQuery flagNav 插件

<script type="text/javascript">
    $(document).ready(function(){
        $("#nav1").flagNav({bgposout:"-261px 0px", bgposover:"-79px 0px"});
        $("#nav2").flagNav({bgposout:"-261px 0px", bgposover:"-79px 0px", rollback:true});
    });
</script>

再在页面载入后对我们的菜单进行初始化,其中 flagNav 函数的参数中 bgposout 和 bgposover 的值分别和前面 CSS 中 “a:link” 和 “a:hover” 的 background-position 值相对应,rollback 参数则表示在菜单消失时是否使用动画效果,默认值是不使用。

这样我们就完成了一个带旗帜动画效果的纵向多级导航菜单,是不是挺简单的?

这个菜单在所有我使用的浏览器上都测试通过了,如果你有任何问题或建议,欢迎给我留言。

Popularity: 4% [?]

Tags: , , , , ,

Circle Tag Cloud Plugin for jQuery


Written on 五月 4, 2009 – 11:59 上午 | by paopao

昨天看到某个 blog 上一个 3D Tag Cloud 插件,效果很炫,是用 Flash 写的。很想把它移植到 JavaScript 来,不过尝试失败,最后得到的效果不甚理想,不过还是记录下来吧,也算是一个学习的过程。

*演示(Demo)
*下载(Download)

这个效果是基于 jQuery 编写的,也用到了 GSGDEasing Plugin (如果选择使用 jQuery 自带的 “linear” 或者 “swing” 效果的话则不需要包含此插件)。

首先需要一个适当的 html 结构:

<h2>Circle Tag Cloud</h2>
<div id="tag_cloud">
    <a id="tag1" href="#1" style="font-size: 20pt; color:blueviolet">UED</a>
    <a id="tag2" href="#2" style="font-size: 10pt; color:maroon">JavaScript</a>
    <a id="tag3" href="#3" style="font-size: 15pt; color:dodgerblue">Jquery</a>
    <a id="tag4" href="#4" style="font-size: 8pt; color:violet">paopao</a>
    <a id="tag5" href="#5" style="font-size: 12pt; color:lightseagreen">demo</a>
</div>

然后给这段 html 加上一些必须的样式:

h2 {font: 13pt/15pt "Arial"; font-weight: bold; }
#tag_cloud{position:relative;width:300px;height:300px;background-color:#eee;overflow:hidden;}
#tag_cloud a{position:absolute;text-decoration:none;white-space:nowrap;}
#tag_cloud a:hover{border:1px solid #000}

当然还要载入一些必需的 js 文件:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="jquery.easing.1.3.js"></script>
<script type="text/javascript" src="jquery.circletag.min.js"></script>

最后,在页面里加入如下的初始化 js 代码就 ok 了:

<script type="text/javascript">
    $(document).ready(function(){
        $("#tag_cloud").circleTag({ speed: 300 });
    });
</script>

下载地址在此

需求:
* jQuery 1.3 or higher
* jQuery Easing Plugin 1.3

Popularity: 3% [?]

Tags: , , ,

你的第一条饭否/ Twitter 消息


Written on 四月 27, 2009 – 10:59 上午 | by paopao

前天在饭否上看到有些人在玩一个 Twitter 应用,这个应用可以查出你加入 Twitter 的时间。觉得蛮好玩的,因为我用 Twitter 很少(主要是觉得网页版速度不够快,又不想再开一个客户端),所以想看看能不能移植到饭否来。虽然饭否的 API 和 Twitter 的基本相同,但是在用户信息这部分稍有不同,饭否并没有提供用户的创建时间这个字段。

没办法,只好曲线救国了… 我用了搜索用户消息的办法来查找用户的第一条消息,虽然这和用户的创建时间不一定一样,不过这也算是另一种应用吧 ^_^

第一次使用 Google App Engine 来部署应用,不过没用到 Python (因为不会 =,= ),只是直接使用了静态文件:

你在饭否的第一条消息?
不幸的发现饭否的 API 也有同样的限制,虽然没有在文档里写明,但是经过测试,只能得到最多 3,200 条用户消息…
Update 了一个新的版本,现在应该可以查询所有人的第一条消息了,即使你是消息数超过 3,200 的饭否狂人 :)

Your First Twitter?
Twitter 这个版本有点问题,由于 API 的限制,只能得到最多 3,200 条用户消息,所以消息数超过 3,200 的目前还无法查到第一条消息…

Rest API Limit
Clients may request up to 3,200 statuses via the page and count parameters for timeline REST API methods.

Your First Twitter? (Search Version)
Twitter 消息数超过 3,200 的 Twitter 狂人们可以尝试这个版本,通过 google 搜索来查找的,不一定能成功

另外第一次用到了 JSONP 技术,和 Jquery 结合起来使用的话,很好很方便。

感谢 James Padolsey 的 TinyURL JSONP API ,可以很方便的得到缩短网址。

Popularity: 5% [?]

Tags: , , , , ,

Gwibber: 支持多个微博客的Gnome客户端


Written on 三月 22, 2009 – 10:46 上午 | by paopao

以下摘自Gwibber的“关于”页面:

Gwibber 是一个基于 GNOME 的微博客客户端。它支持 Twitter, Jaiku, Facebook, Pownce, Identi.ca 以及其他社会化网络服务。

Gwibber 采用 pygtk 作为窗口框架,WebKit 作为内核来渲染内容,支持更换主题,还支持气泡提示、自动缩短长网址等实用功能。从本质上看,Gwibber 就像是一个高度定制化的浏览器,和 Chrome 的“创建桌面App”的概念有点像,但更加专一一些。

我使用的 Gwibber 版本是0.8,项目主页在 launchpad,Ubuntu 下的安装方法在此

对于国内的微博客“饭否”的用户,Liang Zhao 参考 Twitter 的插件制作了饭否的 Gwibber 插件( Blogger 地址,需翻墙,不想翻墙的可以看这里)。目前 Gwibber 似乎还没有很方便的添加新的或者自己制作的插件及协议的方法,只能手动修改。

昨天在Ubuntu 8.10下安装这个饭否插件有点小问题,首先是按照 Liang Zhao 提供的方法安装时出现没有找到 fanfou 这个包的提示,后来发现需要先增加一个文件链接到 /usr/lib/python2.5/site-packages/gwibber/microblog 目录,具体方法就是增加以下这个安装步骤:

sudo ln -T /usr/share/pyshared/gwibber/microblog/fanfou.py /usr/lib/python2.5/site-packages/gwibber/microblog/fanfou.py

接着,在开始接受饭否消息的时候也出现了错误。对比了一下这个饭否插件和 Twitter 创建的内容,似乎是在密码保存方面的错误,尝试着把 fanfou.py 里的 private:password 全部替换成 password 之后问题解决。(把 Gwibber 版本从0.7.3升级到0.8之后就没有这个问题了) 因为我对 Python 不了解,不知道这两个问题是不是和我安装的 Gwibber 版本或者 pygtk 版本有关系,或者就是这个插件本身的问题,反正问题目前已经解决了。

Gwibber 也提供了本地化的支持,用的是 gettext 方法,和 WordPress 一样。Gwibber 采用了 launchpad 提供的协作翻译功能,如果你有 launchpad 帐户,可以在这里很方便的参加翻译。如果想使用中文界面,可以使用下面这个 mo 包,也可以自行去 launchpad 下载(需要 launchpad 帐户)。

Gwibber 中文语言包

中文语言包安装方法:
将下载的 mo 文件改名为 gwibber.mo ,拷贝到 /usr/local/share/locale/zh_CN/LC_MESSAGES 目录(需要 root 权限)即可。

Popularity: 7% [?]

Tags: , , , , , ,

Opera浏览器处理disabled属性的bug


Written on 十一月 26, 2008 – 9:00 下午 | by paopao

最近在看John Resig的《精通JavaScript》,作为JQuery的作者之一,技术实力自然不在话下。不过如果仔细看某些源代码的话,还是有些小问题的,也许是作者比较粗心吧,这里是中文版的勘误页面,再版的时候估计会好很多。

趁着读书时的热情,做了一些小的demo来练习,在上一个demo中发现opera浏览器在处理xhtml标签的”disabled”属性时有一个bug。

事情是这样的,我在页面中有一个button元素,我希望它只能被点击一次,所以我在button的click事件中将它的”disabled”属性置为true。这样,点击一次之后,这个button就变成了灰色的不可用状态,我也确实无法再通过鼠标直接点击它了。事情到此都是没有问题的,接下来我希望能用键盘快捷键来控制这个button,于是我给它添加了”accesskey”属性,然后问题就来了,在我点击一次使得button变为不可用状态后,我还是可以通过accesskey来点击它。
我在其他的浏览器上进行了同样的实验,结果表明在我现有的浏览器 (FireFox3, IE8, Safari3/win, Chrome0.4) 上都没有这个bug,除了opera。我目前使用的是opera 9.61版,不过我估计opera以前的版本也存在同样的bug。

进一步实验后,发现opera不只是在处理”accesskey”的点击时有bug,而是在处理除了鼠标直接点击之外的所有其他方式时都存在这个bug。比如在另一个JavaScript脚本里调用这个已经被禁用的button的click函数,甚至通过tab获取button焦点之后连续点击回车,都可以绕过button的disabled属性而触发它的click事件。

我写了一个demo页面来演示这个bug:Button & accesskey

还有要注意的一点就是accesskey在不同的浏览器中的使用方法并不一样。Opera中是通过shift+esc调出accesskey菜单再按相应的accesskey,IE8、Safari3/win以及Chrome0.4则都是使用alt+accesskey。FireFox3中则默认是alt+shift+accesskey,这避免了与浏览器菜单快捷键的冲突,不过可以通过修改about:config的ui.key.contentAccess键值来更改,这个键值的具体含义如下:

  • 1 = Shift
  • 2 = Ctrl
  • 3 = Shift + Ctrl
  • 4 = Alt
  • 5 = Shift + Alt
  • 6 = Alt + Ctrl
  • 7 = Ctrl + Shift + Alt

另外,在做这个demo的时候还发现了IE在处理button按钮时和其他浏览器的不同。在JavaScript脚本中通过element.value来获取button的value属性的值,在IE中得到的是button的innerHTML值,而在其他浏览器中得到的是正确的value属性的值。在网上搜了一下,这个问题有不少人问,解决办法也有不少,有的人建议改用input标签,不过我觉得不符合语义化的要求。还有通过Javascript和xml来解决的,感觉太麻烦了。最后我决定使用button的title属性来存储我需要的值,没办法,妥协一下吧。

Popularity: 19% [?]

Tags: , , , ,