破除对ASP.NET的误解

Posted on 8月 28th, 2008 in 我学, 我想 | No Comments »

首先我并不想辩论ASP.NET是否优于PHP或Ruby on Rails,不过我很乐意去破除一些对ASP.NET的误解……

以下是对ASP.NET普遍性的误解:

  1. ASP.NET很慢;
  2. ASP.NET生成不规范的XHTML代码;
  3. ASP.NET验证器只能在IE下生效;
  4. ASP.NET尽生成些丑陋的表格代码;
  5. ASP.NET只不过是将控件拖来拖去;
  6. ASP.NET除了SQL Server,其它的数据库都不买帐;
  7. ASP.NET不能使用友好的URL。

够了,看起来再也没有比这些更糟糕的了……

ASP.NET很慢

这是错误的看法。如果之前未进行预编译,那么当一个ASP.NET应用程序第一次被访问时将会被动态编译。编译之后的应用请求将快得多。

ASP.NET生成不规范的XHTML代码

事实上,在ASP.NET 2.0之后版本中,所生成的代码是规范的XHTML代码。

ASP.NET验证器只能在IE下生效

服务器端的验证处理想必与浏览器无关,但客户端的验证处理是兼容当前流行的任何浏览器的。

ASP.NET尽生成些丑陋的表格代码

不否认一些控件会输出表格填充,然而可以利用ASP.NET的可扩展特性就控件编写自己的适配器,使控件生成清洁简化的代码。实际上不须劳烦自己,可以去下载一套强大而且免费的解决方案

ASP.NET只不过是将控件拖来拖去

尽管Visual Studio允许从工具盒中拖出控件放置在页面中并生成必要的代码,但仍然可以自己编写代码,智能提示或帮助信息会起到很大的作用。控件拖放与设置以及一些可视化的操作都会在源视图里清楚地观察到,随时等待进一步的修改。

ASP.NET除了SQL Server,其它的数据库都不买帐

可以使用.NET的数据提供程序提供的任何数据库支持。目前能找到的数据提供程序为MySql,Oracle,DB2,PostgreSQL,Informix,Sybase,Sqlite。

ASP.NET不能使用友好的URL

只要查阅一些教程和实例就明白了。还有同样为IIS7提供的mod_rewrite方式重写URL的模块

ASP.NET MVC框架

若要100%地控制HTML代码,那么就一定要看看ASP.NET MVC框架

ASP.NET MVC结合jQuery插件进行数据验证

Posted on 8月 14th, 2008 in 我做, 我学 | No Comments »

jQuery Validation是一个强大的数据验证插件,该插件支持“validation rule”即验证规则,规则将对表单内的输入控件进行控制或约束,譬如“本项必填”,“本项不能少于n个字符”,或者“这不是一个有效的email地址” 等等。这些规则大多数和asp.net本身的验证控件类似。遗憾的是asp.net本身的验证控件不能在MVC框架下工作,因为服务器端控件受页面的 ViewState限制,而MVC框架是没有ViewState特性的……

一条规则有两种方式应用到输入框中:

1,声明,在输入框中设置class属性。

<input name=”email” id=”email” maxlength=”60″ class=”required email” type=”text”/>

可以看到标记中的class属性被设为“required”和“email”,这表示该输入框是必填的和被约束为合法email字符串内容的的规则。这种多个规则用于一个区域的形式必须要由一个空格符分开。

2,为规则指定脚本。

<script type=”text/javascript”>
$(document).ready(function(){
$(”#form-sign-up”).validate( {
rules: {
email: {
required: true,
email: true
},
messages: {
email: {
required: “Please provide an email”,
email: “Please provide a valid email”
} });
});
</script>

指定id为“form-sign-up”的表单容器里的id为“email”的输入框的规则,并且还设定了当验证用户输入失败时所显示的相应的提示信息。这些提示信息可以在脚本中的“messages”部分里进行自定义设置。提示信息是可选项,jQuery Validation插件提供了一套预先定义的提示信息。如果想提高用户体验效果,建议设置更友好的提示信息。

最后还有一种更有趣更重要的规则方式就是“remote”即“远程规则”,也可以称其为“服务器端验证”(上面的验证都是在客户浏览器端完成)。验证处理在服务器端进行,常用于用户名是否存在之类验证,很重要。AJAX形式执行远程的验证处理,可以使用MVC的控制器方法。

<script type=”text/javascript”>
$(document).ready(function(){
$(”#form-sign-up”).validate( {
rules: {
login: {
required: true,
remote: ‘<%=Url.Action(”IsLoginAvailable”, “Accounts”) %>’
}
},
messages: {
login: {
required: “Please provide an alias”,
remote: jQuery.format(”{0} is already in use”)
}
} });
});
</script>

在服务器控制器端唯一的要求就是Json结果返回验证结果。在MVC框架中是很容易做到的:

public JsonResult IsLoginAvailable(string login)
{
JsonResult result = new JsonResult();
if (login == “boho”)
result.Data = false;
else
result.Data = true;
return result;
}

在上面的处理中,如果输入框输入的数据为”boho”,验证失败,并且用户会看到一条错误消息“boho is already in use”

错误信息的样式:

label.error {
display: block;
color: red;
font-style: italic;
font-weight: normal;
}
input.error {
border: 2px solid red;
}
td.field input.error, td.field select.error, tr.errorRow td.field input,tr.errorRow td.field select {
border: 2px solid red;
background-color: #FFFFD5;
margin: 0px;
color: red;
}

在这可以下载示例代码

很Twitter…

Posted on 8月 4th, 2008 in 我玩 | 2 Comments »

不知多久,总之很久。好像是包子发给我看的一段FLASH。如今看来很Twitter……音量开大点……

AJAX中保持浏览器历史

Posted on 8月 1st, 2008 in 我学, 我译 | No Comments »

如果使用AJAX,浏览器的历史按钮是不起作用的,事实上前进和后退只作用于完整的页面而不能用于AJAX的每一个步骤。对于惯用这些功能的用户来说简直是噩梦……

值得庆幸的是AJAX具有识别浏览器浏览历史点的相关能力,它能让浏览器追踪AJAX的步骤并且将这些步骤运用到前进和后退功能里。

先通过一个例子来了解浏览器的历史点是如何工作的。页面中有一个显示公司部门的下拉列表框,选择一个部门,就会显示隶属该部门的雇员姓名的列表框,选择其中一个雇员就会列出该雇员的资料,如姓名,email,薪水等等。雇员信息保存在Employee类中。

