all files / dom/css/ compact.js

100% Statements 66/66
100% Branches 71/71
100% Functions 6/6
100% Lines 66/66
48 statements, 3 functions, 61 branches Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137                                                                                                                                             
import { avalon, oneObject,msie } from '../../seed/core'
import { cssMap, cssHooks, getWindow } from './share'
 
/* istanbul ignore if */
Iif (msie < 9) {
    avalon.shadowCopy(cssMap, oneObject('float','styleFloat'))
    var rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i
    var rposition = /^(top|right|bottom|left)$/
    var ralpha = /alpha\([^)]+\)/i
    var ropactiy = /(opacity|\d(\d|\.)*)/g
    var ie8 = msie === 8
    var salpha = 'DXImageTransform.Microsoft.Alpha'
    var border = {
        thin: ie8 ? '1px' : '2px',
        medium: ie8 ? '3px' : '4px',
        thick: ie8 ? '5px' : '6px'
    }
    cssHooks['@:get'] = function (node, name) {
        //取得精确值,不过它有可能是带em,pc,mm,pt,%等单位
        var currentStyle = node.currentStyle
        var ret = currentStyle[name]
        if ((rnumnonpx.test(ret) && !rposition.test(ret))) {
            //①,保存原有的style.left, runtimeStyle.left,
            var style = node.style,
                left = style.left,
                rsLeft = node.runtimeStyle.left
            //②由于③处的style.left = xxx会影响到currentStyle.left,
            //因此把它currentStyle.left放到runtimeStyle.left,
            //runtimeStyle.left拥有最高优先级,不会style.left影响
            node.runtimeStyle.left = currentStyle.left
            //③将精确值赋给到style.left,然后通过IE的另一个私有属性 style.pixelLeft
            //得到单位为px的结果;fontSize的分支见http://bugs.jquery.com/ticket/760
            style.left = name === 'fontSize' ? '1em' : (ret || 0)
            ret = style.pixelLeft + 'px'
            //④还原 style.left,runtimeStyle.left
            style.left = left
            node.runtimeStyle.left = rsLeft
        }
        if (ret === 'medium') {
            name = name.replace('Width', 'Style')
            //border width 默认值为medium,即使其为0'
            if (currentStyle[name] === 'none') {
                ret = '0px'
            }
        }
        return ret === '' ? 'auto' : border[ret] || ret
    }
    cssHooks['opacity:set'] = function (node, name, value) {
        var style = node.style
 
        var opacity = Number(value) <= 1 ? 'alpha(opacity=' + value * 100 + ')' : ''
        var filter = style.filter || ''
        style.zoom = 1
        //不能使用以下方式设置透明度
        //node.filters.alpha.opacity = value * 100
        style.filter = (ralpha.test(filter) ?
            filter.replace(ralpha, opacity) :
            filter + ' ' + opacity).trim()
 
        if (!style.filter) {
            style.removeAttribute('filter')
        }
    }
    cssHooks['opacity:get'] = function (node) {
        var match = node.style.filter.match(ropactiy) || []
        var ret = false
        for (var i = 0, el; el = match[i++];) {
            if (el === 'opacity') {
                ret = true
            } else if (ret) {
                return (el / 100) + ''
            }
        }
        return '1' //确保返回的是字符串
    }
}
 
/* istanbul ignore next */
avalon.fn.offset = function () { //取得距离页面左右角的坐标
    var node = this[0],
        box = {
            left: 0,
            top: 0
        }
    Iif (!node || !node.tagName || !node.ownerDocument) {
        return box
    }
    var doc = node.ownerDocument
    var body = doc.body
    var root = doc.documentElement
    var win = doc.defaultView || doc.parentWindow
    Eif (!avalon.contains(root, node)) {
        return box
    }
    //http://hkom.blog1.fc2.com/?mode=m&no=750 body的偏移量是不包含margin的
    //我们可以通过getBoundingClientRect来获得元素相对于client的rect.
    //http://msdn.microsoft.com/en-us/library/ms536433.aspx
    if (node.getBoundingClientRect) {
        box = node.getBoundingClientRect() // BlackBerry 5, iOS 3 (original iPhone)
    }
    //chrome/IE6: body.scrollTop, firefox/other: root.scrollTop
    var clientTop = root.clientTop || body.clientTop,
        clientLeft = root.clientLeft || body.clientLeft,
        scrollTop = Math.max(win.pageYOffset || 0, root.scrollTop, body.scrollTop),
        scrollLeft = Math.max(win.pageXOffset || 0, root.scrollLeft, body.scrollLeft)
    // 把滚动距离加到left,top中去。
    // IE一些版本中会自动为HTML元素加上2px的border,我们需要去掉它
    // http://msdn.microsoft.com/en-us/library/ms533564(VS.85).aspx
    return {
        top: box.top + scrollTop - clientTop,
        left: box.left + scrollLeft - clientLeft
    }
}
 
//生成avalon.fn.scrollLeft, avalon.fn.scrollTop方法
/* istanbul ignore next */
avalon.each({
    scrollLeft: 'pageXOffset',
    scrollTop: 'pageYOffset'
}, function (method, prop) {
    avalon.fn[method] = function (val) {
        var node = this[0] || {}
        var win = getWindow(node)
        var root = avalon.root
        var top = method === 'scrollTop'
        Eif (!arguments.length) {
            return win ? (prop in win) ? win[prop] : root[method] : node[method]
        } else {
            if (win) {
                win.scrollTo(!top ? val : avalon(win).scrollLeft(), top ? val : avalon(win).scrollTop())
            } else {
                node[method] = val
            }
        }
    }
})