zoukankan      html  css  js  c++  java
  • 立即执行函数

    视频地址:你真的知道『立即执行函数』吗?

    立即执行函数(IIFE) == `Immediately Invoked Function Expression`

    函数声明和函数表达式

    // 函数声明 !== 函数表达式
    function test1 () {
      console.log('Function Declaration');
    }
    
    // 把一个(匿名)函数(函数声明式)赋值给一个变量的形式
    var test2 = function () {
      console.log("Function Expression");
    }
    
    // 对于函数名后边的括号,叫做执行符号
    test1()
    test2()
    
    // 语法错误:执行符号只能跟在表达式后边
    function test3 () {
      console.log('Function Declaration');
    }()

    当一个函数是需要立即执行时,必须是表达式形式

    var fn =(function () {
      console.log('Function Expression');
    })();
    
    // 或者(任何运算都是表达式)
    +(function () {
      console.log('Function Expression');
    })();
    
    (
      // W3C推荐的立即执行函数的规范
      (function () {
        console.log('Function Expression');
      })()
    );
    
    // 实践中
    (function () {
      console.log('Function Expression');
    })();

    立即执行函数的特点

    (function test(a, b, c, d) {
      /**
       * 1. 可以创建一个与外界没有任何关系的作用域,独立作用域
       * 2. 执行完立即销毁
       * ES3 ES5 没有模块的概念,立即执行函数来模拟模块化
       * 向外部抛出一系列属性和方法
       * window上保存的属性和方法
       */
      console.log(test);
      console.log(test.length);
      console.log(arguments.length);
      console.log('hello');
    })(1, 2, 3);
    
    // test() // 抱错—— 外部无法得到这个函数

    demo

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
          #my-tab {
            width: 500px;
            height: 500px;
            border: 1px solid #000;
            margin: 50px auto;
          }
          .tab-wrapper {
            height: 50px;
            border-bottom: 1px solid #000;
          }
          .tab-item {
            float: left;
            width: 33.33%;
            height: 50px;
            text-align: center;
            line-height: 50px;
          }
          .tab-item.current {
            background-color: #000;
            color: #fff;
          }
          .page-wrapper {
            position: relative;
            height: 450px;
          }
          .page-item {
            display: none;
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 450px;
            text-align: center;
            line-height: 450px;
          }
          .page-item.current {
            display: block;
          }
    
        </style>
      </head>
      <body>
        <div
          id="my-tab"
          data-type='[
       {
         "tab": "选项一",
         "page": "页面1"
       },
       {
         "tab": "选项二",
         "page": "页面2"
       },
       {
         "tab": "选项三",
         "page": "页面3"
       }
      ]'
        ></div>
        <script src="./utils.js"></script>
        <script src="./tpl.js"></script>
        <script src="./index.js"></script>
        <script>
          new MyTab('#my-tab');
        </script>
      </body>
    </html>

    utils.js

    var tools = (function () {
      function tplReplace (tpl, replaceObj) {
        return tpl.replace(/{{(.*?)}}/g, function (node, key) {
          return replaceObj[key.trim()]
        })
      }
      return {
        tplReplace: tplReplace
      }
    })()

    tpl.js

    var tpl = (function () {
      function tab (field) {
        switch (field) {
          case 'tab':
            return (
              `<div class="tab-item {{ current }}">{{ tab }}</div>`
            )
          case 'page':
            return (
              `<div class="page-item {{ current }}">{{ page }}</div>`
            )
          default:
            break;
        }
      }
      return {
        tab: tab
      }
    })()

    index.js

    ; (function (doc, tpl, tools) {
      // 定义MyTabl方法
      function MyTab (el) {
        // 获取元素
        this.el = doc.querySelector(el);
        // 获取元素数组
        this.data = JSON.parse(this.el.getAttribute("data-type"));
        // 设置默认展示第一个
        this._index = 0;
        // 初始化方法
        this.init()
      }
      MyTab.prototype.init = function () {
        // 渲染页面
        this._render()
        // 绑定方法
        this._bindEvent()
      }
      // 渲染页面
      MyTab.prototype._render = function () {
        // 创建 tab 元素
        var tabWrapper = doc.createElement('div')
        // 创建 page 元素
        var pageWrapper = doc.createElement('div')
        // 为了避免多次将节点插入document,采用 Fragment
        var oFrag = doc.createDocumentFragment()
        // 定义默认类名
        tabWrapper.className = 'tab-wrapper'
        pageWrapper.className = 'page-wrapper'
        // 遍历标签data
        this.data.forEach(function (item, index) {
          // 将 模板内的元素,替换为 this.data 的数据
          tabWrapper.innerHTML += tools.tplReplace(tpl.tab('tab'), {
            tab: item.tab,
            current: !index ? 'current' : ''
          })
          pageWrapper.innerHTML += tools.tplReplace(tpl.tab('page'), {
            page: item.page,
            current: !index ? 'current' : ''
          })
        })
        // 将 html 代码片段添加到 fragment
        oFrag.appendChild(tabWrapper)
        oFrag.appendChild(pageWrapper)
        // 将 fragment 挂载到页面上
        this.el.appendChild(oFrag)
      }
      // 为每一个 tab 绑定方法
      MyTab.prototype._bindEvent = function () {
        // 获取 tab 和 page 的所有元素
        var doms = {
          oTabItems: doc.querySelectorAll('.tab-item'),
          oPageItems: doc.querySelectorAll('.page-item'),
        }
        // 绑定点击事件 注意: 此时bind后的 this 是指向当前的el元素
        this.el.addEventListener('click', this._handlerTabClick.bind(this, doms))
      }
      MyTab.prototype._handlerTabClick = function () {
        // 获取 tab/page 所有元素、点击的元素、以及点击元素的类名
        var _doms = arguments[0], tar = arguments[1].target, className = tar.className.trim();
        // 判断点击元素,如果没有 current 类名,则更新视图
        if (className === 'tab-item') {
          // 给原来激活的元素重置类名
          _doms.oTabItems[this._index].className = 'tab-item';
          _doms.oPageItems[this._index].className = 'page-item';
          // 获取最新激活的元素索引
          this._index = [].indexOf.call(_doms.oTabItems, tar);
          // 给点击的tab元素添加 current 类
          tar.className += ' current';
          // 给点击的tab对应的 page 添加 current 类
          _doms.oPageItems[this._index].className += ' current';
        }
      }
      window.MyTab = MyTab
    })(document, tpl, tools)
    一个vue的UI库:https://github.com/houfee/light-ui,如果对您有帮助,请star ^-^
  • 相关阅读:
    文件内容排名算法,输入排名函数,返回排名后的文件名
    线段树做大数据排序
    给字符排序-基类排序二分查找-JavaScript
    后缀数组、名次数组-JavaScript
    二分查找法、二分去重排序法,返回最接近的位置和实际位置
    用四叉树对图像分类,获取tag和key
    Linux显示所在Git分支
    Linux中设置Git显示颜色
    屏蔽网页广告
    tf.add_to_collection,tf.get_collection简介
  • 原文地址:https://www.cnblogs.com/houfee/p/14511013.html
Copyright © 2011-2022 走看看