自己昨晚封装的工具函数

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事件,对数据进行判断,选出该市下面的县
})();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 原文链接 http://blog.poetries.top/2016/10/20/review-jQuery 关注...
    程序员poetry阅读 16,582评论 18 503
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 我希望自己也是一顆星星:如果我會發光,就不必害怕黑暗。如果我自己是那麼美好,那麼一切恐懼就可以煙消雲散。於是我開始...
    你c哥阅读 111评论 0 0
  • 近日,上海一名男孩输液半分钟就哮喘、眩晕,甚至双眼黑矇,幸亏抢救及时,医生说这就是输液反应引起的!你知道吗?小病输...
    柚子SEM竞价托管阅读 436评论 0 0