Zepto的天坑汇总
目录
前言
最近在做移动端开发,用的是zepto,发现他跟jquery比起来称之为天坑不足为过,但是由于项目本身原因,以及移动端速度要求的情况下,也只能继续用下去。
所以在这里做一下汇总
对img标签空src属性用attr取值会取得当前url地址的BUG
如下图,某img标签有src属性,但是其src属性值为空,但是用zepto的attr取src属性值却是当前页面的url地址
BUG原因分析:
//zepto源码
attr: function(name, value){ var result return (typeof name == 'string' && !(1 in arguments)) ? (!this.length || this[0].nodeType !== 1 ? undefined : (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result ) : this.each(function(idx){ if (this.nodeType !== 1) return if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) }) },
问题在于这个 this[0][name] ,相当于直接取img标签DOM元素的src属性,而不是他的attributes属性里面的值。
在很多情况下元素的DOM属性和attributes属性是不一致的,比如臭名昭著的布尔类类型属性,jquery在这方面做了完善兼容而zepto就没有,非常简单粗暴。
临时解决方案:
编写一个原生js的获取属性的方法
function getAttr(ele, attr) { var e = ele.get(0); var attrs = e.attributes; if (attrs == undefined) { return ""; } else if (attrs[attr] == undefined) { return ""; } else { return attrs[attr].value; } }
判断当前对象是否是Zepto实例化对象的方法
在jquery中,判断是不是jquery实例化对象,直接用instanceof就行,即:
var a=$("body"); if(a instanceof jQuery){ //... }
但是在zepto中这样用是无效的,好在zepto自己提供了一份方法来判断,即:
var a=$("body"); if(Zepto.zepto.isZ(a)){ //... }
其源码是:也就是我们直接去判断instanceof是否zepto.Z即可。
// `$.zepto.Z` swaps out the prototype of the given `dom` array // of nodes with `$.fn` and thus supplying all the Zepto functions // to the array. Note that `__proto__` is not supported on Internet // Explorer. This method can be overriden in plugins. zepto.Z = function(dom, selector) { dom = dom || [] dom.__proto__ = $.fn dom.selector = selector || '' return dom } // `$.zepto.isZ` should return `true` if the given object is a Zepto // collection. This method can be overriden in plugins. zepto.isZ = function(object) { return object instanceof zepto.Z }
使用深度扩展($.extend(true,*,*))后的zepto对象无法使用zepto.isZ来继续判断的bug
直接看图:
原本正常的zepto对象,经过深度扩展后,变成不属于zepto对象了!!
再看下扩展前后的变化:
obj.a.__proto__;//Object {} obj2.a.__proto__;//[]
根据前面的zepto的源码可知,原始对象是有原型属性的,但是经过深度扩展后原型属性没有了!!!
这肯定是$.extend内部写的有问题了:
function extend(target, source, deep) { for (key in source) if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { if (isPlainObject(source[key]) && !isPlainObject(target[key])) target[key] = {} if (isArray(source[key]) && !isArray(target[key])) target[key] = [] extend(target[key], source[key], deep) } else if (source[key] !== undefined) target[key] = source[key] } // Copy all but undefined properties from one or more // objects to the `target` object. $.extend = function(target){ var deep, args = slice.call(arguments, 1) if (typeof target == 'boolean') { deep = target target = args.shift() } args.forEach(function(arg){ extend(target, arg, deep) }) return target }
看完以后发现简直太敷衍了好么!!
直接就用for in遍历也就算了,好歹也得判断下是对象属性还是原型属性呀!
当然既然原型没了,那原型上的方法也就自然全跑到对象上面去了,如此敷衍我也是醉了,如图:
临时解决方案:
目前没想到很好的解决办法,自己多加一些判断。如果有谁有更好的方案请一定告诉我。
扩展阅读
http://chaoskeh.com/blog/some-experience-of-using-zepto.html
如果您认为本文对得起您所阅读他所花的时间,欢迎点击右下角↘ 推荐。您的支持是我继续写作最大的动力,谢谢
作者:沧海月明
出处:http://www.cnblogs.com/xxcanghai/
本文地址:http://www.cnblogs.com/xxcanghai/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?