关于jslib

在前端框架大发展前,jQuery库是最流行的js库,最强大的功能就是dom操作.还提供好多工具函数,不必使用复杂的原生js,使用jQuery简单多了.

随着浏览器的进化,jQuery逐渐丢掉历史包袱,目前最新3.5版本不会再支持旧是浏览器,尤其是很老的IE.

新浏览器支持的js函数可以比较方便的操作dom,这种方便和jQuery的便利相差无几了.前端框架使用绑定数据到dom的数据驱动模式,不再使用dom选择器.

这两个情况让jQuery的使用热度降低了,不过jQuery的设计是非常值得学习的.做这个jslib库是为了学习jQuery.

将模仿jQuery做一个dom操作的库,api名字和操作方式都与jQuery一样,但是没有实现所有的api.

jslib实质上,外形是jQuery,内部实现用的新的js函数.例如:document.querySelectorAll()

全局对象

内部对象jslib,是一个类数组对象.也是模仿jQuery的,里面包含dom引用和操作方法.有length属性,表示回当前选中的dom个数.


    // 类数组对象,存放选择器选中的dom元素,还有操作方法,模仿jQuery对象
    function jslib(selector){}

    // 工厂函数,实例化这个对象.
    function factory(selector){
        return new jslib(selector);
    }

    // 引用对象 模仿jQuery使用 "$".外部调用这个函数使用jslib对象.
    window.jslib = factory
    if(!window.$)
        window.$ = factory

jslib对象实例方法

    // 向jslib类数组添加元素
    $().push(dom)

    // jslib类数组中是否已有指定元素
    $().contains(dom);

    // 重置jslib类数组内容.如果传入elemlist,则添加到jslib类数组
    // elemlist用于填充的新DOM元素列表,如果其中元素已经在jslib类数组中,则不会重复添加
    $().reset(elemlist)

    // 遍历jslib类数组元素.
    $().each(fn)

获取dom对象

    // 从匹配的dom元素中获取dom对象,使用索引
    // 取出第二个div
    let div = $('div')[1]


扩展jslib对象实例方法

    // 为jslib对象添加实例方法 prototype上的方法.
    // json 一个方法名和函数值的json对像.方法名要用""号包起来.
    $.extend(json)


dom选择

$(selector),支持字符串和dom对象


    // 1.字符串css选择器,里面实现是 document.querySelectorAll() 方法,支持css选择器
    $('#id') , $('.class') , $('div') , $('.class .xx') , ...

    // 2.带尖括号的字符串,生成新dom元素
    $('<div>')

    // 3.dom对象,或者dom对象数组
    let div = document.createElement('div')
    $(div)
    let divarr = [];
    divarr.push(div1);divarr.push(div2);
    $(divarr)
  

find(selector)

以已经匹配的元素为根,查找子元素.(内部使用 dom.querySelectorAll())

    <div id="id1"><span class="ss"></span><p>aa</p></div>
    // 匹配 span
    $('#id1').find('.ss')

eq(index)

筛选取匹配元素的第n个元素


    <div><span>1</span><span>2</span></div>
    // 匹配 span1
    $('span').eq(0)

index()

返回第一个匹配元素在父元素中的索引

    <div><p></p><span>1</span><span>2</span></div>
    // 返回 1
    $('span').index()

siblings(selector)

查找所有匹配元素的同级元素,不包含匹配元素自己. selector: 可以筛选


    <div><p></p><span>1</span><span>2</span></div>
    // 匹配 p
    $('span').siblings()

nextAll(selector)

查找所有匹配元素之后所有的同辈元素


    <div><p></p><span>1</span><span>2</span><label></label></div>
    // 匹配 span1 span2 label
    $('p').nextAll()

prevAll(selector)

查找所有匹配元素之后所有的同辈元素

    <div><p></p><span>1</span><span>2</span><label></label></div>
    // 匹配 span2 span1 p
    $('label').prevAll()

parent(selector)