public class Employee
{
    public string Name { get; set; }
    public string Dept { get; set;}
    public string Email { get; set; }
    public int Salary { get; set; }
}

ASPX页面有三个UpdatePanel,如下:

    <asp:ScriptManager ID=”SManager” runat=”server”></asp:ScriptManager>
        <asp:UpdatePanel ID=”DeptUpdPanel” runat=”server”>
            <ContentTemplate>
                <asp:Panel ID=”DeptPanel” runat=”server” Visible=”True”>
                    <asp:DropDownList ID=”DrpDept” runat=”server”
                    AutoPostBack=”True”
                    OnSelectedIndexChanged=”DeptDrp_SelectedIndexChanged”>
                        <asp:ListItem Text=”Select Department” Selected=”true” />
                        <asp:ListItem Text=”Admin” />
                        <asp:ListItem Text=”HR” />
                        <asp:ListItem Text=”Manufacturing” />
                    </asp:DropDownList>                   
                </asp:Panel>
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:UpdatePanel ID=”EmpUpdPanel” runat=”server”>
            <ContentTemplate>
                <asp:Panel ID=”EmpPanel” runat=”server” Visible=”False”>
                    <asp:DropDownList ID=”DrpEmployee” runat=”server”
                    AutoPostBack=”True”
                    OnSelectedIndexChanged=”EmpDrp_SelectedIndexChanged”>
                    </asp:DropDownList>                  
                </asp:Panel>
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:UpdatePanel ID=”DetailUpdPanel” runat=”server”>
            <ContentTemplate>
                <asp:Panel ID=”DetailPanel” runat=”server” Visible=”False”>
                    Department: <asp:Label runat=”server” ID=”LblDept”/></asp:Label><br>
                    Name: <asp:Label runat=”server” ID=”LblName”/></asp:Label><br>
                    Email: <asp:Label runat=”server” ID=”LblEmail”/></asp:Label><br>
                    Salary: <asp:Label runat=”server” ID=”LblSalary”/<br>
                </asp:Panel>
            </ContentTemplate>

        </asp:UpdatePanel>

代码构造很简单,含有下拉框改变SelectedIndex处理事件调用。DeptDrp_SelectedIndexChanged事件函数生成部门雇员数据,并将数据绑定到名为Employees的list类型的列表中,处理数据程序使用基于LINQ查询来检索被选部门的雇员数据。

protected void DeptDrp_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (Session["Employees"] == null)
            {
                Employees = new List<Employee>(new Employee[]{
                    new Employee(){Name = “David”,
                        Dept=”HR”, Email = “David@org.com”,
                        Salary = 2000},
                    new Employee(){Name = “George”,
                        Dept=”Admin”, Email = “George@org.com”,
                        Salary = 2500},
                    new Employee(){Name = “Bill”,
                        Dept=”Admin”, Email = “Bill@org.com”,
                        Salary = 6000},
                    new Employee(){Name = “Henry”,
                        Dept=”Manufacturing”, Email = “Henry@org.com”,
                        Salary = 4750},
                    new Employee(){Name = “Michael”,
                        Dept=”Manufacturing”, Email = “Michael@org.com”,
                        Salary = 8000},
                });
                Session["Employees"] = Employees;
            }
            else
            {
                Employees = (List<Employee>)Session["Employees"];
            }
            DeptPanel.Visible = false;
            EmpPanel.Visible = true;
            var Emp = from E in Employees
                      where E.Dept == DrpDept.SelectedValue
                      select new { E.Name };
            DrpEmployee.DataSource = Emp;
            DrpEmployee.DataValueField = “Name”;
            DrpEmployee.DataBind();
            DrpEmployee.Items.Insert(0, “Select Employee”);

        }

EmpDrp_SelectedIndexChanged事件函数用于显示被选雇员的资料。

protected void EmpDrp_SelectedIndexChanged(object sender, EventArgs e)
        {
            Employees = (List<Employee>)Session["Employees"];
            EmpPanel.Visible = false;
            DetailPanel.Visible = true;
            var Emp = from E in Employees
                      where E.Name == DrpEmployee.SelectedValue
                      select new { E.Name, E.Email, E.Dept, E.Salary };
            foreach (var EDetail in Emp)
            {
                LblDept.Text = EDetail.Dept;
                LblEmail.Text = EDetail.Email;
                LblName.Text = EDetail.Name;
                LblSalary.Text = EDetail.Salary.ToString(”C”);
            }

        }

当生成并运行项目后,你会看到浏览器的前进后退按钮是失效的,因为浏览器目前无法追踪AJAX的所有步骤。

AjaxHistory_1

要解决这个问题,不得不在项目中引入浏览器的历史点。要保持历史,首先必须启用ScriptManager控件的相关设置,还需要具有响应浏览器前进后退按钮按下时的事件处理程序。ScriptManager控件定义如下:

<asp:ScriptManager ID=”SManager” runat=”server”
    EnableHistory=true
    OnNavigate=”History_Navigate” />

此外还需要为两次AJAX异步postback之后创建历史点,一次是选定了部门,另一次是选定了雇员。为此需要创建一个Add_History方法:

private void Add_History(string Title)
        {
            NameValueCollection State = new NameValueCollection();
            State.Add(”DeptIndex”, DrpDept.SelectedIndex.ToString());
            State.Add(”EmployeeIndex”, DrpEmployee.SelectedIndex.ToString());
            SManager.AddHistoryPoint(State, Title);

        }

从代码可见ScriptManager的AddHistoryPoint的调用,该方法将当前被选中的部门值和当前被选中的雇员值连同页面标题一起保存在NameValueCollection类型的State中。用于提供浏览器前进后退时的呈现。

接下来就是调用这个Add_History方法了。在DeptDrp_SelectedIndexChanged(选取了部门)事件处理函数体中添加如下代码:

if (SManager.IsInAsyncPostBack && !SManager.IsNavigating)
            Add_History(”Employee List: ” + DrpDept.SelectedValue);

!SManager.isNavigating用于强调当前的postback,并不会因用户点击了浏览器的前进后退的行为造成的多重调用。同样的方法用于EmpDrp_SelectedIndexChanged(选取了雇员)事件处理函数里:

if (SManager.IsInAsyncPostBack && !SManager.IsNavigating)
            Add_History(”Employee Detail:” + DrpEmployee.SelectedItem.Text);

注意,当DrpEmployee.SelectedIndex也就是被选中的部门的值是0时,应该将EmployeeIndex也设为0。然而目前依照Add_History方法来看,Deptndex和EmployeeIndex都是需要有值的。而且页面在首次加载时并没有任何状态,因此Deptndex和EmployeeIndex都是null。于是当History_Navigate事件被浏览器动作调用时,需要进行一些处理:

