轮播图

468 阅读2分钟

随手记 轮播图

原生js实现简单的轮播

  1. 获取数据 自己封装ajax

  /**
   * 定义ajax
   */
  function _ajax(options) {
    // body...
    try {
      // statements
      options = options || {};
      return new Promise((resolve, reject) => {
        let xhr;
        let promise;
        if (window.XMLHttpRequest) {
          xhr = new XMLHttpRequest();
        } else {
          xhr = new ActiveXObject('Microsoft.XMLHTTP');
        }
        if (options.type.toLowerCase() === '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.toLowerCase() === 'post') {
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        }
        xhr.send(options.data);
        xhr.onreadystatechange = function () {
          if (xhr.readyState === 4) {
            if (xhr.status === 200 || xhr.status === 304) {
              let data = JSON.parse(xhr.responseText);
              resolve.call(undefined, data);
            } else {
              reject.call(undefined, xhr.status);
            }
          }
        }
      })
    } catch (e) {
      // statements
      console.log(e);
    }

  }

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

获取数据

 function getCarouselData(data = {}) {
   return _ajax({
     url: '',
     type: 'get',
     data: {accessToken: ''}
   })
 }
  1. 根据返回数据创建轮播dom元素
  //创建轮播图模块
  function createCarousel(arr, target, className, callback) {
    try {
      let carouselDiv = document.createElement('div');
      carouselDiv.className = className;
      let ul = document.createElement('ul');
      ul.className = 'ul';
      let fragment = document.createDocumentFragment();
      for (let i = 0; i < arr.length; i++) {
        let li = document.createElement('li');
        let a = document.createElement('a');
        let img = document.createElement('img');
        img.src = arr[i].mainImg;
        a.href = `http://${window.location.host}?accessToken=${getQueryString('accessToken')}&articleId=${arr[i].relId}`;
        a.appendChild(img);
        li.appendChild(a);
        fragment.appendChild(li)
      }
      fragment.appendChild(fragment.children[0].cloneNode(true));
      fragment.insertBefore(fragment.children[arr.length - 1].cloneNode(true), fragment.firstChild);
      ul.appendChild(fragment);
      carouselDiv.appendChild(ul);

      target.appendChild(carouselDiv);
      callback();
    } catch (e) {
      console.log(e);
    }

  }


在这里不清楚返回数据量的大小,所以使用fragment,防止数据量过大影响创建的性能。

  1. 创建动画函数
  //轮播动画实现
  /**
   *
   * @type {string}
   */
  //封装 能够让 任意对象 的指定属性 变到指定值 的动画函数
  function animate(obj, json, fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
      let flag = true;
      let leader;
      let target;
      for (let k in json) {
        leader = 0;
        if (k === "opacity") {//特殊处理
          //var leader = parseInt(getStyle(obj, k)) || 0;
          leader = getStyle(obj, k) * 100;//1
          // 0 || 1 结果是1 那么如果透明度当前的值是0 就会变成1
          //所以这里不能给默认值 而且也没有必要
          //透明度没有单位px 所以也不用parseInt 参与运算自动变为数字
          target = json[k] * 100;//0.5
          let 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 {
          leader = parseInt(getStyle(obj, k)) || 0;
          target = json[k];
          let step = (target - leader) / 10;
          step = step > 0 ? Math.ceil(step) : Math.floor(step);
          leader = leader + step;
          obj.style[k] = leader + "px";
          if (step !== 0) {
            flag = false;
          }
        }
        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];
    }
  }
  1. 调用动画函数
  function autoPLay(len, target, width,obj,index,num) {
    obj.timer = setInterval(() => {
      index++;
      num++;
      if (index >= len) {
        target.style.left = -width + 'px';
        index = 2;
      }
      animate(target, {left: -width * index}, () => {
      });
    }, 1000)
  }