day24-Ajax的封装

这篇博客详细介绍了如何封装一个Ajax函数,包括参数校验、错误处理和请求发送。同时,还展示了分页组件的实现,包括动态生成页码、事件监听和状态更新。通过对这两个组件的理解和使用,可以提升前端项目的交互体验和数据加载效率。
摘要由CSDN通过智能技术生成

Ajax的封装

/*
  参数:
    【1】请求的地址
    【2】请求方式(get||post)
    【3】回调函数(用于获取异步代码执行的结果),成功,失败
    【4】请求携带的参数
    【5】设置同步或者异步
  当函数的参数过多的时候,应该把参数写出一个对象传递
  {
     url:“请求的地址”, 请求的地址是必须的
     type:"get" ,选填,不填的时候默认为get请求
     data:{username:"aaa",password:"123456"},选填,有参数就传递,没有就不填,需要有默认值为""
     async:false 选填,值为布尔值,不填写为true
     success:function(){} ,必填,请求成功之后执行的函数 获取到请求的结果
     error:function(){} 选填,请求失败之后执行的函数
  }
*/
function ajax(obj){ 
   //判断必填的属性 是否有传递
   if(!obj.url){
       throw Error("url属性不能为空")
   }
   //判断success 是否有传递
   if(!obj.success){
      throw Error("success属性不能为空")
   }
   //当有一些参数没有传递的时候,需要添加默认值
   let option={
      url:obj.url,
      type:obj.type||"get",
      data:obj.data||"",
      async:obj.async||true,
      success:obj.success,
      error:obj.error||function(err){
          conlose.log(err);
      },
   };
   //判断一下 请求方式是否正确 post||get
   if(!option.type=="get"||option.type=="post"){
      throw Error("type的属性取值 暂时只支持get和post")
   }
   //判断data参数 是否为 对象或者是字符串
   let datatype=Object.prototype.toString.call(option.data);
   if(!(datatype == "[object Object]" || datatype == "[object String]")){
      throw Error("data参数的格式 暂时只支持对象或者字符串");
   }
   //判断async 是否为布尔值
   if (!(Object.prototype.toString.call(option.async) == "[object Boolean]")) {
        throw Error("async的取值只能为布尔值(true|| false)");
    }
   // 判断success 是否是函数
   if (!(Object.prototype.toString.call(option.success) == "[object Function]")) {
        throw Error("success 必须是一个函数");
    }
   // 判断error参数是否为函数
   if (!(Object.prototype.toString.call(option.error) == "[object Function]")) {
        throw Error("error 必须是一个函数");
    }
   //如果参数为对象的时候 需要把对象转化:{name:"老谢",age:18}==>name=老谢&age=18==>"key=value&key=value"
   if((Object.prototype.toString.call(option.data) == "[object Object]")){
      let str="";
      for(let key in option.data){
         str+=key+"="+option.data[key]+"&";
      }
      option.data=str.substr(0,str.length-1);
   }
  let xhr=new XMLHttpRequest();
  xhr.onreadystatechange=function(){
      //agax状态 
      if(xhr.readyState==4&&/^[23]\d{2}$/.test(xhr.status)){
         option.success(xhr.responseText)
      }
      //http状态码为4或者5开头的时候
      if(/^[45]\d{2}$/.test(xhr.status)){
         option.error(xhr.responseText)
      }
  };
  //判断请求方式
  if(option.type=="get"){
        xhr.open(option.type, `${option.url}?${option.data}`, option.async);
        xhr.send();

        return;
  ]
   xhr.open(option.type, option.url, option.async);
   xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
   xhr.send(option.data);
}
  • ajax.js的调用
            ajax({
                url: './ajax.php',
                type: "get",
                data: { name: "老谢", age: 48 },
                async: false,
                success: function (res) {
                    console.log(res);
                },
            });

pagination(分页封装)

在这里插入图片描述

  • pagination.html
<!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>
        <script src="./pagination.js"></script>
    </head>
    <body>
        <div class="box">
            
        </div>
        <script>
            let box = document.querySelector(".box");
            new Pagination(box, {
                pageInfo: {
                    pagenum: 1,
                    pagesize: 5,
                    total: 100,
                    totalpage: 20,
                },
                textInfo: {
                    first: "首页",
                    prev: "上一页",
                    next: "下一页",
                    last: "末页",
                },
                // 点击页码的时候会触发change函数
                change: function (index) {
                    console.log(index);
                    // 重新发起一个ajax请求
                },
            });
        </script>
    </body>