protected void History_Navigate(object sender, HistoryEventArgs e)
        {
            NameValueCollection State = e.State;
            string DeptIndex = State["DeptIndex"];
            string EmployeeIndex = State["EmployeeIndex"];
            //Set DeptIndex = “0″ when its null
            DeptIndex = string.IsNullOrEmpty(DeptIndex)
                ? “0″ : DeptIndex;
            EmployeeIndex = string.IsNullOrEmpty(EmployeeIndex)
                ? “0″ : EmployeeIndex;
            //Dept List View
            if (DeptIndex == “0″)
            {
                DeptPanel.Visible = true;

                EmpPanel.Visible = false;
                DetailPanel.Visible = false;
            }
            //Employee List View
            if (DeptIndex != “0″ && EmployeeIndex == “0″)
            {
                DeptPanel.Visible = false;
                EmpPanel.Visible = true;
                DetailPanel.Visible = false;
            }
            //Employee Detail View
            if (EmployeeIndex != “0″)
            {
                DeptPanel.Visible = false;
                EmpPanel.Visible = false;
                DetailPanel.Visible = true;
            }

        }

该事件通过HistoryEventArgs获得当前页面状态,并而根据状态中DeptIndex和EmployeeIndex的值来隐藏或显示对应状态的panel。

AjaxHistory_2

目前已经成功地将AJAX调用引入浏览器的历史,并能在前进和后退中控制这些调用。很重要的一点,这里所说的历史点如同浏览的URL和历史状态的保存方式一样,最大字节为1024。所以要谨慎使用,建议保存最低限度的信息。

原文链接:http://weblogs.asp.net/haroonwaheed/archive/2008/07/26/Maintain-Browser-History-with-AJAX.aspx

作者:hwaheed

PhotoFunia挺好玩的

Posted on 7月 25th, 2008 in 我玩 | No Comments »

狂点这里,选取一个喜欢的效果,然后玩自己或玩别人……

IC51PGosxE4ORJnQxGQBiw

y3Os8w9zaUb7t4q3MVBuHA

ZUnvyuPRlDoLbPzKIUrRuA

zmUazfWki3xwXrHuyQXOhw

Z4goeIht15XU2bERufXNBQ

在ASP.NET Ajax中取消一个异步postback

Posted on 7月 20th, 2008 in 我学, 我看, 我译 | No Comments »

这又是一篇翻译稿,原文在这里

异步的postback暗地里和同步的postback类似。异步模式与同步模式在服务器端都具有相同的处理方式,Microsoft AJAX库也是一样的。然而当页面呈现时,异步模式只是呈现updatepanel部分的内容,而同步模式则是整个页面。

我假设你具备一定的asp.net ajax的开发基础,并且安装了asp.net ajax库和asp.net control toolkit。在我写这篇文章的时候,toolkit的版本是1.0.20229(Framework2.0,asp.net ajax1.0和Visual Studio 2005)和3.0.20229(.NET Framework3.5和Visual Studio 2008)。我测试实例是使用3.0.20229(.NET Framework 3.5和Visual Visual Studio 2008),但是我坚信它还是能在1.0.20229运行的。

AJAX中的Sys.Application和Sys.WebForms.PageRequestManager类库在提高ASP.NET AJAX的WEB页面生命周期上有着卓著的表现。如果你的页面里有一个updatepanel,你就能通过PageRequestManager类来显式处理异步postback事件。我们马上就可以看到如何使用PageRequestManager类的客户端事件来取消或终止当前的postback。

整个过程先从PageRequestManager类的initializeRequest事件初始化异步postback开始。通过使用PageRequestManager类的isInAsysncPostBack属性检查当前是否有一个异步postback,如果有,并且用户又执行了另一个postback,这时有必要取消掉新加入的postback。

注意:ASP.NET Ajax在同一时间内只能执行一个异步postback。

让我们来看看是如何进行的:

第一步:打开Visual Studio->File->New Web Site->ASP.NET Web Site->设定好站点位置和使用的编程语言,然后点“OK”。

第二步:从工具栏中拖一个ScriptManager控件和一个UpdatePanel控件到页面中。再从工具栏里分别拖三个button控件和一个label控件到UpdatePanel控件中。第一个button控件将引发第一个postback,其次第二个button控件将引发第二个postback,最后一个button控件将终止当前的postback。代码如下:

<body>
<form id=”form1″ runat=”server”>
<asp:ScriptManager ID=”ScriptManager1″ runat=”server”>
</asp:ScriptManager>
<asp:UpdatePanel ID=”UpdatePanel1″ UpdateMode=”Conditional” runat=”server”>
<ContentTemplate>
<asp:Button runat=”server” Text=”PostBackFirst” ID=”btnPostF” onclick=”btnPostF_Click”/>
<asp:Button runat=”server” Text=”PostBackSecond” ID=”btnPostS” onclick=”btnPostS_Click”/>
<asp:Button runat=”server” Text=”AbortPostBack” ID=”btnAbort”/>
<asp:Label ID=”Label1″ runat=”server” Text=”Label”></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>

事件处理代码如下:

C#
protected void btnPostF_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(4000);
Label1.Text = “PostBack 1 Completed”;
}
protected void btnPostS_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(4000);
Label1.Text = “PostBack 2 Completed”;
}
VB.NET
Protected Sub btnPostF_Click(ByVal sender As Object, ByVal e As EventArgs)
System.Threading.Thread.Sleep(4000)
Label1.Text = “PostBack 1 Completed”
End Sub
Protected Sub btnPostS_Click(ByVal sender As Object, ByVal e As EventArgs)
System.Threading.Thread.Sleep(4000)
Label1.Text = “PostBack 2 Completed”
End Sub

在这里,当点击button时我们要引入一个4秒的延迟,你也可以换上你自己的处理代码,比如取出数据库结果或类似的操作。

第三步:在页面中的<head>中加入下面的javascript代码:

<script type=”text/javascript”>
function pageLoad()
{
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(cancelPostBack);
}
function cancelPostBack(sender, args)
{
if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
{
alert(’One postback at a time please’);
args.set_cancel(true);
}
}
</script>

正如本文介绍过的一样,这些代码用于注册initializeRequest事件,并使用isInAsyncPostBack属性来确定当前运行的是否为一个异步的postback。你同样可以使用Sys.CancelEventArgs类来取消当前请求。

注意:你可以用Sys.WebForms.InitializeRequestEventArgs类的postBackElement属性获得一个新发起的postback的ID号,像这样:var ctrl = args.get_postBackElement()。

