美文网首页Web前端之路让前端飞
自己昨晚封装的工具函数

自己昨晚封装的工具函数

作者: VisuperviReborn | 来源:发表于2017-08-25 10:40 被阅读59次
1.前几个DOM操作的自己测试过,后面那些都是有时候用到的,没测试,有问题的希望提出来,还没完全封装完,后期还会更新这个工具函数。
(function (window) {
  var Tools = {
    getElem: getElem,//获取元素
    getFirst: getFirst,//获取元素第一个子元素
    getPre: getPre,//获取元素的前一个兄弟节点
    getNext: getNext,//获取元素的下一个兄弟节点
    getLast: getLast,//获取元素的最后一个子节点
    getStyle: getStyle,//获取元素的外联计算样式
    addClass: addClass,//给元素添加类
    arrIndexOf: arrIndexOf,//数组查找
    removeClass: removeClass,//移除一个类
    setScroll: setScroll,//滚动条高度和宽度的获取
    getClientSize: getClientSize,//可视区域的大小
    getDatetoString: getDatetoString,//返回指定格式的日期
    browserRedirect: browserRedirect,//判断设备
    getUrlParams: getUrlParams,//获取path的值,例如:name = "Tom"
    //eventTools:eventTools,//对事件的封装
    animate: animate,//轮播图动画实现函数
    setSize: setSize,//响应式设置rem
    mouseDrop: mouseDrop,//鼠标拖拽事件
    getWH: getWH,//获取元素不带单位的宽度和高度
    setPosition: setPosition,//对轮播图进行封装
    ajax: ajax,//对ajax封装
  };
  //通过标签名,类名,标签名获取元素
  function getElem(selector, parent) {
    parent = parent || document;
    var firstChar = selector.charAt(0);
    if (firstChar === "#") {
      return document.getElementById(selector.substring(1));
    } else if (firstChar === ".") {
      var allEles = parent.getElementsByTagName("*");
      var arr = [];
      for (var i = 0; i < allEles.length; i++) {

        var arrClassName = allEles[i].className.split(" ");
        for (var j = 0; j < arrClassName.length; j++) {
          if (arrClassName[j] == selector.slice(1)) {
            arr.push(allEles[i]);
            break;
          }
        }
      }
      return arr;
    } else {
      return parent.getElementsByTagName(selector);
    }
  }

  //获取元素的第一个子节点
  function getFirst(ele) {
    var firstEle = ele.firstElementChild || ele.firstChild;
    if (!firstEle || firstEle.nodeType != 1) {
      return null;
    } else {
      return firstEle;
    }
  }

  //获取前一个兄弟节点
  function getPre(ele) {
    var prevEle = ele.previousElementSibling || ele.previousSibling;
    if (!prevEle || prevEle.nodeType != 1) {
      return null;
    } else {
      return prevEle;
    }
  }

  //获取后一个兄弟节点
  function getNext(ele) {
    var nextEle = ele.nextElementSibling || ele.nextSibling;
    if (!nextEle || nextEle.nodeType != 1) {
      return null;
    } else {
      return nextEle;
    }
  }

  //获取最后一个元素
  function getLast(ele) {
    var lastEle = ele.lastElementChild || ele.lastChild;
    if (!lastEle || lastEle.nodeType != 1) {
      return null;
    } else {
      return lastEle;
    }
  }

  //获取元素外联样式
  function getStyle(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr];
  }

  //获取元素的实际宽度和高度
  function getWH(obj) {
    return {
      width: obj.offsetWidth,
      height: obj.offsetHeight
    }
  }

  //封装了一个添加类的函数
  function addClass(obj, myClass) {
    //如果没有类 使用直接添加类的方式
    if (obj.className == "") {
      obj.className = myClass;
    } else {
      //进来里面 说明 它原来有类
      // 将它的类 转化成数组
      var arrClassName = obj.className.split(" ");
      //调用数组的查找方法 返回索引
      var _index = arrIndexOf(arrClassName, myClass);
      // 判断索引是否为-1 说明没找到 则加进去
      if (_index == -1) {
        obj.className += " " + myClass;
      }
    }
  }

  // 用于数组查找的函数
  function arrIndexOf(arr, myClass) {
    //循环数组 进行比较 如果找到 返回对应下标
    for (var i = 0; i < arr.length; i++) {
      if (arr[i] === myClass) {
        return i;
      }
    }
    // 经过循环 之后说明没找到 则返回-1
    return -1;
  }

  //封装一个移除class的函数
  function removeClass(obj, myClass) {
    if (obj.className != "") {
      // 将标签上的class 转成数组
      var arrClassName = obj.className.split(" ");
      // 调用数组查找方法 返回一个索引
      var _index = arrIndexOf(arrClassName, myClass);//[xixi, gaga, haha, hehe, jiji]
      if (_index != -1) {
        // 如果不等于-1
        // 将类的数组 通过删除方法去删除那一项
        arrClassName.splice(_index, 1);
        // 将删除那一项之后的数组重新通过join方法 转换回字符串 赋给标签的class
        obj.className = arrClassName.join(" ");
      }
    }
  }

  //滚动条高度和宽度的获取
  function setScroll() {
    return {
      scrollTop: document.body.scrollTop ||
      window.pageYOffset ||
      document.documentElement.scrollTop || 0,
      scrollLeft: document.body.scrollLeft ||
      window.pageXOffset ||
      document.documentElement.scrollLeft || 0
    }
  }

  //可视区域的大小
  function getClientSize() {
    return {
      clientX: window.innerWidth ||
      document.body.clientWidth ||
      document.documentElement.clientWidth || 0,
      clientY: window.innerHeight ||
      document.body.clientHeight ||
      document.documentElement.clientHeight || 0
    }
  }

// 返回指定格式的日期
  function getDatetoString(date) {
    var strDate;//存储日期的字符串
    //获取年
    var year = date.getFullYear();
    //获取月
    var month = date.getMonth() + 1;
    //获取日
    var day = date.getDate();
    //获取小时
    var hour = date.getHours();
    //获取分钟
    var minute = date.getMinutes();
    //获取秒
    var second = date.getSeconds();
    hour = hour < 10 ? "0" + hour : hour;
    minute = minute < 10 ? "0" + minute : minute;
    second = second < 10 ? "0" + second : second;
    //拼接
    strDate = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;//隐藏问题,关于变量声明的位置
    return strDate;
  }

  //判断设备
  function browserRedirect() {
    var sUserAgent = navigator.userAgent.toLowerCase();
    var bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
    var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
    var bIsMidp = sUserAgent.match(/midp/i) == "midp";
    var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
    var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
    var bIsAndroid = sUserAgent.match(/android/i) == "android";
    var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
    var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
    /*document.writeln("您的浏览设备为:");*/
    if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) {
      /* 链接到不同的网址  这个是手机的 */
      window.location.href = 'http://m.jd.com'
    } else {
      /* 链接到不同的网址  这个是PC的 */
      window.location.href = 'http://www.jd.com'
    }
  }

  //获取path的值,例如:name = "Tom"
  function getUrlParams(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); //定义正则表达式
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return decodeURI(r[2]);
    return null;
  }

  //所有属性都到达目标值之后才能清理定时器
  //封装 能够让 任意对象 的指定属性 变到指定值 的动画函数
  function animate(obj, json, fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
      var flag = true;
      for (var k in json) {
        if (k === "opacity") {//特殊处理
          //var leader = parseInt(getStyle(obj, k)) || 0;
          var leader = getStyle(obj, k) * 100;//1
          // 0 || 1 结果是1 那么如果透明度当前的值是0 就会变成1
          //所以这里不能给默认值 而且也没有必要
          //透明度没有单位px 所以也不用parseInt 参与运算自动变为数字
          var target = json[k] * 100;//0.5
          var step = (target - leader) / 10;//0.5-1=-0.5
          step = step > 0 ? Math.ceil(step) : Math.floor(step);//-1
          leader = leader + step;
          //obj.style[k] = leader + "px";
          obj.style[k] = leader / 100;//opacity没有单位
        } else if (k === "zIndex") {
          obj.style.zIndex = json[k];//无需渐变 直接设置即可
        } else {
          var leader = parseInt(getStyle(obj, k)) || 0;
          var target = json[k];
          var step = (target - leader) / 10;
          step = step > 0 ? Math.ceil(step) : Math.floor(step);
          leader = leader + step;
          obj.style[k] = leader + "px";
        }
        if (leader !== target) {
          flag = false;
        }
      }
      if (flag) {
        clearInterval(obj.timer);
        if (fn) {//如果有才调用
          fn();//动画执行完成后执行
        }
      }
    }, 15);
  }

  function getStyle(obj, attr) {
    if (window.getComputedStyle) {
      return window.getComputedStyle(obj, null)[attr];
    } else {
      return obj.currentStyle[attr];
    }
  }

  //封装rem设置实现响应式
  function setSize() {
    var oHtml = document.documentElement;
    // 获取屏幕的宽度
    var screenWidth = oHtml.offsetWidth;
    // 设计图的宽度,根据自己的设计图去填写
    var uiWidth = 750;
    // 自己设定的html的font值
    var fonts = 40;
    var rate = uiWidth / fonts;
    // 最开始的时候调用一次
    getSize();
    // resize的时候动态监听
    window.addEventListener('resize', getSize);
    function getSize() {
      screenWidth = oHtml.offsetWidth;
      // 如果说屏幕小于320 就限制在320对应的fontsize
      // 如果说大于设计图的宽度,就限制在设计图的宽度
      // 都不满足,就代表在正常的区间里面,就可以自由的动态计算
      if (screenWidth <= 320) {
        oHtml.style.fontSize = 320 / rate + 'px';
      } else if (screenWidth >= uiWidth) {
        oHtml.style.fontSize = uiWidth / rate + 'px';
      } else {
        // 动态设置当前屏幕对应的html的font值
        oHtml.style.fontSize = screenWidth / rate + 'px';
      }
    }
  }

  //对轮播图的移动进行的一个封装
  function setPosition(obj, target, num) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
      var leader = obj.offsetLeft,
        step = num;
      step = obj.offsetLeft < target ? step : -step;
      if (Math.abs(obj.offsetLeft - target) > Math.abs(step)) {
        leader = leader + step;
        obj.style.left = leader + "px";
      } else {
        // leader = leader + step;
        obj.style.left = target + "px";
        clearInterval(obj.timer);
      }
    }, 15);
  }

  //鼠标拖拽事件
  function mouseDrop(argus1, argus2) {//参数1,是整个被拖拽移动的元素,参数2是拖拽区域
    //鼠标在 拖动条上按下的时候可以拖动 鼠标移动的时候 获取鼠标的位置 整个盒子跟着鼠标的位置走
    argus2.onmousedown = function (event) {
      var event = event || window.event;
      var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
      var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
      var spaceX = pageX - argus1.offsetLeft;
      var spaceY = pageY - argus1.offsetTop;
      document.onmousemove = function (event) {
        var event = event || window.event;
        var pageX = event.pageX || event.clientX + document.documentElement.scrollLeft;
        var pageY = event.pageY || event.clientY + document.documentElement.scrollTop;
        argus1.style.left = pageX - spaceX + "px";
        argus1.style.top = pageY - spaceY + "px";
        //清理选中的文字
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

      }
    };
    document.onmouseup = function () {
      document.onmousemove = null;
    }
  }

  //对ajax进行封装
  function ajax(options) {
    var xhr = new XMLHttpRequest();
    if (options.type.toLocaleString() === "get") {
      options.url = options.url + "?" + params(options.data);
      options.data = null
    } else {
      options.data = params(options.data)
    }
    xhr.open(options.type, options.url);
    if (options.type.toLocaleString() === "post") {
      xhr.setRequestHeader("Content-type','application/x-www-form-urlencoded");
    }
    options.beforeSend && options.beforeSend();
    xhr.send(options.data);
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200 || xhr.status === 304) {
          var data = xhr.responseText;
          options.success && options.success(data);
        } else {
          options.error && options.error(xhr.status);
        }
        options.complete && options.complete();
      }
    }
  }

  function params(options) {
    var str = "";
    for (var attr in options) {
      str += attr + "=" + options[attr] + "&";
    }
    return str.slice(0, -1);
  }

  window.Tools = Tools;
})(window);
2.算是迭代的第二版,里面90%的代码全部实际猜测用过,后期还会用jQuery封装原理封装。

