当前位置:嗨网首页>书籍在线阅读

17-讨论

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

7.3.3 讨论

在HTML和CSS中设计了折叠特效的布局,其中的元素都向左浮动。如果将这样的布局用在一个网页上,可能应该在折叠之后直接添加一个清除元素,使后面的内容能够有正常的流程。

通过向左浮动元素,折叠特效以 h3>a 作为内容面板的标题。

如果禁用CSS和JavaScript,内容流程正常,而且可以被Google等搜索引擎理解。

如果启用CSS而禁用JavaScript,默认的视图可以看到所有内容面板。

使用jQuery,通过隐藏除了第一个面板之外的所有面板初始化显示,并将单击处理程序绑定到标题,将内容滑入/滑出可视区域。

水平折叠特效已经被制作成一个jQuery插件,特别要说明的是,不需要在折叠特效中硬编码任何变量。只要将持续速度变量传递给插件,就能确定特效的持续时间。可以简单地升级该插件,使其能够进行缓动工作或者回调。

要注意的是,在整段代码中,所有单击处理和DOM浏览都围绕 <h3> 元素而非 <a> 元素发生。这仍然习以为常工作,保持代码相对简单(不需要从 <a> 元素向上和向下浏览以得到父元素 <h3> 和邻近的 <div> 元素),但是更重要的是,因为 <a> 元素能够用Tab键进入和通过键盘触发,所以这些代码能够提供键盘可访问性。不必为 <a> 元素绑定单击事件处理程序,因为当 <a> 元素触发单击事件(通过单击或者键盘)时,事件会通过DOM向上冒泡,从而被 <h3> 元素上的单击处理程序捕获。

该插件首先收集折叠特效的必要部分:可单击的标题、第一个可见的面板和面板的宽度(注意,这个版本的插件只能用于相同尺寸的面板):

var $accordionHeaders = $(this).find('h3'),

this 是当前的折叠包装器元素,通常是一个 <div>

从折叠包装器中,代码收集所有 <h3> 元素。注意,将使用 next()prev() 将DOM集合从 <h3> 改为DOM树中的下一个节点,特别是各个折叠内容面板:

$open = $accordionHeaders.next().filter(':first'),

$open 是一个临时变量,指向当前可见的面板。不能使用 .is(':visible') ,因为实际上减少了宽度,而面板仍然有 display: block 属性。所以,通过这个 $open 变量跟踪当前面板:

width = $open.outerWidth();

在初始化的最后,捕捉打开的面板的宽度,以便正确地显示变动面板宽度的动画。

现在还剩下两件工作:

  • 初始化面板视图,仅显示第一个面板;
  • 绑定单击处理程序以显示/隐藏面板。

当初始化视图时,隐藏第一个之外的所有面板。还必须将宽度设置为0,使动画函数能够逐渐增加宽度,而不是在显示的时候“弹出”面板。

使用来自 $open 变量的反向过滤器来实现这一功能,特别是 :not(:first)

$accordionHeaders.next().filter(':not(:first)').css({ display : 'none',width : 0 });

一旦选择了除了第一个之外的其他面板,就修改CSS属性对其进行初始化。

最后,附加单击处理程序。

记住, $accordionHeaders 包含 h3 元素,所做的第一件事情就是:如果单击的 <h3> 就是当前打开的面板,那么什么也不做。

因为 $open 变量就是面板,所以使用 .prev() 浏览前一个 <h3> 元素,测试它与单击元素的当前上下文是否匹配。如果单击的元素不是当前打开的面板,就将 $open 面板的宽度`逐渐减小为0,而将当前单击的面板宽度逐步增大为捕捉到的宽度。

注意单击事件处理程序的最后一行:

$open = $(this).next().animate({ width : width }, { duration : speed });

因为jQuery通常返回jQuery(除了获取一个值的时候),而且将要以动画显示的是现在要打开的面板,所以可以同时捕捉 $open 变量中的面板,用最新的面板覆盖它。