第四步:最后一步要通过使用PageRequestManager类的abortPostBack方法来终止当前的postback。要做到这一步,必须添加以下代码到btnAbort这个button控件的onClientClick里:

<asp:Button runat=”server” Text=”AbortPostBack” ID=”btnAbort”
OnClientClick=”Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
alert(’Postback Cancelled’);”/>

完整的代码如下:

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
<title>Cancel Async PostBack</title>
<script type=”text/javascript”>
function pageLoad()
{
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(cancelPostBack);
}
function cancelPostBack(sender, args)
{
if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
{
alert(’One postback at a time please’);
args.set_cancel(true);
}
}
</script>
</head>
<body>
<form id=”form1″ runat=”server”>
<asp:ScriptManager ID=”ScriptManager1″ runat=”server”>
</asp:ScriptManager>
<asp:UpdatePanel ID=”UpdatePanel1″ UpdateMode=”Conditional” runat=”server”>
<ContentTemplate>
<asp:Button runat=”server” Text=”PostBackFirst” ID=”btnPostF”
onclick=”btnPostF_Click”/>
<asp:Button runat=”server” Text=”PostBackSecond” ID=”btnPostS”
onclick=”btnPostS_Click”/>
<asp:Button runat=”server” Text=”AbortPostBack” ID=”btnAbort”
OnClientClick=”Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
alert(’Postback Cancelled’);”/>
<asp:Label ID=”Label1″ runat=”server” Text=”Label”></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>

想要测试功能的完成情况,就按照下面的步骤进行:

1,运行应用程序。

2,点击PostBackFirst按钮,立即点击PostBackSecond按钮。你将会收到“One postback at a time please”的信息,表示代码已经可以感知到一个异步postback正在进行中,不能进行别的操作。

3,现在开始检查如何终止当前的异步postback的功能。点击PostBackFirst或PostBackSecond任意一个按钮,等4秒。默认的表现是在当前线程唤醒(记住,我们用了Thread.Sleep())时,label控件会显示相应的“PostBack Completed”。我们再试一下,这次是点击PostBackFirst或PostBackSecond任意一个按钮,在4秒中内又点击AbortPostBack按钮,结果postback被终止了,label没有显示任何信息。

OK,这只是一个简单(称得上糟糕)的例子,不过有利于说明如何取消或终止异步postback。我相信你在你的实际应用中能找到更不错的功能方法,我十分愿意听到你对此的反馈信息。我希望你能喜欢这篇文章,并且对于你的阅读表示感谢。

jQuery选择器(二)

Posted on 6月 18th, 2008 in 我学, 我想 | No Comments »

尽管jQuery选择器能给我们灵活的方法识别出DOM中的复杂的元素,并能加以设置。但有时一些匹配条件却不能很好地用表达示表达出来。考虑到jQuery强有力的方法集合,我们期望调整匹配表达示和方法集合这两者之间的关系来解决这个问题。

某些情况下,jQuery提供的方法不会基于匹配的元素之上,但又可以与本身进行匹配相关的设置。比如:

add(表达示)

表达示可以是一个选择器表达示,它将得到一个相匹配的结果。当然也可以是一个新元素字符串。不管这个结果是直接引用的元素还是一个与表达示相匹配的元素,add()方法可以将调用该方法的匹配设定与之进行连接。就像这样:

$(’div’).add(’p').css(’color’,'red’);

在原有<div>元素的匹配关系中添加新匹配关系<p>,最后为这个匹配集合(所有的<div>和所有的<p>)再添加一个color=”red”的css属性。

你可能认为这有点多余,因为有效果一样的方法可以做到:

$(‘div,p’).css(‘color’,‘red’);

但有时我们必须要这样做。例如:

