淘宝 flexible.js 源码分析

pink老师有点意思~

立即执行函数

1. 语法规范:

  1. (fucntion() {}) ()
  1. (function() {} ())

主要作用创建一个独立的作用域,避免了命名冲突
栗子

<body>
    <div style="width: 200px;"></div>
    <script>
        //立即执行函数
        function fn() {
            console.log(1);
        }
        fn();
        // 2. 写法
        // (function(){})()   (function(){}());
        (function(a, b) {
            console.log(a);
            var num = 10;
            console.log(num);
        })(1, 2); // 第二个小括号可以看做是调用函数

        (function(a, b) {
            console.log(a + b);
            var num = 10;
        }(1, 2)); // 第二个小括号可以看做是调用函数
        // 3. 立即执行函数最大的作用就是独立创建了一个作用域
    </script>
</body>

2 下面三种情况都会刷新页面,都会触发load事件:

  1. a标签的超链接
  2. F5或者刷新按钮(强制刷新)
  3. 前进后退按钮

但是火狐浏览器有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里。所以此时后退按钮不能刷新页面。

此时可以使用pageshow事件来触发。这个事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件给window添加。

3. flexible.js源码

    <script>
        (function flexible(window, document) {
            // 获取html的根元素
            var docEl = document.documentElement
                // dpr 是物理像素比
            var dpr = window.devicePixelRatio || 1

            // adjust body font size 设置body的字体大小
            function setBodyFontSize() {
                // 如果页面中有body这个元素,就设置body的字体大小
                if (document.body) {
                    document.body.style.fontSize = (12 * dpr) + 'px'
                } else {
                    // 就是在引入时没有加载到body
                    // 如果页面中没有body这个元素,则等着页面的主要DOM元素加载完毕再去设置body的字体大小
                    document.addEventListener('DOMContentLoaded', setBodyFontSize)
                }
            }
            setBodyFontSize();

            // set 1rem = viewWidth / 10 (自己划分rem) 设置html元素的文字大小
            function setRemUnit() {
                var rem = docEl.clientWidth / 10
                docEl.style.fontSize = rem + 'px'
            }

            setRemUnit()

            // reset rem unit on page resize  当页面尺寸大小发生变化的时候,要重新设置下rem的大小
            window.addEventListener('resize', setRemUnit)
                // pageshow 是重新加载页面触发的事件
            window.addEventListener('pageshow', function(e) {
                // e.persisted 返回的是true,就是说如果这个页面是从缓存取过来的页面,也需要重新计算一下rem的大小
                if (e.persisted) {
                    setRemUnit()
                }
            })

            // detect 0.5px supports  有些移动端的浏览器不支持0.5像素的写法
            if (dpr >= 2) {
                var fakeBody = document.createElement('body')
                var testElement = document.createElement('div')
                testElement.style.border = '.5px solid transparent'
                fakeBody.appendChild(testElement)
                docEl.appendChild(fakeBody)
                if (testElement.offsetHeight === 1) {
                    docEl.classList.add('hairlines')
                }
                docEl.removeChild(fakeBody)
            }
        }(window, document))
    </script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章