网站开发日志

2009年10月14日星期三

使用YUI Compressor给JavaScript和CSS瘦身

减小Javascript和CSS的体积有助于加快页面的加载速度。Javascript或者CSS的压缩器在英文里称为compressor,它主要是移除空格和注释来缩小体积。当然优秀的压缩器象YUI Compressor还具有打乱局部符号和优化代码等功能(特别针对JavaScript)。如果你的Javascript或者CSS本身就没有几行,那么你可能感受不到瘦身的效果;反之,通过压缩后的文件体积通常可以缩小40%-50%。

之前我已经用过一些在线工具来压缩网站的JavaScript和CSS代码,但是觉得用其来不是很方便。每次对Javascript和CSS稍作修改,都要把代码拷贝粘贴到在线工具里,然后在把压缩后的版本拷贝粘帖到本地保存。后来想自己网站上的Javascript和CSS本身体积就不是很大,就索性不压缩了,省得麻烦。最近在优化公司的网站代码的时候,决定对Javascript和CSS瘦身,用到了YUI Compressor。很早以前就听说YUI Compressor了,一直没有机会去使用它。这次使用后觉得很好用,故在这里推荐给大家。

我觉得YUI Compressor主要有3大优点:

  1. 同时支持Javascript和CSS的压缩。
  2. 用JAVA写的,可跨平台使用。它需要Java版本>=1.4,现在大部分机子应该都安装有Java,我在Window和Linux都试用过,没有出现任何问题。
  3. 压缩效果好。我分别用YUI Compressor和Dean Edwards的在线Javascript Compressor对一个文件大小为8.341K的javascript进行压缩,YUI Compressor生成的文件大小为5.535K, 而在线Javascript Compressor生成的文件大小为5.985K。虽然Dean Edwards的JS Compressor还可以选择 Base62 encode(编码)和Shrink variable(收缩变量),从而得到更小体积的文件(4.835K)。按照我的理解YUI Compressor是一种Minifier(缩小器),正如文章开头提到的它主要是移除空格和注释来缩小体积,虽然它在一定程度上还缩小变量名和移除不必要的代码,但是比较保守。而Dean Edwards的JS Compressor可以称之为Packer(打包机),它使用了不同的概念和更加先进的打包算法(例如:Shrink variable),虽然它达到更小的体积,但是在性能上要打些折扣,因为客户端需要一定的时间去解压和使用它。

使用YUI Compressor,可以说是非常简单。

  1. 首先到YUI Library官方下载页面,记住该页面有很多YUI的库,你要下载的是YUI Compressor。
  2. 然后解压下载文件,记住直接可以用的是build文件夹下的yuicompressor-2.4.2.jar,另外下载的文件里还包含源代码、文档等等。
  3. 把yuicompressor-2.4.2.jar拷贝到某个文件目录下,比如C:/tools(windows) 或者 /usr/adam/tools(Linux)。
  4. 最后用下面的命令:
//压缩Javascript
java -jar /path/to/yuicompressor-2.4.2.jar example.js -o example.min.js
#例如:java -jar c:\tools\yuicompressor-2.4.2.jar 61dh.js -o 61dh.min.js
//压缩CSS
java -jar /path/to/yuicompressor-2.4.2.jar example.css -o example.min.css
#例如:java -jar /usr/adam/tools/yuicompressor-2.4.2.jar 61dh.css -o 61dh.min.css

更多的用法,请参考YUI Compressor的官方网页

标签: , ,

2009年10月5日星期一

JavaScript在IE6下报错'expected identifier, string or number'

最近一段时间在项目开发里用了许多jQuery的插件,有机会一定在本日志里写一些心得。今天不准备介绍jQuery插件,而是要介绍我在使用jQuery表单插件时碰到的一个问题。jQuery表单插件应该算是家喻户晓的jQury插件,我过去一直没有用它,因为jQuery插件一般体积都挺大的,如果只是需要一些简单的功能,我一般都是自己写。比如jQuery表单的处理,我在日志里介绍过,一般情况下懂的这些基本概念,就可以完成大部分任务了。但是这次的情况比较特别,自己写比较麻烦,而且一定不如jQuery表单插件有效率。

我把下列代码加入我的HTML模板文件:

<script type="text/javascript">
$(document).ready(function() {
    var options = {
        target: '.content',
        //beforeSubmit:  showRequest,  // pre-submit callback 
        //success:       showResponse  // post-submit callback 
    };
    // bind to the form's submit event
    $('#bill_addr_form').submit(function() {
        $(this).ajaxSubmit(options);
        return false;
    });
});
</script>

