在对SVG元素进行类名操作时,发现有一个坑爹的事情,它的className竟然是一个对象,因此报一系列BUG。第一次想到的方法是添加setClasses, getClasses两个更底层的方法。于是相应代码变成:

    var rclass = /\s+/g
function getClasses(node) {
if (node && node.className) {
var classes = node.className//SVG元素是返回一个SVGAnimatedString对象
if ("baseVal" in classes) {
classes = classes.baseVal
}
return classes.split(rclass)
}
return []
}
function setClasses(node, cls) {
if (node && node.nodeType === 1) {
if ("baseVal" in node.className) {
node.setAttribute("class", cls)
} else {
node.className = cls
}
}
} avalon.fn.mix({
hasClass: function(cls) {
var classList = getClasses(this[0])
if (classList.length) {
return (" " + classList.join(" ") + " ").indexOf(" " + cls + " ") > -1
}
return false
},
addClass: function(cls) {
var node = this[0]
if (cls && node && node.nodeType === 1) {
var arr = getClasses(node)
cls.replace(/\S+/g, function(c) {
if (arr.indexOf(c) === -1) {
arr.push(c)
}
})
setClasses(node, arr.join(" "))
}
return this
},
removeClass: function(cls) {
var node = this[0], classList = getClasses(node)
if (cls && classList.length) {
var set = " " + classList.join(" ") + " "
cls.replace(/\S+/g, function(c) {
set = set.replace(" " + c + " ", " ")
})
setClasses(node, set.slice(1, set.length - 1))
}
return this
},
toggleClass: function(value, stateVal) {
var state = stateVal,
className, i = 0
var classNames = value.split(rclass)
var isBool = typeof stateVal === "boolean"
while ((className = classNames[i++])) {
state = isBool ? state : !this.hasClass(className)
this[state ? "addClass" : "removeClass"](className)
}
return this
}
})

这里的麻烦处是,IE6,IE7不能直接通过getAttribute("class")得到className,而SVG如果直接用className又没有用,于是抽取出getClasses方法,赋值也一样。

在高级浏览器,classList在SVG中是没有兼容问题。看avalon.mobile的相关实现是多么简洁:

    "add,remove".replace(rword, function(method) {
avalon.fn[method + "Class"] = function(cls) {
var el = this[0]
//https://developer.mozilla.org/zh-CN/docs/Mozilla/Firefox/Releases/26
if (cls && typeof cls === "string" && el && el.nodeType == 1) {
cls.replace(/\S+/g, function(c) {
el.classList[method](c)
})
}
return this
}
}) avalon.fn.mix({
hasClass: function(cls) {
var el = this[0] || {} //IE10+, chrome8+, firefox3.6+, safari5.1+,opera11.5+支持classList,chrome24+,firefox26+支持classList2.0
return el.nodeType === 1 && el.classList.contains(cls)
},
toggleClass: function(value, stateVal) {
var state = stateVal,
className, i = 0
var classNames = value.split(/\s+/)
var isBool = typeof stateVal === "boolean"
var node = this[0] || {}, classList
if (classList = node.classList) {
while ((className = classNames[i++])) {
state = isBool ? state : !classList.contains(className)
classList[state ? "add" : "remove"](className)
}
}
return this
}
})

因此新的思路来了,为IE6-9等实现一个classList,通过它来屏蔽底层,再在classList的基础上构建avalon的addClass, removeClass, toggleClass,hasClass

    function ClassList(node) {
if (!("classList" in node)) {
node.classList = {
node: node,
toString: function() {
var node = this.node
return (node.hasAttribute ? node.getAttribute("class") || "" : node.className).split(/\s+/).join(" ")
},
contains: function(cls) {
return (" " + this + " ").indexOf(" " + cls + " ") > -1
},
_set: function(cls) {
var node = this.node
if (typeof node.className == "string") {
node.className = cls
} else {
node.setAttribute("class", cls)
}
},
add: function(cls) {
if (!this.contains(cls)) {
this._set(this + " " + cls)
}
},
remove: function(cls) {
this._set((" " + this + " ").replace(" " + cls + " ", " ").trim())
}
}
}
return node.classList
}
"add,remove".replace(rword, function(method) {
avalon.fn[method + "Class"] = function(cls) {
var el = this[0]
//https://developer.mozilla.org/zh-CN/docs/Mozilla/Firefox/Releases/26
if (cls && typeof cls === "string" && el && el.nodeType == 1) {
cls.replace(/\S+/, function(c) {
ClassList(el)[method](c)
})
}
return this
}
})
avalon.fn.mix({
hasClass: function(cls) {
var el = this[0] || {}
return el.nodeType === 1 && ClassList(el).contains(cls)
return false
},
toggleClass: function(value, stateVal) {
var state = stateVal,
className, i = 0
var classNames = value.split(/\s+/)
var isBool = typeof stateVal === "boolean"
while ((className = classNames[i++])) {
state = isBool ? state : !this.hasClass(className)
this[state ? "addClass" : "removeClass"](className)
}
return this
}
})

http://baike.baidu.com/view/957693.htm

