环境检测与 DOM 工具


文档摘要

7.2 环境检测与 DOM 工具 器械台的第二格放着仪表与接口:一类是"判断手上的东西是什么"的检测工具,一类是"判断浏览器能做什么"的能力探测,还有一类处理 DOM 树关系的独立函数。本节还承接一章旧债——原教程的插件章在本册被合并至此,因为插件机制本质上只是给 jQuery 原型挂方法的固定仪式,属于这台机器的官方加装接口。 本节摘要:类型判断族( 、 、 、 、 )用于防御性编码,如今大半可由原生替代;能力探测的正解是特性检测而非浏览器嗅探;独立 DOM 工具 判定包含关系;插件机制 把自定义方法挂上 jQuery 原型,是类库生态的地基。 类型判断族:先问是什么,再决定怎么动 这族函数的典型岗位是接口入口的防御:函数答应接收配置对象,先 验一下身;答应接收数字,先 拦一拦。

7.2 环境检测与 DOM 工具

器械台的第二格放着仪表与接口:一类是"判断手上的东西是什么"的检测工具,一类是"判断浏览器能做什么"的能力探测,还有一类处理 DOM 树关系的独立函数。本节还承接一章旧债——原教程的插件章在本册被合并至此,因为插件机制本质上只是给 jQuery 原型挂方法的固定仪式,属于这台机器的官方加装接口。

本节摘要:类型判断族(isPlainObjectisFunctionisNumericisEmptyObjecttype)用于防御性编码,如今大半可由原生替代;能力探测的正解是特性检测而非浏览器嗅探;独立 DOM 工具 $.contains 判定包含关系;插件机制 $.fn.extend 把自定义方法挂上 jQuery 原型,是类库生态的地基。

类型判断族:先问是什么,再决定怎么动

$.isPlainObject({ a: 1 }); // true:纯对象字面量或 new Object $.isPlainObject(document.body); // false:DOM 节点不算 $.isFunction(function () {}); // true $.isNumeric('42'); // true:数字字符串也算 $.isNumeric('4ab'); // false $.isEmptyObject({}); // true:没有任何可枚举属性 $.type(/re/); // 'regexp':返回小写类型名字符串

这族函数的典型岗位是接口入口的防御:函数答应接收配置对象,先 isPlainObject 验一下身;答应接收数字,先 isNumeric 拦一拦。原生对照里,typeofArray.isArrayinstanceof 覆盖了多数场景,isNumeric 的"字符串数字也算"与 type 的统一字符串命名是它的方言特性——type 随 jQuery 3.3 起已标记废弃,新代码请用 typeofObject.prototype.toString 组合。

能力探测:问浏览器"能做什么"而不是"你是谁"

判断浏览器能力的正路是特性检测——直接问某个 API 存不存在,而不是猜浏览器版本。历史上 $.browser(按 user-agent 嗅探)早已废弃,$.support 是官方给的能力检测面板,但现代开发里更推荐按需手查:

// 特征检测的直觉写法:用之前先确认存在 if ('IntersectionObserver' in window) { // 用新接口做懒加载 } else { // 退回滚动事件的旧方案 }

这条思路在本册出现过好几次——第 4 章判断 closest 存不存在、第 6 章判断 fetch 与 JSONP 走哪条路,本质都是特性检测。把它上升为习惯:任何"新 API 上了老浏览器会怎样"的担忧,答案都是运行前查一次,而不是查一次浏览器名单然后祈祷。

独立 DOM 工具与插件机制

$.contains(容器, 可能的后代) 判定节点包含关系,委托代码里偶有出场(判断点击是否落在某区域内,比 closest 更轻)。原生对应是 Node.contains,同名同义,直接平移。

插件机制是本节的重头。所谓插件,就是把自定义方法挂上 $.fn(jQuery 原型),让所有 jQuery 对象立刻拥有它:

(function ($) { $.fn.tag = function (options) { // 规范一:支持配置合并(上一节的 extend 正好上岗) var opts = $.extend({ cls: 'tagged' }, options); // 规范二:this 是当前集合,each 处理每个元素 return this.each(function () { $(this).addClass(opts.cls); }); // 规范三:return this 保持链式 }; })(jQuery); $('.item').tag({ cls: 'picked' }).fadeOut('fast'); // 挂上即用,链式不断

三条规范各有来由。外层立即执行函数并把 jQuery 作为 $ 传入,是防 $ 被其他库占用(呼应 7.5 的 noConflict);配置合并让插件可定制;return this 是插件能继续链式的全部秘密——上一节"方法返回集合"的公理在这里变成一条纪律。原教程另立一章讲的 jQuery UI,本质是官方维护的大型插件集与交互组件库,现代项目里它的多数组件已被轻量方案替代,但"组件即插件"的思想在各类类库生态里一脉相承。

实战:给一个公开函数装上入口安检

检测工具的价值要放在真实场景里看。背景是标本页上的一个公开小函数:它接收配置对象并渲染候诊条目,最初版本天真地信任一切输入,页面一接错参数就静默罢工。

操作分两步。第一步在入口装安检:

function renderQueue(config) { if (!$.isPlainObject(config)) { console.warn('renderQueue 需要 config 对象,收到的是', $.type(config)); return; } if (config.max != null && !$.isNumeric(config.max)) { throw new Error('max 必须是数字'); } var items = $.isArray(config.items) ? config.items : []; // 安检通过,进入正常渲染 }

结果:把字符串、null、缺字段的对象分别喂进去,前两者被礼貌拦下并留下线索,第三者按空列表降级渲染,页面不再死给你看。解读——防御的层次有三等:致命参数直接抛错(让调用方立刻发现),可降级参数给默认值(让页面活着),可疑输入留日志(让排查有迹可循)。变式:若这个函数要交给团队外部使用,再加一层配置合并 $.extend(true, {}, defaults, config),安检与补全就都齐了——上一节的 extend 在这里正式与检测工具同台。

插件的默认值模式:tag 插件的完整形态

上面的插件还可以长成更规范的形态:默认值挂在插件名下,供使用者查阅与整体覆盖——

(function ($) { $.fn.tag.defaults = { cls: 'tagged', scope: 'closest' }; $.fn.tag = function (options) { var opts = $.extend({}, $.fn.tag.defaults, options); return this.each(function () { var host = opts.scope === 'self' ? $(this) : $(this).parent(); host.children().addClass(opts.cls); }); }; })(jQuery); $.fn.tag.defaults.cls = 'picked'; // 全局改默认 $('.row').tag({ scope: 'self' }); // 单次覆盖

这个形态的好处是"默认值成为公开文档":使用者一眼能查到全部可调项,也能一次改掉全站默认,而不必每次调用都传全套参数。对照主流插件的配置写法(传一个 options 对象、暴露 defaults、支持深合并),套路如出一辙——读懂这一个,就读懂了那个生态的配置约定。

检测工具与原生对照速查

检测需求 jQuery 写法 原生等价物 备注
纯对象判断 $.isPlainObject Object.getPrototypeOf(x) === Object.prototype 近似 原生没有一刀切的现成函数
函数判断 $.isFunction typeof x === 'function' 完全等价
数字判断 $.isNumeric typeof x === 'number' && !isNaN(x) jQuery 认数字字符串,语义不同
空对象判断 $.isEmptyObject Object.keys(x).length === 0 等价,原生更直白
数组判断 $.isArray Array.isArray jQuery 3 已是别名
节点包含 $.contains Node.prototype.contains 同名同义
类型名 $.type(已废弃) Object.prototype.toString.call 原生组合拳接班

这张表的读法:大多数检测已被原生覆盖,老代码迁移时逐行对号;真正值得一提的是 isNumeric 这类"语义型"检测——它替你做了字符串到数字的宽容判断,用原生替代时要决定要不要保留这份宽容,别让迁移悄悄改变行为。

要点复盘

  • 检测族用于接口防御;isNumeric 认数字字符串、type 已废弃,新代码用 typeof 组合拳。
  • 能力判断走特性检测(查 API 在不在),不走浏览器嗅探;$.browser 是反面教材。
  • $.contains 与原生 Node.contains 同名同义,判定包含关系。
  • 插件三规范:立即执行函数防冲突、配置合并可定制、return this 保链式。
  • 组件生态的本质是"方法挂原型";读懂一个插件的源码,需要的知识全册已备齐。

仪表与接口点验完毕。下一节进性能车间:四个高频止血点,和一份写代码时该绕开的反面清单。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U