我把选项(options)里的beforeSubmit 和success注释掉,代码在Forefox和IE8下工作正常,但是在IE6下报错:

expected identifier, string or number

上网搜了一下,发现这只是一个很低级的错误。如果变量options有多个选项,那么我们可以用逗号分开;但是最后一个选项后不可以有逗号。虽然IE8和Firefox可以忽略这个逗号,但是IE6下会报错(据说IE7下也会报错)

解决方法很简单,把多余的逗号删除就可以了。

var options = {
        target: '.content' //注意不可以加逗号
    };

标签: ,

2009年6月29日星期一

Greasemonkey 控制链接的打开方式

如果你对HTML有所认识,你一定知道链接里有个属性叫target,当这个值被设"_blank",该链接被点击后就会在新窗口(或者新标签)里打开;当这个值被设为"_self"或者不做设置时,该链接被点击后就在同一框架或窗口中打开。中国的网站设计倾向于使用第一种方法,因此当你在一个网站上多点几个链接(例如百度知道), 你的浏览器就会被这个网站'淹没'。相反,国外的网站倾向于使用第二种(好像这被认为是一种标准)。个人比较认同第二种方法,但是这种方法也有一种弊端,比如我在使用美味书签(delicious), 点击其中的一个书签后进入另外一个网站(在同一个窗口),当离开这个网站的时候,我会自然而然地关闭窗口,这么一来美味书签也被关闭了。因此我觉得合理的做法应该是站内的链接在同一窗口打开,而站外的链接在新窗口打开。我在创建自己网站的页面时,都会尽量遵从这条规则,虽然我也有遗漏的时候,但是别人的网站我就根本无法控制了。

好在我们还是可以借助一个工具来解决这个问题,它就是Greasemoneky。不知道什么是Greasemonkey?它是Firefox的一个插件,你可以到这里下载。简单的讲Greasemonkey提供一个接口,可以导入用户自行创建脚本来控制页面的显示,就比如说我下面要介绍的:控制页面链接的打开方式。当然借助Greasemonkey你可以做的东西可多了,如果你有兴趣,可以到这里看看。

言归正传,下面是实现"站内的链接在同一窗口打开,而站外的链接在新窗口打开"的步骤:

1. 使用Firefox,据我所知Greasemonkey只支持Firefox。还没有Firefox?请点击下载:Spread Firefox Affiliate Button

2. 在Firefox里点击这里安装Greasemonkey。

3. 重启Firefox后,你会在Firefox的右下角看到一个可爱的猴头,那就是Greasemonkey。

4. 请确保Greasmonkey处于开启状态(金黄色的猴头代表开启,灰色的猴头代表关闭), 然后点击这里安装用户脚本。

5. 刷新页面,你就可以实现站内的链接在同一窗口打开,而站外的链接在新窗口打开。

有问题?请留言。

标签:

2009年4月6日星期一

jQuery 制作迷你背词汇工具

jQuery提供的Load的函数可能可以说是实现ajax功能的最轻巧的方法。我在博客里介绍了很多,请参考这些文章。今天我要介绍的是load()函数的一个实际运用,希望你读完以后会觉得它很简单、而且很实用。下面是一个类似金山词霸里背单词的小工具,它和滚动文字(图片)的效果差不多,但是用到的是ajax功能,也就是涉及到服务器端的脚本的执行。

loading ...

首先我创建的一个文本文件包含有我要背诵的英文词汇,然后是下面的PHP代码,用来读取词汇,并且随机返回一个词汇。

<?php
$buffer = array();
$handle = @fopen("toefl_listen.txt", "r");
if ($handle) {
    while (!feof($handle)) {
        array_push ($buffer, fgets($handle, 4096));
    }
    fclose($handle);
}
echo $buffer[array_rand($buffer)];
?>

最后是通过下面的Javascript脚本加上一点Ajax技术,调用服务器端的PHP代码,并把返回结果在特定DIV里显示。因为是循环播放,所以我用到了setInterval()函数。此外还使用clearInterval()函数,实现鼠标滑过 - 暂定播放的功能。

<script>
  $(document).ready(function()
  {
   //没隔3秒调用服务器端的php文件
   var refreshId = setInterval(function()
   {
    $('#timeval').load('reflesh.php');
   }, 3000);
   //鼠标滑过 - 暂停播放
   $("#timeval").mouseover(function()
   {
      clearInterval(refreshId);
   });
   $("#timeval").mouseout(function(){
      refreshId = setInterval(function()
      {
      $('#timeval').load('reflesh.php');
      }, 3000);
   });
  });