返回每个匹配元素的一个父元素或者祖先元素.不传参数时,返回父元素

    <div><p></p><span>1</span><span>2</span><label></label></div>
    // 匹配 div
    $('label').parent()

prop(key, val)

设置每个匹配元素的属性或返回第一个元素的属性值.

    <div><p p1="aa"></p><span>1</span></div>
    // 返回 aa
    $('p').prop('p1')
    // p1修改为 bb
    $('p').prop('p1','bb')

val(val)

设置每个匹配元素的value属性或返回第一个元素的value属性值.主要用于input,textarea,select等表单元素

  <input type="text" value="mirror" />
  // 返回 mirror
  $('input').val()
  // 设置 value值
  $('input').val('space')

removeProp(...key)

删除每个匹配的元素指定的属性.属性名一个或者多个.

    <span p1="aa" p2="bb" title="cc"></span>
    // 删除属性 p1 p2
    $('span').removeProp("p1","p2");

addClass(...val)

为每个匹配的元素添加指定的类名

    <span p1="aa" p2="bb" title="cc"></span>
    // 为span添加 primary btn 样式类
    $('span').addClass("primary","btn");

removeClass(...val)

从所有匹配的元素中删除全部或者指定的类

    <span class="primary btn cc" p2="dd"></span>
    // 删除样式primary btn
    $('span').removeClass("primary","btn");

hasClass(val)

检查第一个匹配的元素是否含有指定的类

    <span class="primary btn cc" p2="dd"></span>
    // 返回 true
    $('span').hasClass("primary");

text(val)

设置所有匹配的元素的innerText.无参数时,返回第一个元素的innerText内容

    <span class="primary btn cc" p2="dd"></span>
    // 设置文本mirror space
    $('span').text("mirror space");

html(val)

设置所有匹配的元素的innerHTML属性.如果html中,含有script时,会重新生成script标签再加入文档中.

如果有外联的script,会ajax下载变成内联的.如此操作,当html加入到文档时,其中包含的script脚本会执行.

    <div></div>
    let html='<p></p>'
    // 给div设置html文本标签
    $('div').html(html)

append(content)

向每个匹配元素内部追加内容.content是一个dom对象,或者DocumentFragment对象,或者html字符串

    <div><span>1</span></div>
    let p=document.createElement('p');
    // 给div里追加p元素,在span1后面
    $('<div>').append(p)

    // 多个内容可以多次调用append
    $('<div>').append(p).append(p1);

prepend(content)

向每个匹配元素内部第一子节点前面加入内容.

    <div><span>1</span></div>
    let p=document.createElement('p');
    // 给div里前面插入p元素,在span1前面
    $('div').prepend(p)

before(content)

向每个匹配元素的前面加元素

    <div><span>1</span></div>
    let p=document.createElement('p');
    // 在span前面插入p元素
    $('span').before(p)

after(content)

向每个匹配元素的后面加元素

    <div><span>1</span></div>
    let p=document.createElement('p');
    // 在span后面插入p元素
    $('span').after(p)

remove()

删除所有匹配的元素.被删除的元素要有个父元素.

    <div><span>1</span></div>
    // 删除span
    $('span').remove()

empty()

清空所有匹配的元素的全部子元素

    <div><span>1</span></div>
    // 删除div的所有子元素
    $('div').empty()

fragment(...content)

建立一个DocumentFragment文档片段对象,将传入的node或DocumentFragment对象添加到其中.

$ 的静态方法, 这个就是调用document.createDocumentFragment()方法.

    // 参数是node节点 或者 DocumentFragment对象,返回 DocumentFragment实例
    $.fragment(...content)

$('#id').load(url,callback)

从url加载html,然后设置到所有匹配元素的innerHTML.

$ 的实例方法,类似于jquery.load()的功能.这里是使用XMLHttpRequest对象的get方法实现.不能跨域.

如果返回失败了,丢出异常.如果成功:xhr.readyState === 4 && xhr.status === 200 则设置返回的html到容器元素里.