</html>

class Pagination {
  constructor(ele, options) {
    if (!ele) {
      throw new Error('方法必须传递参数,第一个为dom元素,第二个为对象');
    }
    this.ele = ele;

    // 把用户传递进来的信息保存一下
    this.options = options || {};

    // 准备一些分页信息
    this.default = {
      pageInfo: {
        pagenum: 1,
        pagesize: 10,
        total: 1000,
        totalpage: 100 // 页码总数
      },
      textInfo: {
        first: 'first',
        prev: 'prev',
        list: '',
        next: 'next',
        last: 'last'
      }
    };

    // 当页码发生改变的时候就执行这个函数
    this.change = this.options.change || function () {};

    // 提前准备一个变量,保存 list 里面的元素
    this.list = null;

    // 调用过的入口函数
    this.init();
  }
  init() {
    this.setDefault();
    this.setStyle();
    this.dongcidaci();
  }
  // 使用用户传递的信息替换我自己的信息
  setDefault() {
    if (this.options.pageInfo) {
      for (let attr in this.options.pageInfo) {
        this.default.pageInfo[attr] = this.options.pageInfo[attr];
      }
    }

    if (this.options.textInfo) {
      for (let attr in this.options.textInfo) {
        this.default.textInfo[attr] = this.options.textInfo[attr];
      }
    }
  }
  // 给大盒子设置样式
  setStyle() {
    this.ele.innerHTML = '';
    setCss(this.ele, {
      display: 'flex',
      justifyContent: 'center',
      alignItems: 'center'
    });

    // 设置完样式就添加元素
    this.createEle();
    // 添加列表
    this.creteList();
    // 添加文本框
    this.go();
    // 禁用的判断
    this.isDis();

    // 动过以后要执行函数(如果第一次渲染分页的时候也需要执行change函数的时候 那么就在这里this.change)
    // this.change(this.default.pageInfo.pagenum);
  }
  // 添加上一页下一页首页末页列表标签到 this.ele 里面
  createEle() {
    for (let attr in this.default.textInfo) {
      const div = document.createElement('div');
      div.className = attr;
      if (attr === 'list') {
        this.list = div;
        setCss(div, {
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center'
        });
      } else {
        setCss(div, {
          border: '1px solid #333',
          padding: '0 5px',
          margin: '0 5px'
        });
      }
      div.innerHTML = this.default.textInfo[attr];
      this.ele.appendChild(div);
    }
  }
  // 设置页码
  creteList() {
    const pagenum = this.default.pageInfo.pagenum;
    const totalpage = this.default.pageInfo.totalpage;

    if (totalpage <= 9) { // 小于九个直接渲染
      for (let i = 1; i <= this.default.pageInfo.totalpage; i++) {
        const p = this.crealeP(i);
        this.list.appendChild(p);
      }
    } else { // 大于九个分成几个步骤来渲染
      if (pagenum < 5) {
        // 1 2 3 4 5 ... 99 100
        for (let i = 1; i <= 5; i++) {
          this.list.appendChild(this.crealeP(i));
        }

        const span = document.createElement('span');
        span.innerHTML = '...';
        this.list.appendChild(span);

        for (let i = totalpage - 1; i <= totalpage; i++) {
          this.list.appendChild(this.crealeP(i));
        }
      } else if (pagenum === 5) {
        // 1 2 3 4 5 6 7 ... 99 100
        for (let i = 1; i <= 7; i++) {
          this.list.appendChild(this.crealeP(i));
        }

        const span = document.createElement('span');
        span.innerHTML = '...';
        this.list.appendChild(span);

        for (let i = totalpage - 1; i <= totalpage; i++) {
          this.list.appendChild(this.crealeP(i));
        }

      } else if (pagenum > 5 && pagenum < totalpage - 4) {
        for (let i = 1; i <= 2; i++) {
          this.list.appendChild(this.crealeP(i));
        }

        const span = document.createElement('span');
        span.innerHTML = '...';
        this.list.appendChild(span);

        for (let i = pagenum - 2; i <= pagenum + 2; i++) {
          this.list.appendChild(this.crealeP(i));
        }

        const span2 = document.createElement('span');
        span2.innerHTML = '...';
        this.list.appendChild(span2);

        for (let i = totalpage - 1; i <= totalpage; i++) {
          this.list.appendChild(this.crealeP(i));
        }
      } else if (pagenum === totalpage - 4) {
        for (let i = 1; i <= 2; i++) {
          this.list.appendChild(this.crealeP(i));
        }

        const span = document.createElement('span');
        span.innerHTML = '...';
        this.list.appendChild(span);

        for (let i = totalpage - 6; i <= totalpage; i++) {
          this.list.appendChild(this.crealeP(i));
        }

      } else if (pagenum > totalpage - 4) {
        for (let i = 1; i <= 2; i++) {
          this.list.appendChild(this.crealeP(i));
        }

        const span = document.createElement('span');
        span.innerHTML = '...';
        this.list.appendChild(span);

        for (let i = totalpage - 4; i <= totalpage; i++) {
          this.list.appendChild(this.crealeP(i));
        }
      }
    }
  }
  // 提取了一个专门用来创建 li 的函数
  crealeP(i) {
    // i 形参就是要拿到循环中的 i 我好渲染文字
    // 和当前页面进行比较
    const p = document.createElement('p');

    p.innerHTML = i;
    setCss(p, {
      border: '1px solid #333',
      margin: '0 5px',
      padding: '0 5px'
    });

    if (i === this.default.pageInfo.pagenum) {
      setCss(p, {
        backgroundColor: 'orange'
      });
    }

    return p;
  }
  // 设置文本款和按钮
  go() {
    const inp = document.createElement('input');
    const btn = document.createElement('button');
    setCss(inp, {
      outline: 'none',
      width: '50px',
      height: '20px'
    });
    inp.value = this.default.pageInfo.pagenum;
    inp.type = 'number';
    inp.setAttribute('min', '1');
    inp.setAttribute('max', this.default.pageInfo.totalpage);
    setCss(btn, {
      outline: 'none',
      width: '30px',
      height: '24px',
      marginLeft: '5px'
    });
    btn.innerHTML = 'go';
    this.ele.appendChild(inp);
    this.ele.appendChild(btn);
  }
  // 判断一下禁用
  isDis() {
    if (this.default.pageInfo.pagenum === 1) {
      this.ele.children[0].style.backgroundColor = '#ccc';
      this.ele.children[1].style.backgroundColor = '#ccc';
    }

    if (this.default.pageInfo.pagenum === this.default.pageInfo.totalpage) {
      this.ele.children[3].style.backgroundColor = '#ccc';
      this.ele.children[4].style.backgroundColor = '#ccc';
    }
  }
  // 动起来
  dongcidaci() {
    // 事件委托来做
    this.ele.addEventListener('click', e => {
      e = e || window.event;
      const target = e.target;

      if (target.className === 'first' && this.default.pageInfo.pagenum !== 1) {
        this.default.pageInfo.pagenum = 1;
        this.setStyle();
      }

      if (target.className === 'prev' && this.default.pageInfo.pagenum !== 1) {
        this.default.pageInfo.pagenum--;
        this.setStyle();
      }

      if (target.className === 'next' && this.default.pageInfo.pagenum !== this.default.pageInfo.totalpage) {
        this.default.pageInfo.pagenum++;
        this.setStyle();
      }

      if (target.className === 'last' && this.default.pageInfo.pagenum !== this.default.pageInfo.totalpage) {
        this.default.pageInfo.pagenum = this.default.pageInfo.totalpage;
        this.setStyle();
      }

      if (target.nodeName === 'P' && target.innerHTML - 0 !== this.default.pageInfo.pagenum) {
        this.default.pageInfo.pagenum = target.innerHTML - 0;
        this.setStyle();
      }

      if (target.nodeName === 'BUTTON' && target.previousElementSibling.value - 0 !== this.default.pageInfo.pagenum) {
        this.default.pageInfo.pagenum = target.previousElementSibling.value - 0;
        this.setStyle();
      }

      // 如果一开始渲染的时候 不需要执行change函数的时候 在这个位置调用this.change函数
      this.change(this.default.pageInfo.pagenum);
    });
  }
}










function setCss(ele, options) {
  for (let attr in options) {
    ele.style[attr] = options[attr]
  }
}```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值