在前端框架大发展前,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)
$(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)
以已经匹配的元素为根,查找子元素.(内部使用 dom.querySelectorAll())
<div id="id1"><span class="ss"></span><p>aa</p></div> // 匹配 span $('#id1').find('.ss')
筛选取匹配元素的第n个元素
<div><span>1</span><span>2</span></div> // 匹配 span1 $('span').eq(0)
返回第一个匹配元素在父元素中的索引
<div><p></p><span>1</span><span>2</span></div> // 返回 1 $('span').index()
查找所有匹配元素的同级元素,不包含匹配元素自己. selector: 可以筛选
<div><p></p><span>1</span><span>2</span></div> // 匹配 p $('span').siblings()
查找所有匹配元素的后面一个同辈元素,不指定筛选时返回紧邻的后一个元素
<div><p></p><span>1</span><span>2</span><label></label></div> // 匹配 span1 $('p').next() // 匹配 label $('p').next('label')
查找所有匹配元素之后所有的同辈元素
<div><p></p><span>1</span><span>2</span><label></label></div> // 匹配 span1 span2 label $('p').nextAll()
查找所有匹配元素的紧邻的前面那一个同辈元素
<div><p></p><span>1</span><span>2</span><label></label></div> // 匹配 span2 $('label').prev()
查找所有匹配元素之后所有的同辈元素
<div><p></p><span>1</span><span>2</span><label></label></div> // 匹配 span2 span1 p $('label').prevAll()
返回每个匹配元素的一个父元素或者祖先元素.不传参数时,返回父元素
<div><p></p><span>1</span><span>2</span><label></label></div> // 匹配 div $('label').parent()
设置每个匹配元素的属性或返回第一个元素的属性值.
<div><p p1="aa"></p><span>1</span></div> // 返回 aa $('p').prop('p1') // p1修改为 bb $('p').prop('p1','bb')
设置每个匹配元素的value属性或返回第一个元素的value属性值.主要用于input,textarea,select等表单元素
<input type="text" value="mirror" /> // 返回 mirror $('input').val() // 设置 value值 $('input').val('space')
删除每个匹配的元素指定的属性.属性名一个或者多个.
<span p1="aa" p2="bb" title="cc"></span> // 删除属性 p1 p2 $('span').removeProp("p1","p2");
为每个匹配的元素添加指定的类名
<span p1="aa" p2="bb" title="cc"></span> // 为span添加 primary btn 样式类 $('span').addClass("primary","btn");
从所有匹配的元素中删除全部或者指定的类
<span class="primary btn cc" p2="dd"></span> // 删除样式primary btn $('span').removeClass("primary","btn");
检查第一个匹配的元素是否含有指定的类
<span class="primary btn cc" p2="dd"></span> // 返回 true $('span').hasClass("primary");
设置所有匹配的元素的innerText.无参数时,返回第一个元素的innerText内容
<span class="primary btn cc" p2="dd"></span> // 设置文本mirror space $('span').text("mirror space");
设置所有匹配的元素的innerHTML属性.如果html中,含有script时,会重新生成script标签再加入文档中.
如果有外联的script,会ajax下载变成内联的.如此操作,当html加入到文档时,其中包含的script脚本会执行.
<div></div> let html='<p></p>' // 给div设置html文本标签 $('div').html(html)
向每个匹配元素内部追加内容.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);
向每个匹配元素内部第一子节点前面加入内容.
<div><span>1</span></div> let p=document.createElement('p'); // 给div里前面插入p元素,在span1前面 $('div').prepend(p)
向每个匹配元素的前面加元素
<div><span>1</span></div> let p=document.createElement('p'); // 在span前面插入p元素 $('span').before(p)
向每个匹配元素的后面加元素
<div><span>1</span></div> let p=document.createElement('p'); // 在span后面插入p元素 $('span').after(p)
删除所有匹配的元素.被删除的元素要有个父元素.
<div><span>1</span></div> // 删除span $('span').remove()
清空所有匹配的元素的全部子元素
<div><span>1</span></div> // 删除div的所有子元素 $('div').empty()
建立一个DocumentFragment文档片段对象,将传入的node或DocumentFragment对象添加到其中.
$ 的静态方法, 这个就是调用document.createDocumentFragment()方法.
// 参数是node节点 或者 DocumentFragment对象,返回 DocumentFragment实例 $.fragment(...content)
从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方法在成功返回时执行
post
内部使用fetch()方法实现.包装处理了参数,方便使用.
$.post(url, para, initCfg = null, resType = 'json')
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')
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() })
日期时间格式化便利方法
$.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
验证表单元素的值.支持 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位小数
验证相关方法
$.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)
指示一个字符串是否为日期格式
$.nextInt(intMin, intMax)
生成一个非负随机整数
intMinnumber ,起始值(>0整数,含)
intMaxnumber ,intMax:结束值(大于起始值整数,不含)
返回number ,返回整数,范围在 [intMin ~ intMax)
let randNum = $.nextInt(0,100); // 返回0,100间的数,不含100
字符串相关方法
$.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元素字符串,主要用于拼接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'});