前十一式的招式,大多一句话就能点完;这一式我们回头看两件容易被忽略的内功—— 链式调用的“刚才那一步在哪”,和自己动手去量网页元素的尺寸与位置。
- 链式调用为什么能一路点下去,以及适时换行的写法
.end()回到上一环、.addBack()把上一环并回来- 量尺寸:
width/height/innerWidth/outerWidth - 定位置:
offset()/position()/scrollTop() .data():把数据挂在元素上,刷新前一直存在
链式调用:一气呵成
jQuery 的绝大多数方法都返回自己(那个 jQuery 对象),所以可以一路点下去。 就像一句话说到一半不停顿:“找到卡片 → 给它一条边 → 里面的字变色 → 再淡入”。 写的时候别怕换行:一行一个动作,读起来比挤成一长条清楚得多。
.end() 的作用就在注释里:把“操作对象”退回一步。
没有它,第三步之后你就只能继续操作段落;有了它,第四步又能回到容器身上。
这在你不得不在“父子元素之间来回切换”时特别省事。
不加 .end():边框落在段落上,容器保持原样
我是段落
加了 .end():页面先给段落上色,再退回来给容器加边
我是段落
还有一个亲兄弟 .addBack():它不是“退回”,而是“把上一环也叫回来一起操作”。
典型场景:$('#box').find('.item').addBack() 得到的是“容器 + 它里面的 item”,
适合做“父容器与子元素一起”的一次性处理。
量尺寸:width 与 height 家族
元素的“宽度”其实有好几层含义,jQuery 把它们分别做成方法,量的是哪一层一眼便知:
| 方法 | 量的范围 |
|---|---|
width() / height() | 内容区(不含内边距、边框、外边距) |
innerWidth() / innerHeight() | 内容区 + 内边距 |
outerWidth() / outerHeight() | 内容区 + 内边距 + 边框 |
outerWidth(true) | 连外边距也算上 |
传数字进去就是设置尺寸,例如 $('#box').width(300);
不传参数就是读取当前计算值(读回来的都是像素数字,不带单位)。
定位置:offset / position / scrollTop
offset()——元素相对于文档左上角的位置,返回{top: …, left: …};position()——元素相对于最近的定位祖先的位置(“我被摆在哪”);scrollTop()——滚动条往下滚了多少像素;传0就滚回顶部。
第一行:往下滚,看看读数怎么变。
第二行:scrollTop 会告诉你答案。
第三行:它统计的是“向上滚出视野”的像素。
第四行:滚到底再点按钮看看。
第五行:路过人间。
第六行:终点线在下面。
第七行:要滚到底了。
第八行:到头了。
点上面的按钮,读数显示在这里。
数据缓存:.data()
.data(key, value) 把一小份数据挂在元素上,读的时候 .data(key) 取回,
.removeData(key) 删除。它和 attr('data-…') 的区别是:
.data() 存的是真正的 JavaScript 值(数字、数组、对象都行),
不会写进 HTML,也不怕被序列化成字符串——适合放“临时状态”:
点了几次、选中了哪一项、上一次的值是什么。
已经点了 0 次;元素身上挂着的数据是 0。
页面初始值写在 HTML 的 data-* 属性里,用 .attr() 读;
程序运行起来后的临时状态用 .data() 存。
两者同名时会互相“偷看”(首次 .data('k') 会去读 data-k 属性),
但之后各存各的——同一份数据只用一个来源,才不会自己跟自己打架。
- 用一条链式完成:给
#jq12-end里的段落加fw-bold,退回来给容器加border,再给容器追加一行小字。 - 做一个“回到顶部”按钮:点击时让页面的滚动条回到顶部(提示:窗口的滚动位置用
$(window).scrollTop())。 - 思考题:链式调用越长越好吗?什么时候应该拆成几段写?
参考答案 1
end() 的落点要看清楚:它把操作对象从“段落”退回“容器”;
之后的操作都在容器上,直到链条结束。写成多行、对齐缩进,读起来像一段小剧本。
参考答案 2
同时写 html 与 body 是历史遗留的习惯——不同浏览器把“页面滚动条”
挂在不同的元素上,两个都写就不会扑空。animate({ scrollTop: 0 })
比直接 scrollTop(0) 多了一段平滑滚动的过程。
参考答案 3
不是越长越好。链式的好处是表达“同一批元素的连续动作”;
一旦中途换了主语、或者中间需要判断(if)、需要复用某个中间结果,
就该果断断开赋值给变量。还有一个现实因素:链式过长,出错时定位困难——
报错行号只能告诉你“这一长条里有问题”,却不告诉你是哪一环。
心法一句话:一气呵成的写成链,需要喘气的就另起一行。
本式小结
- 链式调用靠“方法返回自己”串起来,一行一个动作、对齐缩进最易读;
.end()退回上一环,.addBack()把上一环并进来;- 尺寸四层:
width(内容)→innerWidth(含内边距)→outerWidth(含边框)→outerWidth(true)(含外边距); offset()相对文档、position()相对定位祖先、scrollTop()管滚动;.data()存运行时状态,data-*属性存初始值,一个数据一个来源。
下一式,我们不再满足于用别人的招式——亲手造一个插件。