</script>
我觉得上面介绍的间隔一定时间调用服务器的代码,其扩展性还是挺大的。我这里只是使用它来读取一个简单的文本文件,你还可以用它来调用数据库,来实现对某个数据的实时更新。

标签: , ,

2009年3月26日星期四

cookie

cookie在网站开发里运用的很多,特别是购物网站。cookie可以分为两种,会话cookie(session cookie) 和持久cookie(presistent cookie)。在PHP里,当一个会话开始,服务器会在客户端的浏览器里设置一个cookie用来保存PHP session ID,而cookie的内容被存放在服务器端。会话cookie的有效期通常是持续到会话结束,也就是当你关闭浏览器后,但是你也可以在PHP.INI里改变会话的有效期。通常我们说的cookie是指持久cookie,它是完全保存在客户端的浏览器里,其有效期是在设置的时候定义好。在这篇文章里,我准备介绍持久cookie(以下简称cookie)。

cookie的运用涉及到信息的保存和提取,当然我们可以使用数据库来完成这项工作,但是对于一些小信息,比如email,使用cookie显得更加快捷。cookie是存在客户端的,因此首先想到的是使用Javascript来设置和提取cookie。W3Cschool上提供两个函数,使用它们基本上就可以满足我们的需要。我把它们稍作修改,如下:

// 全局变量
domain    = '.61dh.com'; //如果不设代表当前页面的域名
path    = '/'; //通常使用根目录,当然你可以可特指一个路径
secure    = 0; //对于SSL网站(https),需要设置安全cookie,这时可以把值设为‘1’
//setCookie,设置cookie,需要三个变量,cookie名称,cookie值,和有效时长
function setCookie(c_name,value,expiredays){
  var exdate=new Date();
  exdate.setDate(exdate.getDate()+expiredays);
  document.cookie=c_name+ "=" +escape(value)+
  ((domain.length > 0) ? ';domain=' + domain : '') +
  ((path) ? ';path=' + path : '') +
  ((secure) ? ';secure' : '') +
  ((expiredays==null) ? "" : ";expires="+exdate.toGMTString());
}
//getCookie,获取相关cookie的值
function getCookie(c_name){
  if (document.cookie.length>0){
    c_start=document.cookie.indexOf(c_name + "=");
    if (c_start!=-1){ 
      c_start=c_start + c_name.length+1; 
      c_end=document.cookie.indexOf(";",c_start);
      if (c_end==-1) c_end=document.cookie.length;
      return unescape(document.cookie.substring(c_start,c_end));
    } 
  }
  return "";
}

有了上面的函数,你就可以根据需要来保存一个数据(setCookie),然后再根据需要取回数据(getCookie), 例如:

setCookie('email',adamcai@live.com,365);//保存email,有效期365天
var email = getCookie('email');//获取email

另外一种方法是使用PHP,这要根据实际需要,有时你可能会觉得使用PHP更方便。PHP自带有函数:

setcookie(name,value,expire,path,domain,secure)
  • name:必须,cookie名称
  • value:必须,cookie值
  • expire:任择。指定的cookie时到期。单位是秒,例如: 3600 * 24 * 30将设置Cookie过期30天。如果此参数没有设置时,cookie将在会话结束时(当浏览器关闭)到期,
  • path:任择。指定服务器路径的Cookie如果设置为“ / ”时, cookie将可在整个域内有效。如果设置为“ /测试/ ”时, cookie将只在测试目录及所有子目录有效。默认值是当前目录。
  • domain:任择。指定域名的cookie 。为了使现有的cookie的所有子网域内有效,你应该将其设定为 ".example.com"。如果不设置,将使用当前页的域名。
  • secure:任择。指定是否cookie应用于安全的HTTPS连接。如果设为true,那么cookie将只可以在安全连接存在的情况下设定。默认值为false 。

$_COOKIE['name'] //用来获取cookie的值。

