对avalon的类名操作进行升级

在对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的类名操作进行升级

时间: 2024-10-10 21:39:27

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

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

ms-class是avalon用得最多的几个绑定之一,也正因为如此其功能一直在扩充中.根据时期的不同,分为旧风格与新风格两种. 旧风格是指ms-class-xxx=”expr”,*ms-class-aaa-bbb=”expr”*.正如第三节<绑定属性与扫描机制>所讲,一个绑定属性分成三部分,第一部分是ms,第二部分是class,第三部分是第二个-之后的所有字符串,它们被称之为param.上面的xxx与aaa-bbb都是我们要处理里的类名.等号后面的expr是一个表达式,根据它们的真假值决定是添

图书数据库操作界面升级

今年年初,我写了一篇名为<图书管理库以及操作界面>的文章(链接:http://blog.csdn.net/qq_32897527/article/details/50493313),但是由于技术问题,导致程序不是很优化,界面也不是很友好.最近得空稍微研究了下,对界面进行了升级. 1.使用表格进行数据项显示 升级前 升级后 #coding:gbk import wx,sqlite3 import wx.lib.sheet as sheet class find(wx.Frame): def lo

jq 筛选选择器,方法,隐式迭代 元素显示隐藏 淡入淡出 上拉下拉 动画 类名操作以及样式

jQuery 地址:https://jquery.com/ 历史版本:http://code.jquery.com/ 1.x:兼容 IE678 低版本浏览器 2.x:不兼容 IE678 低版本浏览器 3.x:不兼容 IE678 低版本浏览器,官方主要维护版本 入口函数 // 一下两种入口函数 相当于原生中的 DOMContentLoaded $(function () { /* DOM加载完成的入口*/ }) $(document).ready(function(){ /* DOM加载完成的入口

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

一.下载升级包: http://pan.baidu.com/s/1kTmw9sr 如连接不可以用可以直接私聊我.QQ1841031740 二.升级: 下载完后,运行exe文件,如下图: NSG9000的管理地址:比如:192.168.0.1  根据nsg9000设置的ip来填写. 默认: 用户名:admin 密码 :nsgadmin 然后install等待安装完成. 三.NSG9K-6G使用文档: http://wenku.baidu.com/view/252723287375a417866f8

CoreData的操作(使用, 升级)

使用和多表嵌套 1.创建项目的时候选择use core data 2.添加实体,添加属性,添加关联表 3.可以在这修改1对1或者一对多 4.commond + N 生成类 选择位置  然后检查类里面是否正确 升级 1.点击corData文件 点击Add Model Version 2.选择最高版本, 3.点击Create NSManagedObjectSubclass 选择最新 选择model类,然后选择对应的文件夹,需要和原来的model类在一个文件夹下,然后覆盖原始的model 3.comm

JavaScript css类名操作

1.className 属性 直接对这个属性赋值可以添加 /修改类名 缺点:新的赋值会覆盖掉前面的值,即使保留之前的值基础上添加也无法保证没有重复 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initi

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命令在获取dabase信息步骤时提示输入pfile文件,无法next操作,升级阻塞.(不是在自己环境操作,暂无截图) 问题分析   oracle start mount步骤时会出现提示ORA-32004: obsolete or deprecated parameter(s) specified for

HTML5 DOM元素类名相关操作API classList简介(转载自张鑫旭大神)

一.其实事情的发展就像切水果 如果我们把元素的类名操作比作“切水果”游戏的话,其中一个单独的类名就好比“水果”或“炸弹”! DOM Level 2时代,类名的获取与设置,多半使用className属性,className的生效近似切水果的“一刀切”.在web的初期,交互什么的其实很简单的来:就像切水果刚开始的时候,一次就一个水果飞上来,一刀“咔嚓”切了就好,就像使用className赋个类名值,就算偶尔冒出2个水果,className也可以一刀切搞定的. 但是,随着web的发展,交互的逐渐复杂,

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

文章转自:豆豆系统收藏备用 win10预览版系统安装的用户非常多,现在最新版本已经到了10049,但是之前很多装了9926版本或者10041版本的同学在通过系统自动更新的时候,且发现,微软官方提供的速度超级的不给力,有用户反映下载了1天24小时都还没有下载好,小编也亲自测试了,还是没有好!今天在隔壁论坛一个高手分享了一个方法,也提供了资源,可以快速的从win10预览版9926升级到10049! 下面是隔壁论坛高手提供的升级包制作与说明! 当我们通过系统自带的更新与恢复界面下载完fbl_impre