对avalon的类名操作进行升级的更多相关文章

  1. 哈雷监控设备的操作及升级NSG9k6G

    哈雷监控设备的操作及升级NSG9k6G 一.下载升级包: http://pan.baidu.com/s/1kTmw9sr 如连接不可以用可以直接私聊我.QQ1841031740 二.升级: 下载完后, ...

  2. 迷你MVVM框架 avalonjs 学习教程9、类名操作

    ms-class是avalon用得最多的几个绑定之一,也正因为如此其功能一直在扩充中.根据时期的不同,分为旧风格与新风格两种. 旧风格是指ms-class-xxx=”expr”,*ms-class-a ...

  3. CentOS操作系统内核升级

    一.升级内核(带aufs模块,记住一定要升级,要不然会出现很多莫名奇怪的问题,建议用yum安装) 1.yum安装带aufs模块的3.10内核(或到这里下载kernel手动安装:http://down. ...

  4. win10预览版9926升级10049操作步骤

    文章转自:豆豆系统收藏备用 win10预览版系统安装的用户非常多,现在最新版本已经到了10049,但是之前很多装了9926版本或者10041版本的同学在通过系统自动更新的时候,且发现,微软官方提供的速 ...

  5. oracle数据库升级dbua操作阻塞解决方法(解决ORA-32004报错)

    操作环境 1.SuSE11sp3操作系统 2.oracle 11.2.0.3版本升级到11.2.0.4版本 问题现象   oracle 11.2.0.3版本升级到11.2.0.4版本时执行dbua命令 ...

  6. avalon学习笔记

    背景: 刚刚到一家新的公司,我新接手的项目采用的mvvm框架是avalon,当然我以前没有学过angular,但是用过react,所以对于这类框架应该不算陌生.但毕竟是一个新的框架,所以还是先学起来, ...

  7. 迷你MVVM框架 avalonjs 学习教程19、avalon历史回顾

    avalon最早发布于2012.09.15,当时还只是mass Framework的一个模块,当时为了解决视图与JS代码的分耦,参考knockout开发出来. 它的依赖收集机制,视图扫描,绑定的命名d ...

  8. 迷你MVVM框架 avalonjs 学习教程8、属性操作

    属性操作是DOM操作很大的一块,它包括类名操作,表单元素的value属性操作,元素固有属性的管理,元素自定义属性的管理,某些元素的一些布尔属性的操作.大多数情况下,元素属性的值是字符串类型,我们称之为 ...

  9. Avalon探索之旅

    avalon2是一款基于虚拟DOM与属性劫持的 迷你. 易用. 高性能 的 前端MVVM框架, 拥有超优秀的兼容性, 支持移动开发, 后端渲染, WEB Component式组件开发, 无需编译, 开 ...

随机推荐

  1. Kaggle比赛冠军经验分享:如何用 RNN 预测维基百科网络流量

    Kaggle比赛冠军经验分享:如何用 RNN 预测维基百科网络流量 from:https://www.leiphone.com/news/201712/zbX22Ye5wD6CiwCJ.html 导语 ...

  2. SPOJ VLATTICE Visible Lattice Points 莫比乌斯反演 难度:3

    http://www.spoj.com/problems/VLATTICE/ 明显,当gcd(x,y,z)=k,k!=1时,(x,y,z)被(x/k,y/k,z/k)遮挡,所以这道题要求的是gcd(x ...

  3. Beta阶段第2周/共2周 Scrum立会报告+燃尽图 13

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2411] 版本控制:https://git.coding.net/liuyy08 ...

  4. Linux DMA Engine framework(2)_功能介绍及解接口分析

    http://www.wowotech.net/linux_kenrel/dma_engine_api.html 补充 http://www.zhimengzhe.com/linux/259646.h ...

  5. C# 序列化详解,xml序列化,json序列化对比

    本文讲讲一些纯技术的东西.并且讲讲一些原理性的东西,和一般的百度的文章不一致,如果你对序列化不清楚,绝对可以很有收获. 技术支持QQ群(主要面向工业软件及HSL组件的):592132877  (组件的 ...

  6. iOS 关于时间天数星期月份的总结

    #import <Foundation/Foundation.h> @interface NSDate (SLExtend) // 判断是否是本周更早 - (BOOL)isThisWeek ...

  7. 使用nomad && consul && fabio 创建简单的微服务系统

    具体每个组件的功能就不详细说明了 nomad 一个调度工具,consul 一个服务发现,健康检查多数据中心支持的工具 fabio 一个基于consul的负载均衡&&动态路由工具,对于集 ...

  8. timesacledb 测试demo数据运行

    timesacledb 的安装还是使用docker,对于测试数据需要提前下载 启动timesacledb 使用支持gis 的镜像,后边需要使用 docker run -d --name timesca ...

  9. ThinkPHP think-migration 简洁使用教程

    ThinkPHP think-migration 简洁使用教程 migration:一种数据库的版本控制,让团队在修改数据库结构的同时,保持彼此的进度一致.帮你更简单的管理数据库.基于原生 think ...

  10. windows默认文件浏览器大小

    windows打开之后,发现默认窗口很小.