下面贴几个测试用例
第一个是封装轮播图动画函数,这里里面用到了获取元素的各种方式

(function () {
  Tools.setSize();
  var timer = null;
  var num = 0;
  var square = 0;
  var oLeft = Tools.getElem(".left");
  var oRight = Tools.getElem(".right");
  var arrow = Tools.getElem(".arrow");
  console.log(arrow[0]);
  var outter = Tools.getElem(".wrap");
  var WrapWidth = Tools.getWH(outter[0]).width;
  console.log(WrapWidth);
  var inner = Tools.getElem("ul");
  var ulLis = Tools.getElem("li", inner[0]);
  var oOl = Tools.getElem("ol");
  var oFrag = document.createDocumentFragment();
  for (var i = 0; i < ulLis.length; i++) {

    var li = document.createElement("li");
    if (i === 0) {
      Tools.addClass(li, "active");
    }
    li.innerHTML = i + 1;
    oFrag.appendChild(li);
  }
  oOl[0].appendChild(oFrag);
//  克隆第一张放在最后边
  var firsClone = ulLis[0].cloneNode(true);
  inner[0].appendChild(firsClone);
  //重新计算一下ul的宽度
  var cUlLis = Tools.getElem("li", inner[0]);
  var liWidth = Tools.getWH(cUlLis[0]);
  var ulWidth = (liWidth.width) * (cUlLis.length);
  inner[0].style.width = ulWidth + "px";
  //自动播放
  timer = setInterval(playNext, 1000);
  //实现鼠标划过小方块显示颜色
  var oOlis = Tools.getElem("li", oOl[0]);
  for (var i = 0; i < oOlis.length; i++) {
    oOlis[i].index = i;
    oOlis[i].onmouseover = function () {
      for (var i = 0; i < oOlis.length; i++) {
        oOlis[i].className = "";
      }
      oOlis[this.index].className = "active";
      var target = -this.index * WrapWidth;
      Tools.setPosition(inner[0], target, 10);
      num = this.index;
      square = this.index;
    }
  }
// 对左右箭头进行监听
  oLeft[0].addEventListener("click", function () {
    playPre();
  });
  oRight[0].addEventListener("click", function () {
    playNext();
  });
  //单击小方块对对应相应图片,同时小方块的索引也要同步
  for (var i = 0; i < oOlis.length; i++) {
    oOlis[i].index = i;
    oOlis[i].onclick = function () {
      for (var i = 0; i < oOlis.length; i++) {
        oOlis[i].className = "";
      }
      target = -this.index * WrapWidth;
      Tools.setPosition(inner[0], target, 10);
      this.className = "active";
      num = this.index;
    }
  }
  outter[0].onmouseover = function () {
    clearInterval(timer);
    arrow[0].style.display = "block";
  };
  outter[0].onmouseout = function () {
    arrow[0].style.display = "none";
    timer = setInterval(playNext, 1000);
  };
//  封装向右点击事件
  function playNext() {
    if (num === cUlLis.length - 1) {
      num = 0;
      inner[0].style.left = 0;
    }
    num++;
    target = -num * WrapWidth;
    Tools.setPosition(inner[0], target, 10);
    if (square < oOlis.length - 1) {
      square++;
    } else {
      square = 0;
    }
    for (var i = 0; i < oOlis.length; i++) {
      oOlis[i].className = "";
    }
    oOlis[square].className = "active";
  }

  function playPre() {
    if (num === 0) {
      num = cUlLis.length - 1;
      target = -num * WrapWidth + "px";
      inner[0].style.left = target;
    }
    num--;
    target = -num * WrapWidth;
    Tools.setPosition(inner[0], target, 10);
    if (square > 0) {
      square--;
    } else {
      square = oOlis.length - 1;
    }
    for (var i = 0; i < oOlis.length; i++) {
      oOlis[i].className = "";
    }
    oOlis[square].className = "active";
  }
})();