这个主要用于,ajax请求html片段页面.不使用fetch的原因是,为了兼容打包APP.使用xhr时,可以从包本地取得html片段.

    // 参数是url地址
    $('#div1').load('test.html');
    // 也支持js,扩展名js
    $('#div1').load('testjs.js');

也可以加载js,为了实现动态加载js.用url扩展名判断,例如 xx.js是js文件,hh.html是html文件.

如果请求的是js,那么将js放到script标记中. 再放到this.html('<script>xhr.response)

callback方法在成功返回时执行

ajax

post

内部使用fetch()方法实现.包装处理了参数,方便使用.


    $.post(url, para, initCfg = null, resType = 'json')

  • url : string 请求地址url
  • para : FormData|json|string json对象或FormData对象或者字符串,如果是json对象,会转化成FormData对象.para会设置到initCfg.body属性.
  • initCfg : json fetch请求配置对象.例如传headers:{'Auth':'xxx'}用来验证
  • resType : string 返回值类型 默认"json",可选"html"
  • return : Promise 返回值类型,fetch().then()返回的Promise对象

post请求,.then()链式调用方式.方法发送fetch请求后,调用then()处理,如果res.ok==ok,默认返回json结果.

当res.ok为false时,丢出异常,异常信息是res.text()的文本信息.

后面需要继续调用.then()来处理结果,也可以调用.catch()处理异常

外部调用后可以继续使用then(),catch().

  let para = { p1:'',p2:'' };
  $.post('http://url', para)
    // 这个data值: resType != 'json' ? res.text() : res.json();
    .then((data) => {
      console.log(data);
    })
    .catch((err) => {
      console.log('服务器异常')
    })


get


    $.get(url, para, initCfg = null, resType = 'html')

  • url : string 请求地址url
  • para : FormData|json|string json对象或FormData对象或者字符串,会转化为url参数加到URL地址上
  • initCfg : json fetch请求配置对象.例如传headers:{'Auth':'xxx'}用来验证
  • resType : string 返回值类型 默认"json",可选"html"
  • return : Promise 返回值类型,fetch().then()返回的Promise对象

get请求,.then()链式调用方式.方法发送fetch请求后,调用then()处理,如果res.ok==ok,默认返回text结果.

当res.ok为false时,丢出异常,异常信息是res.text()的文本信息.

后面需要继续调用.then()来处理结果,也可以调用.catch()处理异常


  let para = { p1:'a',p2:'b' },para1="id=5"
  // para会转化为 p1=a&p2=b,然后加到url上,如果已有参数,会加到最后. http://url?p1=a&p2=b&id=5
  $.get('http://url', para)
    // 这个html默认服务器返回的是html字符串
    .then((html) => {
      console.log(html);
    })
    .catch((err) => {
      console.log('服务器异常')
    })

await方式

使用await的语法,可读性更好.是同步代码的习惯,远离繁琐的回调函数.

postAsync


  $.postAsync(url, para, initCfg = null, resType = 'json')

post请求,使用await方式.当res.ok==true时,默认返回json结果.

当res.ok为false时,丢出异常,异常信息是res.text()的文本信息.要获取异常,可以在try catch中使用本方法


    try {
      let para = { p1:'',p2:'' };
      let json = await $.postAsync('http://url',para);
      console.log(json);
    } catch (err) {
      console.log(err);
    }

getAsync


  $.getAsync(url, para, initCfg = null, resType = 'html')

get请求,使用await方式.当res.ok==true时,默认返回text结果.

当res.ok为false时,丢出异常,异常信息是res.text()的文本信息.要获取异常,可以在try catch中使用本方法


    try {
      let html = await $.postAsync('http://url');
      console.log(html);
    } catch (err) {
      console.log(err);
    }
    

fetch请求配置

initCfg参数用于配置fetch请求,就是fetch()的第2个参数. [fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象]

para参数,将会设置到fetch()第2个参数里的 body 属性的值.para参数最后会转为FormData对象.

如果要将参数放到body,para的参数必须是字符串.或者不设置para,直接设置body属性.


    // fetch常用请求配置
    fetch(url,{
      method: 'POST',// GET, POST
      headers: {
                  'Auth':'',
                  'Content-Type': 'application/json'
                  // 'Content-Type': 'application/x-www-form-urlencoded',
               },
      body: new FormData()
    })

array

date

日期时间格式化便利方法

$.datefmt(date, fmtstr)

格式化时间

dateDate ,要格式化的Date对象

fmtstrstring ,format string 格式化字符串 (默认:四位年份,24小时制: "yyyy/MM/dd HH:mm:ss")

自定义格式时,年月日时分秒代号必须是: y(年)M(月)d(日)H(时)m(分)s(秒)

返回string ,返回格式化时间字符串

    let d = new Date(2000,0,1,1,1,1);
    let dStr = $.datefmt(d);
    console.log(dStr);
    // 2000/01/01 01:01:01

    let fmtstr = 'yyyy年MM月dd日 HH时mm分ss秒';
    dStr = $.datefmt(d, fmtstr);
    console.log(dStr);
    // 2000年01月01日 01时01分01秒


$.dateByfmt(fmtstr)

将时间字符串转换为Date对象.

fmtstrDate ,时间格式的字符串

支持格式: yyyy/mm/dd yyyy-mm-dd yyyy/mm/dd hh:mm:ss 时分秒可省略自动补0,年月日必须.年份4位月日时分秒支持1位.

返回Date|null ,成功时返回Date对象,失败返回null

    let dStr = '2000/1/1';
    let d = $.dateByfmt(dStr, dStr);
    console.log(d.getFullYear());
    // 2000

formcheck

验证表单元素的值.支持 input,textarea

$.formCheck(elem)

提交表单前,验证值的有效性.返回 true / false

需要设置表单元素的vtype属性,一个或者多个,用逗号隔开.verrmsg是自定义提示语,和vtype对应,可以不设置.

如果验证不通过,那么表单上会变色提示.


    <input class="input-text" name="title" type="text" value="" placeholder="请输入名字" vtype="notnull" verrmsg="必填项">
    let isCheck = $.formCheck(input);
    // true / false


一般情况下只需要使用$.formCheck(elem)即可.后面两个方法也可以手动操作.

$.formClear(elem)

清除表单元素的错误样式和提示语.

清除$.formAlert()产生的表单错误提示.


$.formAlert(elem,msg)

触发错误提示

生成表单元素验证出错时的错误样式和提示语: 背景变红,在其正下方生成span,显示提示语


vtype选项

notnull必要项且不能为空或空白字符

email电子邮件格式

mobile指示一个字符串是否为国内11位手机号

abc限26个英文,大小写不限.

123限0-9数字

abc123限26个英文字母(开头)和0-9整数(可选)

abc_123限26个英文字母和0-9整数(可选)和_下划线(可选),并且是字母或者下划线开头.

url限url

ipv4限ipv4

date是否为可以转换为Date对象的日期字符串,例如: "1999-02-28 12:08:33"

maxlen是否超长度限制.

需要在表单元素上设置属性 maxlength

minlen是否小于长度

需要在表单元素上设置属性 minlength

maxnum是否大于数值限制.

需要在表单元素上设置属性 maxnum

minnum是否小于数值限制

需要在表单元素上设置属性 minnum

money正整数或正1-3位小数

valid

验证相关方法

$.isNotNull(str)

指示一个字符串是否含有内容,并且不能全部是空白字符


$.isNumber(str)

指示一个字符串是否为数值


$.isEmail(str)

指示一个字符串是否为email地址


$.isMobile(str)

指示一个字符串是否为国内11位手机号

可匹配"(+86)013800138000",()号可以省略,+号可以省略,(+86)可以省略,11位手机号前的0可以省略;11位手机号第二位数可以是3~9中的任意一个


$.isAbc(str)

指示一个字符串是否为26个英文字母组成,大小写不限.


$.isDigit(str)

指示一个字符串是否为0-9整数组成


$.isAbcDigit(str)

指示一个字符串是否为26个英文字母和0-9整数(可选)组成,但必须是字母开头.


$.isAbcDigitUline(str)

指示一个字符串是否为26个英文字母和0-9整数(可选)和_下划线(可选)组成,并且是字母或者下划线开头.


/**

$.isUrl(str)

指示一个字符串是否为url


$.isIpv4(str)

指示一个字符串是否为ipv4


$.isMaxLength(str, maxlen)

指示一个字符串长度是否超过maxlength. maxlen 最大长度


$.isMinLength(str, minlen)

指示一个字符串长度是否小于minlength. minlen 最小长度


$.isMoney(str)

指示一个字符串是否为1~3位小数,或者正数 (d | d.dd | d.d | d.ddd),可用于金额


$.isDate(str)

指示一个字符串是否为日期格式


rand

$.nextInt(intMin, intMax)

生成一个非负随机整数

intMinnumber ,起始值(>0整数,含)

intMaxnumber ,intMax:结束值(大于起始值整数,不含)

返回number ,返回整数,范围在 [intMin ~ intMax)

    let randNum = $.nextInt(0,100);
    // 返回0,100间的数,不含100

string

字符串相关方法

$.isEmptyOrNull(str)

字符串是否为空或者null或者全是空白字符.

strstring ,被检查字符串

返回boolean ,true / false


$.isNullOrWhiteSpace(str)

字符串是否为空或者null或者全是空白字符.

strstring ,被检查字符串

返回boolean ,true / false


$.format(str, ...repstrs)

格式化字符串,将字符串中的占位符替换为给定字符串{d},返回替换后字符串.例:("my name is {0} from {1}",mirror,china)

strstring ,要格式化的字符串,包含占位符{d}

...anyrepstrs ,替换占位符的字符串数组

返回string ,返回替换后字符串

    let str = 'my name is {0} from {1}';
    let nstr=$.format(str,'mirror','china');
    console.log(nstr);
    // my name is mirror from china


$.dataBind(str, json)

格式化字符串,根据占位符${key},到json中找到json.key,然后替换掉${key}

没找到的'${key}'时, ${key}替换为''(空值)

strstring ,要格式化的字符串,包含占位符${key}

jsonany ,json对象,键为key

返回string ,返回替换后字符串

    let json={name:'mirror',from:'china'};
    let str='my name is ${name} from ${from}';
    let nstr=$.dataBind(str,json);
    console.log(nstr);
    // my name is mirror from china


$.trim(str)

去除字符串前后的空白字符

strstring ,字符串

返回string ,返回新字符串

dom string

生成dom元素字符串,主要用于拼接html字符串的情况,直接拼接有点啰嗦.

$.dom

$.dom是个对象,每个属性的名字是dom的名字,例如div,span,p.值是一个函数,返回这个dom的html字符串

$.dom.div('innerText','class',attrjson)

innerTextstring ,html标记中的文本

classstring ,样式字符串.如果不需要样式参数但有属性参数,可以省略.

attrjsonjson ,属性名值对

支持的标记有: 'div', 'span', 'a', 'p', 'table', 'tr', 'th', 'td', 'select', 'option', 'ul', 'li', 'dt', 'dd', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'

    // 生成一个段落
    $.dom.p('一个段落','article-title primary',{id:'myname'});
    // <p class="article-title primary" id="myname">一个段落</p>

重复生成标记,在文本前加 :for,文本用 | 竖线隔开

    // 生成一个列表
    let li = $.dom.li,ul = $.dom.ul;
    ul(li(':for第一列|第二列|第三列'), 'list square', { id: 'mylist' });
    // <ul class="list square" id="mylist"><li>第一列</li><li>第二列</li><li>第三列</li></ul>

    // 省略样式参数
    ul(li('单列'),{id:'myul'});