只写一次执行函数 同时兼容桌面noConflict后的jQuery与移动端的Zepto

只写一次执行函数 同时兼容桌面noConflict后的jQuery与移动端的Zepto

💡 原文中文,约2100字,阅读约需5分钟。
📝

内容提要

老项目桌面端使用jQuery(noConflict后$不可用),移动端使用Zepto,且两者引入位置不同,导致中间层需求代码无法统一。解决方案是用立即执行函数传参区分jQuery和Zepto;桌面端用jq(ready)执行,移动端用addEventListener监听load后调用,从而兼容双端并支持ajax。

🔎

延伸解读

双端库差异的根源与影响

文章指出,桌面端因jQuery的noConflict导致$不可用,移动端则使用Zepto且默认$可用,同时两端库的引入位置不同(桌面在页头,移动在页尾)。这种差异使得中间层代码无法直接复用,需要针对不同平台做适配。这提醒我们,在维护多端项目时,库的引入方式和配置差异会直接影响代码的通用性。

形参立即执行函数的巧妙运用

通过将核心逻辑封装到函数fn中,并以$作为形参,再根据UA判断调用fn(jQuery)或fn(Zepto),实现了只写一次执行函数。这种方法避免了直接使用全局$,也绕过了noConflict的限制。对于需要兼容不同库的场景,这是一种简单有效的模式,但需注意UA判断的准确性。

加载时机与事件监听的取舍

桌面端因jQuery在页头已定义,可直接用jq(ready)执行;移动端因Zepto在页尾,需用addEventListener监听load事件,且将fn(Zepto)包裹在loadDone函数中避免未定义错误。这体现了根据库的引入位置选择合适加载时机的重要性,同时也利用了addEventListener支持多监听的优势。

方案局限与适用边界

该方案依赖于UA判断来区分平台,若UA被篡改或存在非典型设备,可能导致误判。此外,移动端使用load事件而非DOMContentLoaded,会延迟执行时机。文章未讨论错误处理或库加载失败的情况,因此在实际应用中需考虑这些边界条件,确保方案的健壮性。

❓

Q&A

桌面端 jQuery 用了 noConflict 后 $ 不可用,移动端用 Zepto,怎么让同一段代码同时兼容?

把公共代码封装到一个函数 fn 里,通过形参 $ 接收库对象。桌面端调用 fn(jQuery),移动端调用 fn(Zepto),这样代码只写一次,就能同时兼容两端。

桌面端 jQuery 在页头引入,移动端 Zepto 在页尾引入,编辑器代码怎么确保在库加载后执行?

桌面端因为 jQuery 已定义,直接用 jq(function(){ fn(jQuery) }) 在 ready 时执行;移动端 Zepto 尚未定义,用 window.addEventListener('load', loadDone) 监听 load 事件,在 loadDone 里调用 fn(Zepto)。

页面已有 onload 事件,不能重复使用,也不能用 ready,还有什么办法等页面加载完再执行代码?

可以用 addEventListener 监听 load 事件,它允许添加多个监听器,不会覆盖已有的 onload,适合移动端没有 IE8 兼容需求的场景。

移动端直接调用 fn(Zepto) 会报 Zepto 未定义,怎么避免?

不要直接执行 fn(Zepto),而是把 fn(Zepto) 放到一个函数(如 loadDone)里,通过 addEventListener 在 load 事件触发时再调用,此时 Zepto 已加载完成。

这个方案里如何判断当前是移动端还是桌面端?

通过正则 /iPhone|phone|android|iPod|pad|iPad/i 测试 navigator.userAgent.toLowerCase(),匹配则视为移动端,否则为桌面端。

方案中提到的 ajax 非简单请求问题是怎么解决的?

解决了 $ 的引用和加载时机后,就可以正常使用 jQuery 或 Zepto 的 ajax 方法,非简单请求不再需要额外处理。

🏷️

标签

➡️

继续阅读