//设置cookie
setcookie("email","adamcai@live.com”, time()+3600*24); //时常为24小时
//获取cookie
if(isset($_COOKIE("email")){
  $email = $_COOKIE("email");
}

标签: ,

2009年3月22日星期日

document.ready还是不够快

我曾经在日志里介绍过jQuery的document.ready:

document.ready()和传统的方法<body onload=”load()”> 相似,不同的是onload()的方法是在页面加载完成后才发生,这包括DOM元素和其他页面元素(例如图片)的加载,因此,使用document.ready()方法的执行速度比onload()的方法要快。

document.ready()可以说是jQuery的一大特色,它不仅比传统的Javascript函数onload()要快,而且加上jQuery强大的选择器可以在不用修改HTML代码情况下(例如:不用在HTML标签加入onClick()函数来调用其它自定义Javascript函数)对Web页面中的各种元素和事件进行控制、实现和Web客户交互的作用。

可是有时document.ready()并非你想像的那么快,我在最近的一个project里就碰到这个问题。例如一个页面含有多个相似的链接,每一个链接的HTML代码大致如下:

<a rel="popin" href="/cart/?popin=yes&act=add&sku=xxx">
  <img src="/images/new/buynow.gif" border="0" />
</a> 

当这些链接被点击后,相对应的物品(sku)就会被加入购物篮,为让客户点击链接后不用离开当前页面,我使用了jQuery的ajax方法,从后台调用添加购物篮函数,然后返回xml响应,最后把xml携带的信息通过HTML层(layer)传递给客户。大致的jQuery+ajax代码如下:

$(document).ready(function(){
  $("a[rel^='popin']").click(function(){
    $.ajax({
      url: $(this).attr('href'),
      type: 'GET',
      dataType: 'xml',
      error: function(){
      alert('Error loading XML document');
    },
    success: function(xml){
      $('#cart_sum1').html($(xml).find('cart').text());
      $('#buynow-result').html($(xml).find('pop').text());
      $('#buynow-inform').show('slow');
      $('#cart_sum2').html($(xml).find('cart').text());        
    }
    });
    return false;
  });
});    

注意到我用了document.ready,试图在DOM ready的时候给这些链接(<a[rel^='popin'>)绑定点击事件控制。这在我的机子(windowxp+firefox3)里测试通过,但是在我老板的机子(redhat+firefox)上,有时会出现点击链接后跳出XML代码,原因很明显: 当她点击链接的时候,链接还没有被绑定事件控制,也就是说document.reday()还是不够快。

怎么解决?我有打算在链接代码里加入传统Javscript的onClick函数,这样当客户点击链接的时候,先调用onClick函数,然后在onClick函数里在调用ajax,应该就可以解决问题。今天想看看别人都是怎么解决这个问题,就用Google搜索了一下。找到这篇论坛问答,觉得说的挺有道理:

  • Using window.onload waits until the whole page is loaded.  (onload是在页面加载后起作用)
  • Using document.ready waits until the whole DOM is ready (document.ready是在DOM 准备好后起作用)
  • Having the script at the end of the body without document.ready, that doesn't wait. (把去掉document.ready的jQuery代码放在</body>前,无需等待)

准备明天到公司试试这种方法。其实把Javascript放在</body>前的说法以前也有看到过,Google的Analytics代码就建议放在</body>前。

Updated:(3/24/08)

经测试,第三种方法也不好用,主要问题是在页面没有完全加载完毕时,链接就已经被点击,这时</body>前的那一段jQuery代码还没有被加载,因此链接还没有被绑定ajax事件控制。

最终的解决办法是,把上面那段jQuery代码写出一个函数,反正header里,然后结合传统Javascript onClick函数,在链接被点击时直接调用header里函数。具体更改如下:

1. jQuery函数 (这段函数被放在header里)

function ajax_add(url_str){//把jquery代码写成一个函数
   $.ajax({
     url: url_str,
     type: 'GET',
     dataType: 'xml',
     //timeout: 5000,
     error: function(){
       alert('Error loading XML document');
     },
     success: function(xml){
       $('#cart_sum1').html($(xml).find('cart').text());
       $('#buynow-result').html($(xml).find('pop').text());
       $('#buynow-inform').show('slow');
       $('#cart_sum2').html($(xml).find('cart').text());
     }
   });
}

2. 链接代码:

<a onClick="add_ajax('/cart/?popin=yes&act=add&sku=xxx')" href="#">
  <img src="/images/new/buynow.gif" border="0" />
</a> 
注意:链接直接加入onClick事件控制,而不在页面加载后绑定事件控制。这样就可以避免链接被点击时,事件还没有绑定的问题。

标签: ,

2009年3月16日星期一

使用jQuery+jSon+delicious创建'相关文章'

我的日志引擎使用的是Google的Blooger,然后FTP到61dh.com的所属服务器。所有页面都是HTML,没有使用数据库。因此和Wordpress相比之下,功能要少了很多。但是每次发布新文章,我都会把文章的加到delicious(美味书签)。这么一来,借助delicous提供的扩展接口,我给日志添加了一些功能。我在日志里曾经介绍过,如何使用美味书签创建日志分类。昨天我又给日志添加了'相关文章'的功能,这次使用到的是delicious提供的JSON Feeds。

通过http://feeds.delicious.com/v2/json/61dh,可以得到61dh.com的最新15个日志的Feeds ,Delicious提供的JSON Feed不仅仅是罗列保存的书签链接,而且还可以输出具有相同标签的链接。因此只要根据一篇日志的标签信息,就可以找出具有相同标签的帖子信息了。例如:通过http://feeds.delicious.com/v2/json/61dh/css+html 可以找出标签是css和html的文章链接。 Feeds输出是JSON格式,大致如下:

[
{"u":"http:\/\/www.61dh.com\/blog\/2009\/03\/jquery-ajax-xml.html",
 "d":"jQuery ajax - \u5982\u4f55\u4f7f\u7528XML",
 "t":["jQuery","PHP","ajax"],
 "dt":"2009-03-09T03:14:29Z",
 "n":"",
 "a":"61dh"
},
{...}, //第二篇文章
... //第三、第四...
]

上面,我只列出一个完整文章的JSON对象格式,很显然不同的JSON Feed有着不同的Object Attributes。在Delicious提供的JSON feed里,每个Object包含有6个属性:

  • 1. u - 链接URL,在这里代表每一篇日志的永久地址
  • 2. d - 链接名称,在这里代表日志的标题
  • 3. t - 链接标签,在这里代表日志的标签
  • 3. dt - 链接代表加入时间
  • 4. n - 链接注释,在这里是空白
  • 5. a - 书签的所有者, 这里是61dh

知道了JSON的输出格式后,就可以使用jQuery的getJSON()方法来处理输出结果。这里我们感兴趣的是相关文章的地址和标题,也就是u和d。jQuery代码如下:

$.getJSON("http://feeds.delicious.com/v2/json/61dh/CSS+HTML+Jquery?callback=?",
  function(data){//data这里是JSON对象,它可以是由多个JSON对象组成
    $.each(data, function(i,item){//每一个对象包含有一个日志的信息
      //item.u 就是日志的地址;item.d就是日志的标题
      $('<a href='+item.u+'>'+item.d+'</a><br />').appendTo("#related-post");
        if ( i == 8 ) return false; //默认下,JSON feed 提供15个链接,这里我只取8个
      });
  });

注意:.getJSON的第一个变量是可以提供JSON格式输出的URL,URL的参数要根据实际情况而定,delicious提供的JSON,使用callback作为参数名:callback=?, jQuery 将自动替换 ? 为正确的函数名,以执行回调函数。

上面的代码可以把标签为CSS、HTML和jQuery的文章链接找出,但是就这么写还不行,相对一篇文章,我们要自动找出该文章的所属的标签,然后动态的加入到JSON URL上。另外还有考虑找不到结果(标签有误) 和只有一个结果(找到文章本身)的情况。所以完整的代码如下:

 <script type="text/javascript">    
  //改函数用于判断JSON object所包含的子object个数
  function getOnum(object) {
    var num = 0;
    for(var i in object) { num ++; }
    return num;
  }
  $(document).ready(function(){
    var cat ="";
    $(".blogger-labels a[rel='tag']").each(function(){ //找出标签的名称
      cat += $(this).text() + '+'; //标签用+分隔
    });
    cat = cat.slice(0,-1); //去掉最后一个‘+’号
    
  $.getJSON("http://feeds.delicious.com/v2/json/61dh/"+cat+"?callback=?",
  function(data){
    var Onum = getOnum (data); 
    if ((Onum == 0) || (Onum == 1)) //结果为0或者1
      $('<p>找不到相关文章</p>').appendTo("#related-post");
    else{ //结果 > 1
      $('<ul>').appendTo("#related-post");
      $.each(data, function(i,item){
      $('<li><a href='+item.u+'>'+item.d+'</a></li>').appendTo("#related-post");
      if ( i == 8 ) return false;
      });
      $('</ul>').appendTo("#related-post");
    }
  });
});
</script>
<div id="related-post">
  <h4>相关文章: </h4>
</div> 

除了getJSON,上面的代码里还有一些小知识点:

  • 1. 如何判断Object是否为空: getOnum()函数
  • 2. jQuery selector - 选择所有class name 为blogger-labels区内的rel属性为tag的<a>: $(".blogger-labels a[rel='tag']") -
  • 3. 去除字符串的最后一个字符:cat = cat.slice(0,-1);
  • 4. 往一个HTML元素里添加加HTML代码:appendTo("#related-post")

标签: , ,

2009年3月15日星期日

jQuery对表单处理的三个实例

我花了整整一个星期时间,更新了公司网站的购物结帐系统。主要增加的功能是允许用户在多个Billing Address(或者Shipping Address)进行选择和编辑,所有这些功能都是在同一个页面完成。我运用了jQuery代码进行ajax调用和表单处理。在这篇文章里我准备介绍三个jQuery对表单元素处理的实际运用,和我在jQuery基础里提到的 - 处理表单元素相比,这些运用要相对灵活一点。

1. 清空表单元素

使用传统Javascript提供的reset()方法可以把表单所有元素重设为初始值(或者默认值),但是有时reset()并非你要的,比如说,表单的初始值使用的是预设值(非空),或者你只是想清空特定表单元素,这时候使用reset()就行不通了。

HTML表单代码

<form>
  First name: <input type="text" name="firstname" value="Adam"> <br />
  Last name: <input type="text" name="lastname" value="Cai"> <br />
  Accoutn ID: <input type="text" name="acc_id" value ="123">
</form>

使用以下jQuery代码,可以清空所有类型为'text'的input表单控件,但是除了name为'acc_id'的input;并且把name=acc_id的输入框设置为0

$("input[type='text']").each(function(){
  if (this.name != 'acc_id') $(this).val("");
  else $(this).val("0");
});

2. 下拉框的选择/清除选择

HTML下拉框代码:

<form action="">
  <select name="cars">
    <option value="0">前选择车的牌子</option>
    <option value="volvo">沃尔沃</option>
    <option value="honda">本田</option>
    <option value="toyota">丰田</option>
    <option value="audi">奥迪</option>
  </select>
</form>

如果每个选项(option)都没有属性'selected',那么第一选项将被选中。使用下面的jQuery代码,可以先选中本田,接下来,如果要选择丰田,可以先清除选择,然后使用同样的方法进行再选。

$("select[name='cars'] option[value='toyota']").attr("selected","selected"); 
//接下来,如果要选择丰田,可以先清除选择,然后使用同样的方法进行选择
$("select[name='cars'] :selected").removeAttr("selected");
$("select[name='cars'] option[value='honda']").attr("selected","selected"); 

另外我们还可以使用传统的Javascript选择方法:selectedIndex,要注意:下拉框的选项索引(index)是从0开始,因此在上述表单里,selectedIndex=2 - 代表本田车被选中。具体写法如下:

document.form[0].cars.selectedIndex = 2; //选择本田车
//这里用form[0],代表页面的第一个form,如果FORM有特定的名字,那么可以使用form的名字代替
//例如 form的名为:myCar,
document.myCar.cars.selectedIndex = 0; //恢复默认值

3.选择单选框(radio)和复选框(checkbox)

不论是单选框还是复选框,我们都可以使用checked的属性,设置值为true代表选择;设置值为false代表反选择。

HTML代码:

<input type="checkbox" name="fruit" value ="apple">苹果<br>
<input type="checkbox" name="fruit" value ="orange">桔子<br>
<input type="checkbox" name="fruit" value ="mango">芒果<br>

使用下面的jQuery代码,可以把桔子选中。

$("input[type='checkbox']").each(function(){
  if ($(this).val() == 'orange')
  $(this).attr('checked', true);
});

标签: ,

2009年2月15日星期日

jQuery 动画卷页

当一个网页内容很长,为了方便读者返回页首,我们通常会在网页底部加上个链接并且把链接的href属性设为'#';当用户点击这个链接,页面就会快速返回到顶端,同时当前链接名后会加上一个‘#’。你是否觉得这种卷页方法有些生硬?jQuery提供一种动画卷页方法,简单易用。先看看效果 (拉到页面底部点击'返回页首'),还不错吧?:-) 接下来我将介绍如何实现这一特效。

首先给这些‘返回页首’的链接加上个Class:

<a href="#" class="backtotop" target="_self">返回页首↑</a>
<!--把所有返回页首的链接加上class,例如:backtotop-->

然后加入下面jQuery代码,你可以把这行代码放在</body>前,或者其它位置。当然你还要在<head>里包含jQuery库文件。(如果你对jQuery一无所知,那么建议阅读我写的jQuery基础系列文章)

jQuery(document).ready(function() {
   jQuery('.backtotop').click(function(){
     jQuery('html').animate({scrollTop:0}, 'slow');
}

就这么简单?基本上是!但是使用jQuery('html')在Safari和Chrome(记得在什么地方看到过:chrome使用的是safari的核)下选择不到我们要的对象。好在在这两种浏览器下,我们可以使用jQuery('body')来替代。因此为了让代码的兼容性更强,我们可以加入对浏览器的判断,这里使用到jQuery提供jQuery.browser的方法。注意: 在jQuery1.3里,这种方法已经不建议使用。jQuery1.3新增jQuery.support的方法,用于展示不同浏览器各自特性和bug的属性集合,也就是说jQuery1.3不在建议对浏览器进行判断,而建议直接对某个特性进行判断。但是我不知道这个选择器的问题应该属于哪个特性,因此,我还是使用旧的方法。(jQuery.browser的方法在jQuery1.3里还是支持的)

jQuery(document).ready(function() {
  jQuery('.backtotop').click(function(){
    if(jQuery.browser.safari) {//这里判断浏览器是否为safari
      jQuery('body').animate({scrollTop:0}, 'slow');
      return false;//返回false可以避免在原链接后加上#
    }
    else{
      jQuery('html').animate({scrollTop:0}, 'slow');
      return false;
    }
  });
});

这上述代码里,我用到jQuery('body').animate({scrollTop:0}, 'slow'); 我们可以根据实际需要更改卷页的速度,你可以用'slow'、'fast'、或者用具体数字,例如1000(代表一秒,注意用具体数字时不用加单引号)。 另外,{scrollTop:0}表示返回页首,如果你只是想让页面卷到你要的特定位置,我们可以使用标签(ID)的方法,例如:要移到某个ID为'myID'的区域(<div id="myID">....</div>)顶部,我们可以使用类似的方法,但是要先计算这个区域距离页首的距离,代码如下:

jQuery('body').animate({scrollTop:jQuery('#myID').offset().top}, 'slow');
//jQuery('#myID').offset().top可以计算ID为myID的区域里页首的距离

演示

标签: ,

2009年1月25日星期日

jQuery基础 - 如何判断页面元素存在与否

在传统的Javascript里,当我们对某个页面元素进行某种操作前,最好先判断这个元素是否存在。原因是对一个不存在的元素进行操作是不允许的。例如:

document.getElementById("someID").innerText("hi");

如果ID为"someID"的元素不存在,我们将得到Javascript运行错误:document.getElementById("someID") is null

正确的写法应该是:

obj = document.getElementById("someID");
if (obj){
  obj.innerText("hi");
}

那么在jQuery,我们如何判断页面元素存在与否呢?如果参照上面的传统Javascript的写法,我们第一个想到的办法一定是:

if ($("#someID")){
  $("#someID").text("hi");
}

可是这么写是不对的!因为jQuery对象永远都有返回值,所以$("someID")总是TRUE,IF语句没有起到任何判断作用。正确的写法应该是:

if ( $("#someID").length > 0 ) {
$("#someID").text("hi");
}
注意:判断某个页面元素存在与否在jQuery实际上是没有必要的,jQuery本身会忽略对一个不存在的元素进行操作,并且不会报错。

标签: , ,

2009年1月24日星期六

jQuery基础 - 改变CSS样式

我在前面的文章里介绍了 - 如何添加/移除CSS类,那种方法需要先定义好CSS类,然后针对"类"来改变某个元素的样式。本文要介绍的是另外一种改变CSS样式的方法 - 直接添加样式法。使用CSS样式一般有两种方法:一种是在Head里引用外部定义了CSS样式的文件;另一种是直接在HTML元素里嵌入样式。如何添加/移除CSS类一文里介绍的方法通常需要把CSS类定义在外部CSS样式文件里;而本文介绍的方法就类似于嵌入式CSS。

jQuery提供css()的方法来实现嵌入式改变元素样式,css()方法在使用上具有多样性。其中一种接受两个输入参数:样式属性和样式值,它们之间用逗号分开。比如我们要改变链接颜色,我们可以使用下面的代码:

$("#61dh a").css('color','#123456');
//这里选择器‘$("#61dh a")’表示ID为‘#61dh’的元素下的所有链接。
//.css(‘color’,'#123456');表示把颜色设为'#123456'

如果我们需要改变多个样式属性,我们可以先定义属性变量,然后直接赋值给css()方法。示例如下:

var divcss = {
  background: '#EEE',
      width: '478px',
      margin: '10px 0 0',
      padding: '5px 10px',
      border: '1px solid #CCC'
};
$("#result").css(divcss);
//这里我们先定义了一个CSS样式属性变量‘divcss’,这类似于建立一个外部CSS文件。
//然后通过jQuery提供的css()方法,把属性赋给ID为'#result'的DIV。

另外jQuery提供的css()方法还可以用来查看某个元素的css属性值。例如,我们想查看链接的颜色,可以使用下面的代码:

$("#61dh a").css("color")
//和第一个例子相似,但是这里我们只传递一个参数(样式属性)

最后要介绍的是如何设置鼠标划过后的链接样式(比如: 颜色)。我们无法使用选择器直接选择鼠标划过状态下的链接,也就是说$("a:hover")是不成立的。因此我们需要用到jQuery提供的事件类方法 - hover()。值得注意的是,hover()方法需要定义两个函数,一个是鼠标划过时;另一个是鼠标划过后。具体方法如下:

$("#61dh a").css('color','#123456');
  $("#61dh a").hover(function(){
  $(this).css('color','#999');
  },
  function(){
  $(this).css('color','#123456');
});
//hover()方法的两个函数使用用逗号分隔

你或许注意到这种方法一点都不简洁(违背了jQuery的宗旨),其实jQuery提供的hover()方法不是用来改变CSS样式的。在实际运用中,建议使用如何添加/移除CSS类一文提到的方法来改变鼠标划过的链接样式。

演示+代码

标签: , ,

2009年1月20日星期二

jQuery基础 - 如何添加/移除CSS类

在网页设计中,我们常常要使用Javascript来改变页面元素的样式。其中一种办法是改变页面元素的CSS类(Class),这在传统的Javascript里,我们通常是通过处理HTML Dom的classname特性来实现的;而jQuery里提供三种方法来实现这个功能,虽然它们和传统方法的思想相通,但是却节省了许多代码。还是那句话 - “jQuery让JavaScript代码变得简洁!”

1. addClass() - 添加CSS类

$("#target").addClass("newClass");
//#target 指的是需要添加样式的元素的ID
//newClass 指的是CSS类的名称

2. removeClass() - 移除CSS类

$("#target").removeClass("oldClass");
//#target 指的是需要移除CSS类的元素的ID
//oldClass 指的是CSS类的名称

3. toggleClass() - 添加或者移除CSS类:如果CSS类已经存在,它将被移除;相反,如果CSS类不存在,它将被加上。

$("#target").toggleClass("newClass")
//如果ID为“target”的元素已经定义了CSS样式,它将被移除;
//反之,CSS类”newClass“将被赋给该ID。

在实际运用中,我们常常先定义好这些CSS类,然后通过Javascript事件触发(比如点击某个链接)来改变页面元素样式。此外,jQuery还提供一种方法 hasClass("className"),用来判断某个元素是否已经被赋予某个CSS类。

演示+代码

标签: , ,

2009年1月15日星期四

jQuery基础 - 树形结构的选择器

在前面的文章里,我介绍了jQuery选择器。在那篇文章里介绍的选择器的方法,不管是通过"id"还是通过"class”,它们都是针对某个元素本身,这和常规的Javascript方法(getElementById以及getElementByName)的思想相似。在这篇文章里我要介绍jQuery提供的另外一种类型的选择器,我称之为树形结构的选择器。树形结构里的节点,如果它不是根部,也不是末枝,那么它一定有父母和孩子。DOM结构其实也是一种树形结构,jQuery提供的树形选择器可以用来选择DOM Tree里的节点。这些树形选择器的方法包括:children(), parent(), parents(), next(), prev(), siblings().

  • 选择某个元素的"孩子" - children()
<ul id="parent">
  <li id="son1">第一列</li>
  <li id="son2">第二列</li>
  <li id="son3">第三列</li>
</ul>
$("#parent").children().length //得到所有的”孩子“(li)的个数,“3”
$("#parent").children("#son1").text(); //得到第一个”孩子“(li)的值 - “第一列” 
  • 选择某个元素的“父母” - parent()
<ul id="parent">
  <li id="son1">第一列</li>
  <li id="son2">第二列</li>
  <li id="son3">第三列</li>
</ul>
$("#son1").parent().attr("id");//得到ul的ID - "parent"
  • 选择某个元素的“祖先”-parents() (注意:一级一级向上选择直到<html>)
<div id="grand">
  <ul id="parent">
    <li id="son1">第一列</li>
    <li id="son2">第二列</li>
    <li id="son3">第三列</li>
  </ul>
</div>
$("#son2").parents().each(function(i){
  if(i<3) //只显示3代祖先
  alert($(this).html());
});
  • 选择某个元素的“弟弟” - next()
<ul id="parent">
  <li id="son1">第一列</li>
  <li id="son2">第二列</li>
  <li id="son3">第三列</li>
</ul>
$("#son2").next().text(); //选择#son3
  • 选择某个元素的“哥哥” - prev()
<ul id="parent">
  <li id="son1">第一列</li>
  <li id="son2">第二列</li>
  <li id="son3">第三列</li>
</ul>
$("#son2").prev().text(); //选择#son1
  • 选择某个元素的“兄弟” - siblings()
<ul id="parent">
  <li id="son1">第一列</li>
  <li id="son2">第二列</li>
  <li id="son3">第三列</li>
</ul>
$("#son2").siblings().text(); //选择#son1和#son3
演示以及代码

标签: , ,