第二个,封装了ajax

(function () {
  var cityData;
  var select = Tools.getElem("select");
  console.log(select);
  Tools.ajax({
    url: "city.php",
    type: "get",
    success: function (data) {
      // console.log(data)  ;
      data = JSON.parse(data);
      // console.log(data);
      var str = template("tpl", data);
      // console.log(str);
      cityData = data;
      var province = Tools.getElem("#province");
      province.innerHTML = str;
    }
  });
  select[0].addEventListener("change", function () {
    select[1].innerHTML = '<option value="">请选择市区</option>';
    select[2].innerHTML = '<option value="">请选择区域</option>';
    var pro = this.value;
    for (var i = 0; i < cityData.provinces.length; i++) {
      // console.log(1);
      if (pro === cityData.provinces[i].provinceName) {
        var citys = {
          city: cityData.provinces[i].citys
        };
        var str = template("tpl2", citys);
        // console.log(str);
        select[1].innerHTML = str;
      }
    }
  });
//  由于json文件没有县所以没法实现
//  原理与选择省分之后如何渲染出市是一样的,当select[1]发生了change事件,对数据进行判断,选出该市下面的县
})();

相关文章

网友评论

    本文标题:自己昨晚封装的工具函数

    本文链接:https://www.haomeiwen.com/subject/bbcudxtx.html