$(’div’).css(’font-weight’,'bold’).add(’p').css(’color’,'red’);

先为所有匹配的<div>元素加个字符粗体的样式,然后再加再入一个所有匹配的<p>元素,字体样式设为”red”。看起来能节省不少代码……

更多的例子:

$(’div’).add(someElement).css(’border’,'3px solid pink’);
$(’div’).add([element1,element2]).css(’border’,'3px solid pink’);

去除匹配的元素

当要从已经匹配的元素中去除一些元素,就要用到not()方法。与add()类似,也是创建一个新的匹配设置,但这个匹配设置的元素会被除外。可以声明一个jQuery选择器,也可以是一个指定的元素。例如:

$(’body *’).css(’font-weight’,'bold’).not(’p').css(’color’,'red’);

让所有的元素字体加粗,然后然除<p>元素之外的其它元素字体色设为”red”。

$(’body *’).css(’font-weight’,'bold’).not(anElement).css(’color’,'red’);

和之前讲的除外的做法一样,变量anElement不受第二个匹配的设置的影响,因此它的字体色不会被设为”red”。

注意,避免犯低级错误,不要将.net()方法与remove()方法混淆。一个是从匹配表达示的元素中去除元素,另一个是从DOM中删除元素。

寻找子元素

有时要在已经确定的元素中寻找特定的子元素,就要用到find()方法。

这有别于之前的审核方法,find()方法只接受一个选择器表达示作为它的工作依据。在匹配选择器表达示的元素集合中寻找子元素。任何匹配选择器表达示的源元素本身不在它的寻找范围内。例子:

$(’div’).css(’background-color’,'blue’).find(’img’).css(’border’,'1px solid aqua’);

前面部分很简单了,选取所有的<div>元素,并使其背景色为成”blue”。后面部分是在这些被选取的<div>元素中寻找<img>子元素,并为其加个”aqua”色的边框。注意是在被选取的<div>元素内寻找,其它的不属于寻找范围。

筛选匹配集合

filter()方法可以接受选择器表达示,也可以接受一个函数。当接受的是选择器表达示时,他的功能与not()方法相反,是保留匹配表达示的元素。当接受的是函数时,函数可以编历每一个元素并且决定一些选择器表达无法确定的元素的去留。

看看例子:

$(’.bashful’).show().filter(’img[src$=.gif]‘).attr(’title’,'Hi there!’);

选取class=”bashful”的元素,并设置这些元素为可视。然后在这些元素当中筛选出src属性以.gif结尾的<img>元素,再为筛选出的这些元素指定一个title=”Hi there!”的属性。

$(’img[src^=images/]‘).filter(function(){
return $(this).attr(’title’).match(/.+@.+\.com/)!= null;
}).hide();

在src属性以images/开头的<img>元素中,筛选出title属性匹配一个.com的电子邮件格式的所有元素。

切分匹配集合

基于匹配表达示元素位置上的切分,并创建新的匹配关系。

看例子:

$(’body *’).slice(3).hide();

选取body内的所有元素,然后创建一个新的匹配元素集合,集合中切分出第三个元素之后的所有元素。将使其隐含起来。

$(’body *’).slice(2,4).hide();

选取body内的所有元素,然后创建一个新的匹配元素集合,集合中从第二个元素之后,直到第四个元素被切分出来,并使其隐含。

我们发现eq(n)事实上就是slice(n,n+1)的简写方法。

匹配关系

我们也许经常要在元素之间的关系上建立一些匹配设置。下表是一些类似的方法:

方法名称 说明
children(表达示) 选取在父级匹配元素中与表达示相匹配的所有子元素。
next(表达示) 选取紧接着原匹配元素,并且同级别与表达示相区配的一个元素。
nextAll(表达示) 选取紧接着原区配元素,并且同级别与表达示相匹配的所有元素。
parent(表达示) 选取与表达式相匹配的元素的直接父级元素。
parents(表达示) 选取与表达式相匹配的元素的所有父级元素。
prev(表达示) 选取原匹配元素之前,并且同级别与表达示相区配的一个元素。
prevAll(表达示) 选取原匹配元素之前,并且同级别与表达示相区配的所有元素。
siblings(表达示) 选取与表达示相匹配的所有同级别的元素。
contents() 选取包含有指定内容的所有元素。

所有的这些方法都可以接受筛选表达示。如果缺省呢?当然就没有进行任何筛选了……

元素转换

有时你可能要把相匹配的元素转换成其它的值。jQuery提供map()方达到这个目的。看一个例子,你可这样来获取name=”myForm”的表单的所有表单元素的值:

var values = $(’#myForm :input’).map(function(){
return $(this).val();
});

map()的回调函数返回一个jQuery对象实例,要将其转换成JavaScript的标准数组。你可以使用不带参数get()方法:

var values = $(’#myForm :input’).map(function(){
return $(this).val();
}).get();

这时返回的值是一个JavaScript数组,而不再是jQuery对象了。

控制链

之前的所有的方法都是在一层层地迭加匹配表达式,以达到想要的审核目的。但jQuery允许你“亮出”之前的匹配表达式。来看看end()方法。

$(’div’).add(’p').css(’color’,'red’);

之前已经使用过这个例子,匹配的<div>元素表达示的基础上再加一个匹配<p>元素的表达示。

$(’div’).add(’p').css(’color’,'red’).end().hide();

这时,当访问了.css()方法之后,end()方法将”亮出”原来的匹配的表达示,也就是匹配所有的<div>元素。然后将其隐含。事实上等同于:

$(’div’).add(’p').css(’color’,'red’);
$(’div’).hide();

还一个有用的方法,它能影响表达示集合链的的设置,就是andSelf()方法:

$(’div’).css(’background-color’,'yellow’).children(’img’).css(’border’,'4px ridge maroon’)
.andSelf().css(’margin’,'4em’);

选取所有的<div>元素,并设定其’background-color:yellow。然后在被选取的<div>元素中选取<img>子元素,并设其border:4px ridge maroon。最后,子元素<img>和父级元素<div>(原匹配表达式)合并起来,共同设置一个margin:4em的样式。

差不多了,就到这里吧。选择器毫无疑问的是jQuery的精华。你会发现了解选择器能更有效地进行WEB开发。本系列的BLOG是参考Bear Bibeault和Yehuda katz两位大师的《jQuery Selector》所写。原书PDF可以在此下载。也许我还没有真正理解原书的精髓,但我自从开始接触jQuery到现在的半年时间里,所感受到的所学到的并不仅仅是完成一个效果或show一个样式。如今,我甚至羞于面对三个月前用jQuery完成的那些项目……

jQuery选择器(一)

Posted on 6月 16th, 2008 in 我学, 我看 | No Comments »

jQuery选择器是什么?

jQuery选择器是jQuery库中非常重要的部分之一。它支持网页开发者所熟知的CSS语法快速轻松地对页面进行设置。了解jQuery选择器是打开高效开发jQuery之门的钥匙。一个典型的jQuery选择器句法形式:
$(selector).methodName();
selector是一个字符串表达示,用于识别DOM中的元素,然后使用jQuery提供的方法集合加以设置。
大多数情况下jQuery支持这样的操作:
$(selector).method1().method2().method3();
这个实例表示隐含DOM中id=”goAway”的元素,然后为其添加一个class=”incognito”属性。
$(’#goAway’).hide().addClass(’incognito’);
提示一下:当选择器表达示匹配多个元素时,可以象JavaScritp数组操作一样,方便灵活地利用数组指针进行选取。这是例子:
var element = $(’img’)[0];
匹配表达示的元素中,第一个元素对象将赋给变量element。

jQuery选择器的分类

有三种分类:基本选择器,位置选择器和自定义选择器。可以将基本选择器理解为“发现型选择器”,事实上它用于搜索DOM中的元素。位置选择器和自定义选择器更像是“筛选型选择器”。

基本选择器

这里提供了一份基本选择器的参考实例。这些选择器都支持CSS3语法准标和语议。

$(‘div’) 选取所有<div>元素。

$(‘fieldset a’) 选择在<fieldset>元素内出现的所有<a>元素。

$(‘li>p’) 选取在<li>标记中直接出现的所有<p>元素。

$(‘div~p’) 选取位为<div>标记之后出现的所有<p>元素。

$(‘p:has(b)’) 选取<p>元素内包含有<b>的所有元素。

$(‘div.someClass’) 选取<div>元素中出现class=”someClass”属性的所有元素。

$(‘.someClass’) 选取出现class=”someClass”属性的所有元素。

$(‘#testButton’) 选取id=”testButton”的元素。元素id属性值在当前DOM中是唯一的。因此我很好奇出现了两个id=”testButton”的元素时它会怎么选。实验证明它只会选取第一个元素。真正的开发过程中,我们绝对不要在一个DOM中出现多个id相同的元素。

$(‘img[alt]’) 选取具有alt属性的所有<img>元素。

$(‘a[href$=.pdf]’) 选取具有href属性,而且属性的值以.pdf结尾的所有<a>元素。

$(‘button[id*=test]’) 选取所有的按钮,但按钮的id属性要包含”test”。

提示一下:在同一个$()结构中可以用“,”来连接多个不同的选择器,比如这样:

$(’div,p’)

以下是匹配所有具有title属性的<div>元素,和所有具有alt属性的<img>元素:

$(’div[title],img[alt]‘)

位置选择器

这种类型的选择器可以附加到任何基本选择器上,用于进行基于元素位置的筛选。如果缺省基本选择器,则将被视为所有元素。

举一些例子吧。

$(’p:first’) 选取页面中第一个出现的<p>元素。

$(’img[src$=.png]:first’) 选取页面中第一个出现src属性值以.png结尾的<img>元素。

$(’button.small:last’) 选取页面中最后一个出现class=”small”的按钮元素。

$(’li:first-child’) 选取页面中所有<li>列表的第一项元素。

$(’a:only-child’) 选取页面中所有<a>元素,但这些元素只能位于一个父级元素内。比如<li><a href=”url”>An url</a></li>,此时<li>内的<a>是匹配的。

$(‘li:nth-child(2)’) 选取父级元素中第二个<li>元素。<li>也一家要位于一个父级元素内。比如<ul>
<li>1</li>
<li>2</li>
</ul>

此时<li>2</li>是匹配的。

$(’tr:nth-child(odd)’) 选取表格中所有为奇数的行元素。

$(‘li:nth-child(3n)’) 在父级元素中有很多个<li>元素,但只选取隔3次出现的<li>元素。比如

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>

其中<li>3</li>,<li>6</li>匹配。

$(’li:nth-child(3n+5)’) 带有偏移量的选取。在父级元素中只选取从第5个<li>元素开始每隔3次出现的<li>元素。比如

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>

其中<li>5</li>,<li>8</li>匹配。

$(‘.someClass:eq(1)’) 选取页面中class=”someClass”的第二个元素。jQuery以0为基准,因此(1)表示相当于第2个。

$(‘.someClass:gt(1)’) 选取页面中所有class=”someClass”的元素,除了开头两个。

$(‘.someClass:lt(4)’) 只选取页面中所有class=”someClass”元素中最先的4个元素。

自定义选择器

jQuery提供这类的选择器用于在并不期望有CSS明确规定时,对元素进行方便快捷地选取。自定义选择器有可能会被组合起来,来看一看这些强大的选择器实例。

$(’img:animated’) 选取所有刚刚经历完动画方法调用的<img>元素。

$(’:button:hidden’) 选取所有被hide()方法隐含的按钮类型元素。

$(’input[name=myRadioGroup]:radio:checked’) 选取name=”myRadioGroup”的单选框内被选中的项目。

$(’:text:disabled’) 选取所有被禁用的文本框元素。

$(’#xyz :header’) 选取id=”xyz”元素内的所有<h>元素。

$(’option:not(:selected)’) 选取没有被选中的所有的<option>元素。

$(’#myForm button:not(.someClass)’) 选取id=”myForm”的表单内不具有class=”someClass”属性的所有按钮。

$(’select[name=choices] :selected’) 选取name=”choices”的<select>元素中所有被选中的<option>项。

$(’p:contains(coffee)’) 选取所有内容包含有coffee的<p>元素。

无论是单一的或是组合,jQuery选择器能创建强大而简便的一套方案,便于jQuery内置的一些方法地行极富想像力的WEB开发。

待续……

有关jQuery动画的认识

Posted on 6月 12th, 2008 in 我学, 我看, 我译 | 2 Comments »

原文链接

我知道最近我大多数的文章都在关注jQuery,对于那些不了解或没兴趣的人,我真要劝你们还是花几个小时在它上面吧。jQuery留给我许多值得兴奋的回忆(至少关于WEB的)。我肯定你会从不少人那里听到取笑jQuery的声音……不必担心不同的浏览的修正问题(我很讨厌);不必再去为了只修改一个元素而动用数十行的代码。jQuery安排好了一切。如果你仍然不服气,为什么不去读一读《为什么你不用jQuery》呢?文章将带你一步一步从起点开始了解jQuery。

这篇文章是动画专题,这可是jQuery库的精华部分。我们首先来关注简单的“show/hide”方法。然后我们会继续进行一些自定义的动画操作。那么让我们来彻底了解这些机制。

简单的动画

在我早期的jQuery文章中已经对这些功能有了概述,如果你需要更多的帮助,请参考

“show”和”hide”是什么?它们是干什么的?

在你的html文档里,为一个元素调用”Hide()”方法,会将该元素的display样式改为”none”。以下CSS和jQuery的代码完成的功能是相同的。

#someElement
{
display: none;
}

$(“#someElement”).hide();

我敢肯定你会自己弄明白”Show()”方法就是将元素变回display的初始状态。再看看以下的代码段的功能也是一样的。

#someElement
{
display: inline;
}

$(“#someElement”).show();

“Show()”和”Hide()”方法会让元素动起来吗?

会,也不会。不带任何参数的情况下,它不会有动画。但,在调用”Show()”方时,如果我们希望看到元素慢慢地显示出来呢?在这种情况下,我们不得不采用”slow”关键字。看例子……

$(“#someElement”).show(“slow”);

现在,当该代码运行,元素将慢慢地在0.6秒内显示出来。这个速度参数,我们可以任选一个长度的速度关键字在某个动画中运行。速度关键字有”slow”,”normal”和”fast”(长度分别是0.6秒,0.4秒和0.2秒)。除此这外,我们还可以为速度指定一个数字……

$(“#someElement”).show(1000);

这将使元素在1秒钟(1000毫秒)内显示出来。注意,当使用速度关键字时要加引号,而然在指定数字时就不需要加引号。

奇妙的”Show()”方法,我们实际上并没有花费太多的力气就能得到相当好的效果。在这个方法中,我们改变元素的不透明度、宽度和高度的值。jQuery库的其它动画方法,从另一个角度讲,恐怕需要改变一下特性。

FadeIn() 和 FadeOut()

Fade方法只改变元素的不透明度。FadeOut()在指定的一段时间内降低元素的不透明度,直到元素完全消失(display:none)。很明显FadeIn()则相反。作为显示和隐含的方法,我们可以引入我们的”slow”,”normal”和”fast”这些关键字。

假设有一个超链接,当它被点击后慢慢地消失了(淡出)。首先看看例子,然后再看看代码。

$(document).ready(function()
{
$(”#someId”).click(function()
{
$(this).fadeOut(”slow”);
});
});

HTML文档打开完成,我们要侦听一个ID为”someId”的超链接的点击事件,当被点击,this(即被点击的超链接对象)会慢慢消失(淡出)。

slideUp() 和slideDown()

slide方法只会改变元素的高度。如果一个元素的display样式为none,当调用”slideDown”方法时,这个元素将按指定高度由上至下延伸显示。该动画方法和其它动画方法一样支持关键字和数字参数。

自定义动画

许多情况下,你可能需要对你的动画有更多的控制。有些是jQuery内置方法办不到的,那么我们就要采取一些高级的自定义的解决办法。

让元素横穿页面

本例要让一个图片被点击后横穿页面。看看效果。让我们假设有这么一个空白的Html,里面有一个id=”theImage”的图片标记。首先设置它的CSS样式。

#theImage
{
position: relative;
}

为了要让图片运动,我们要更改它的”left”样式属性。不管怎样,为了能影响这个元素的top,left,bottom和right的样式属性,必需先要有position的样式设置。还没弄清相对定位和绝对定位吗……现在,添加我们的jQuery代码。

$(document).ready(function(){
$(”#theImage”).click(function()
{
$(this).animate
({left: “400px”}, 3000);
});
});

这里,我们为图片创建一个点击事件。然后加入”animate”方法。

动画语法结构:.animate({property: “value”}, speed, callbackFunction);

我们使元素3秒钟(3000毫秒)内完成右移400象素。

多重动画

看着,改动一下前面的例子,要让我们的图片向右滑动然后放大图片的宽度。下面的代码对吗?

$(“#theImage”).click(function()
{
$(this).animate
({
left: “400px”,
width: “300px”
}, 3000);

答案是否定的(至少不完全是)。如果你再重新理解我们的目标,我们是要让图片向右滑动,完成后再将图片的宽度改成300像素。这个代码的表示则是让两个动画同时进行,即图片向右滑动的同时改变了它的宽度。那么,我们如何能够让我们的动画“排队”呢

$(“#theImage”).click(function()
{
$(this).animate
({
left: “400px”,
}, 3000);
$(this).animate
){
width: “300px”
}, 3000);

现在我们将这两者分开了,在”left”这个定位属性改变之前”width”属性将不会改变。称其为“动画队列”……或动画链!

来个综合

看看效果

接下来的例子,我们要点击图片后让它向右移动,并将它的不透明度从10%变换到100%。当完成这些效果后,我们还要有一个三秒内淡出的过程。首先,我们要稍微编辑一下CSS文件。

#theImage
{
position: relative;
display: none;
}

为了使元素的”left”样式属性发生变化,元素需要相对定位。我们同样还要将元素的display设为none,以便它在横穿屏幕时我们可以淡入它。现在该jQuery了。

$(document).ready(function(){
$(”#theImage”).css(”opacity”, “.1″);
$(”#theImage”).click(function()
{
$(this).animate
({left: “400px”, opacity: “1″}, 3000, function()
{
$(this).fadeOut(3000);
}
);
});
});

.CSS居然插队!

如果图片移动并淡入之后,我们又要更换它的CSS为……

.css(“border”, “5px solid red”);

很遗憾,你不能得到预期响应。.CSS方法不会等待动画完成而是立即被更换样式。那么你怎样使这个没有效果过程的.CSS方法老老实实地排上队呢?答案是”callback”回调函数(我们已经在以前的示例中运行过)。这里我们复习一下。

$(document).ready(function(){
$(”#theImage”).css(”opacity”, “.1″);
$(”#theImage”).click(function()
{
$(this).animate
({left: “400px”, opacity: “1″}, 3000, function()
{
$(this).css(“border”, “5px solid red”);
$(this).fadeOut(3000);
}
);
});
});

回调函数允许你在效果完成后声明一些功能。它适用于jQuery所有的效果方法。

$(“#someElement”).slideDown(“normal”, function()
{
…这里可以写些代码
});
);

这段代码表示id=”someElement”的元素将在0.4秒内(正常速度)向下完全展开。当动画完成后,回调函数体的代码将会被执行。

我希望这篇文章能帮助你。如果可以,请将文章推荐出去,那么其它的开发者也能学到些东西。

5个jQuery问题和解答

Posted on 6月 9th, 2008 in 我学, 我看, 我译 | No Comments »

原文链接,这是他的系列问答的第二部分,第一部分是关于CSS的

我怎样用jQuery放大和缩小文本

先看看效果有几种方法实现,我们只专注于其中的一种。首先,我们添加的一些简单的标记:

<div>
<p id=”text”>
  This is some text. This is some text. This is some text. This is some text. This
  is some text. This is some text. This is some text. This is some text. This is some
  text. This is some text. This is some text. This is some text. This is some text.
  This is some text. This is some text. This is some text. This is some text. This
  is some text. This is some text.
</p>
<a href=”#” id=”smallerTextLink”>Smaller Text</a><br>
<a href=”#” id=”largerTextLink”>Larger Text</a>
</div>

这是一常规的文本和两个超级链接。点击这些链接时将可以控制文本是否放大或缩小。现在来添加我们的jQuery代码。

$(document).ready(function()
        {
            $(’a').click(function()
                {
                    var theElement = $(”#text”).css(”font-size”);
                    var textSize = parseFloat(theElement, 10);
                    var unitOfMeasurement = theElement.slice(-2);
                    if ( (this).id == “largerTextLink”)
                    {
                        textSize += 2;
                    }
                    else
                    {
                        textSize -= 2;
                    };
                    $(’p').css(”font-size”,  textSize + unitOfMeasurement);
                    return false;
                    });
        });

和平时一样,我们一步步来看看代码到底完成了什么事。

$(document).ready(function()
        {
            $(’a').click(function()

这是当HTML打开完成时,为HTML文档内的所有超链接<a>元素绑定了一个点击(click)事件函数。

var theElement = $(”#text”).css(”font-size”);
var textSize = parseFloat(theElement, 10);
var unitOfMeasurement = theElement.slice(-2);

在这,我们创建一些变量。HTML文档中ID为text的元素的font-size(字符尺寸)属性值将赋给变量”theElement”。”.css”方法可以获取或设置定指属性的值。当只在()内添加属性名称时(为.css方法提供一个属性名称参数),意思就是让jQuery去获取段落的font-size(字符尺寸)的值。这个值将返回数字和单位,也就是20px。我们需要将”20″和”px”分开。

“textSize”变量使用”parseFloat”方法。”parseFloat”能读取或解析字符串中的数字字符并返回这些值。既然如此,我们就用这种方法去掉font-size属性值中的”px”。”10″表示进制,我们就用这个10进制。

“unitOfMeasurement”只保存font-size属性值的最后两个字符(px),也就是值的单位。我们需要用它来确保将来产生的一些新值的单位一致。

if ( (this).id == “largerTextLink”)
{
    textSize += 2;
}
else
{
    textSize -= 2;
};

if语句用于判断当前被点击的超链接元素<a>的ID是否为”largerTextLink”。如果是,我们要为textSize变量增加2px。类似textSize=textSize+2的写法。如果不是,那说明用户肯定点击了ID为”smallerTextLink”的超链接,这种情况下,我们要减掉textSize变量的2px。

$(’p').css(”font-size”,  textSize + unitOfMeasurement);
return false;

最后,我们还要获取段落元素并为段落元素赋予新的值。font-size将被新的textSize变量的值取代,还要连接unitOfMeasurement变量作为单位。很简单,不是吗?

我怎样实现当点击图片后让它放大

看看效果这个比较容易,首先,我们加些简单的HTML。

<img src=”img/logo.gif” alt=”Logo” id=”image”>
<p>
  Click To Zoom In
</p>

只有一个图片和一个段落。我们为什么不干脆用超链接而用段落呢。我只是想让你知道我可以为任何标记声明click事件。

$(document).ready(function()
    {
    $(”#image”).css(”width”, “100px”);
        $(”#image”).toggle(function()
            {
                $(this).animate({width: “300px”}, 1000);
                $(’p').text(”Click To Zoom Out”);
            }, function(){
                $(this).animate({width: “100px”}, 1000);
                $(’p').text(”Click To Zoom In”);
            });
    });

一步一步来看,你知道要这样的……

$(document).ready(function()
    {
    $(”#image”).css(”width”, “100px”);

当html打开完成,我们要为ID为”image”的元素设置一个100px的宽度。这在第二步时不是十分有必要的,界时只是将其缩小回原样。

$(”#image”).toggle(function()
{
  $(this).animate({width: “300px”}, 1000);
  $(’p').text(”Click To Zoom Out”);

当ID为image的图片元素被点击,我们要调用toggle方法。用”toggle”方法,我们可以设置两个函数,第一个函数用于处理一次点击的响应,第二个函数用于处理再次点击的响应。这最适合用来处理一些类似“展开/收缩”的样式。

ID为image的图片元素第一次被点击,我们要获取”this”(就是被点击的图片对象)并赋予它一个动画。即在一秒钟内完成图片的宽度变换到300px(1000表示毫秒即一秒)

}, function(){
$(this).animate({width: “100px”}, 1000);
$(’p').text(”Click To Zoom In”);

第二次点击图片,就要将图片的宽度改回到100px,并更改段落的相应文本。

我怎样创建一个“阅读更多内容”的链接,该链接一被点击就展开并向用户显示更多的内容?

看看效果

非常简单,先加点简单的html。

<p>
This is some text. This is some text. This is some text. This is some text. This
is some text. This is some text. This is some text. This is some text. This is some
text. This is some text. This is some text. <span class=”readMore”>Read More</span>
</p>
<p>
This is some text. This is some text. This is some text. This is some text. This
is some text. This is some text. This is some text. This is some text. This is some
text. This is some text. This is some text. This is some text. This is some text.
</p>

这只是些常规的文本,文本位于两个段落标记内。并且还有一个class=”readMore”的span的标记。当这个标记被点击,我们就要移走它。

现在来看看jQuery!

$(document).ready(function()
{
  $(’p:eq(1)’).hide();
  $(’span.readMore’).css({”cursor” : “pointer”, “color” : “blue”, “font-size” : “.8em”}).click(function()
{
  $(’p:eq(1)’).fadeIn(”slow”);
  $(this).fadeOut(”normal”);
});
});

在这里,我们要隐含第二个段落,p:eq(1),记住,javascript是以零为基准,也就是用0表示第一个元素或对象。所以,这里的”1″就相当于第二个段落。

$(’span.readMore’).css({”cursor” : “pointer”, “color” : “blue”, “font-size” : “.8em”}).click(function()

接着,我们获取class=”readMore”的span元素,并设置一些css属性。我们改变了这个元素的指针移到时的光标样式,为了让用户知道这是一个可以点击操作的地方。接下来我们会改变它的颜色,以一个随机的颜色来突显这个span标记。我们还将减小span标记文本的大小,就小一格吧。接下来我们为span标记设置一个点击事件函数。

$(’p:eq(1)’).fadeIn(”slow”);
$(this).fadeOut(”normal”);

当span标记被点击时,我们要获取第二个段落对象(p:eq(1)),并且让段落淡入。其中”this”(就是被点击的span标记对象)将会在0.4秒(默认)内完成淡出效果。

这就是操作的全部。

我怎样才能不论何时点击图片都会移动确切数量的像素?

看看效果

5行代码我就可以解决问题,Bob!

<img src=”img/logo.gif” alt=”Detached Designs” id=”image”>
<a href=”#” id=”scroll”>Scroll</a>

简单的html,这只是一个图片和一个超链接。现在轮到jQuery了。

$(document).ready(function()
{
  $(”#scroll”).click(function()
{
var theLeftAmount = $(”#image”).css(”left”);
var theNumber = parseFloat(theLeftAmount, 10);
theNumber += 25;
var amountToShift = theNumber + “px”;
$(”#image”).css(”left”, amountToShift); });
});

在这儿,我们来分析一下!

$(document).ready(function()
{
  $(”#scroll”).click(function()

html打开完成了,我们要获取id为scroll的超链接元素对象,并为其声明一个点击事件函数。

var theLeftAmount = $(”#image”).css(”left”);
var theNumber = parseFloat(theLeftAmount, 10);
theNumber += 25;
var amountToShift = theNumber + “px”;

被点击后做些什么呢?这里,我们要创建一些变量。为使图片能够移动,我们还要改变它的CSS样式的”left”属性。这个”theLeftAmount”变量要保存图片的当前CSS样式的left属性值。这个图片的left属性如果在CSS文档里为”20px”……那么”theLeftAmount”变量也相应的是”20px”。

“theNumber”变量要对”theLeftAmount”变量进和分析,提取数值字符串和去掉”px”。那个”10″的参数表示进制,我们当然是要10进制。

接下来,我们将其自增25px。再创建一个新的变量叫”amountToShift”来接收”theNumber”变量,再加上单位,本例是”px”。

$(”#image”).css(”left”, amountToShift); });

最后,我们用新的值(amountToShift)来改变图片的left属性。

请记住,所有的这些例子里都是使用.css直接将样式添加到HTML中。我的本意是保持简单的叙述。理想的做法是,你要添加的样式可以放到样式表里,然后用.addClass方法来提取它们。

最后的一个问题由我来问你们所有人

有没有某些地方需要我在将来的教程中着重讲解的?谢谢!我希望所有的一切都能对你有所帮助。