# s94-web

> 常用的web工具方法封装---牧人与鱼

Latest version **2.1.0** (published 2024-05-07) · ISC license · 0 weekly downloads

## Install

```sh
npm install s94-web
pnpm add s94-web
yarn add s94-web
bun add s94-web
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.1.0 |
| Published | 2024-05-07 |
| First published | 2021-12-28 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 179.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | 牧人与鱼 |
| Maintainers | s94 |
| Keywords | s94 |

## Links

- npm: https://www.npmjs.com/package/s94-web
- npm.io page: https://npm.io/package/s94-web

## Dependencies (1)

- [s94-js](https://npm.io/package/s94-js.md) ^2.0.8

## Recent versions

- 2.1.0 (latest) — 2024-05-07
- 2.0.2 — 2024-04-15
- 2.0.1 — 2024-04-14
- 2.0.0 — 2024-04-14
- 1.2.0 — 2024-04-12
- 1.1.99 — 2024-02-24
- 1.1.98 — 2024-02-23
- 1.1.97 — 2024-02-23
- 1.1.96 — 2024-02-22
- 1.1.95 — 2024-01-04
- 1.1.94 — 2024-01-03
- 1.1.93 — 2023-12-27
- 1.1.92 — 2023-12-25
- 1.1.91 — 2023-12-24
- 1.1.90 — 2023-12-24
- … 107 more at https://npm.io/package/s94-web/versions

## README

# **s94-web**
> 浏览器中常用工具库，类似jQuery，依赖了s94-js库

## **安装**
```
$ npm install s94-web
```
## **使用**
直接引入js方式
>注1：s94-web中包含了s94-require模块，所以尽量保持s94-web模块在模块目录厘米。详情参考[s94-require模块](https://www.npmjs.com/package/s94-require)

>注2：如果是“直接引入js方式”，也可以使用$代替s94
```html
<script src="/node_modules/s94-web/s94.js" type="text/javascript" charset="utf-8"></script>
<!--调试模式-->
<script src="/node_modules/s94-web/s94.js?debug" type="text/javascript" charset="utf-8"></script>
```
require引入方式
```js
var s94 = require('s94-web');
```

# **属性和方法**

[s94(selector)](#s94) 基本方法

[s94.__stack([index])](#__stack) 获取js执行堆栈

[s94.filename](#filename) 文件的url地址

[s94.dir](#dir) 文件所在目录的url地址

[s94.dirname(path)](#dirname) 计算path的上级目录地址

[s94.debug](#debug) 是否开启debug

[s94.load(f)](#load) DOM结构加载完成后执行回调函数f

[new s94.Ready(f)](#Ready) 函数队列对象

[s94.extend(obj, data[, options])](#extend) 对象扩展

[s94.type(obj)](#type) 返回obj参数的数据类型

[s94.each(obj, callback[, thisArg])](#each) 遍历obj对象（for in的语法糖）

[s94.eachloop(obj, childkey, callback[, thisArg])](#eachloop) 递归遍历obj对象

[s94.eachlimit(obj, op)](#eachlimit) 限制遍历obj对象

[s94.merge(obj1[, obj2 ,...])](#merge) 合并多个对象，支持合并数组和对象

[s94.sort(arr, ace)](#sort) 使用自定义的规则对数组进行排序

[s94.trim(str[, mask])](#trim) 去除字符串首尾的空格，传入mask参数可以额外去除对应字符

[s94.reparam(str)](#reparam) 把urlparam类型字符串转化成对象

[s94.param(obj)](#param) 把对象转化成urlparam类型字符串

[s94.url(str[, base])](#url) new URL()的低版本兼容

[s94.encode(data)](#encode) 把data编码成36位字符串(包含小写英文、数字)

[new s94.Cache(engine)](#new_cache) 示例化缓存对象

[s94.cache(name[, value, timeout])](#cache) 缓存数据或者提取缓存的数据

[s94.cache.clean([name])](#cache.clean) 清理缓存数据

[s94.ajax(setup)](#ajax) XMLHttpRequest同步异步请求

[s94.loadJs(setup[, callback])](#loadJs) 异步加载js文件，加载完成执行回调

[s94.screenOffsetPage([to, op, callback])](#screenOffsetPage) 屏幕相对于页面的偏移，或者滚动到指定位置

[s94.domOffsetPage(dom)](#domOffsetPage) 元素相对于页面的偏移

[s94.domOffsetParent(dom[, parent])](#domOffsetParent) 元素doc相对于父级元素parent的偏移

[s94.eventOffsetScreen(e)](#eventOffsetScreen) 获取事件触发定位，相对于屏幕

[s94.eventOffsetTarget(e)](#eventOffsetTarget) 获取事件触发定位，相对于触发DOM节点

[s94.eventOffsetDom(dom, e)](#eventOffsetDom) 获取事件触发定位，相对于DOM节点

[s94.date(fmt[, time])](#date) 格式化时间日期

[s94.strtodate(str, fmt)](#strtodate) 字符转Date对象

[s94.autoRequire(data)](#autoRequire) 自动加载模块注册

[s94.lazy(doms)](#lazy) 懒加载

[s94.log(obj[, note, depth])](#log) 打印日志

[s94.msg(data)](#msg) 消息模块

[s94.pjax(data)](#pjax) 无刷新跳转pjax模块

[s94.rem](#rem) rem系统

[s94.Scroll](#Scroll) 滚动事件模块

[s94.Touch](#Touch) 触摸事件模块


<p id="s94"></p>

## **s94(selector)** 
- selector `Function|String` 传入的参数，不同参数，处理方法不同
	- 传入`Function`：如果传入Function规定了传参，等同于`new s94.Ready(f)`。否则等同于`s94.load(f)`
	- 传入`String`：返回`s94.fn`对象。如果字符串包含“<”符号，当做HTML代码处理；否则当作选择器处理
- 返回 `s94.fn`对象或者`s94.Ready`对象
>基本方法
```js
//返回s94.fn对象
var $p1 = s94('p');
var $p2 = s94('<p>123</p>');

//等同于s94.load(f)
s94(function(){
	alert('加载完了');
})

//等同于new s94.Ready(f)
var ready = s94(function(next){
	setTimeout(function(){
		next()
	},1000)
})
```

<p id="__stack"></p>

## **s94.__stack([index])** 
- index `Number` 序号，不传返回所有。0：s94.__stack所在位置；1：执行“s94.__stack方法”的闭包所在位置；2：执行“执行了s94.__stack方法”的闭包所在位置；3：依此类推
- 返回 `Object|Array` 包含了执行流程中的文件url、行号、列号的Object或者包含所有Object的Array
>获取js执行堆栈，包含了执行流程中的文件url、行号、列号
```js
//获取当前js代码执行所在的url地址
alert(s94.__stack(1)['file']);

//创建一个方法，执行方法的时候，获取执行时所在的url地址
function this_file(){
	return s94.__stack(2)['file'];
}
```

<p id="dirname"></p>

## **s94.dirname(path)** 
- path `String` 路径，最好位http(s)协议
- 返回 `String` 上级目录地址
>计算path的上级目录地址
```js
var dir = s94.dirname('http://127.0.0.1/debug/index.html'); //http://127.0.0.1/debug
```

<p id="debug"></p>

## **s94.debug** 
- 返回 `Boolean` DEBUG状态
>获取或者设置DEBUG状态，DEBUG状态下，会进行错误监听。并把错误信息打印出了
```js
s94.debug = true;
''.join(); //此处报错，会打印错误信息
```

<p id="load"></p>

## **s94.load(f)** 
- f `Function` 执行的回调函数
- 返回 `Underfind` 
>DOM结构加载完成后执行回调函数f
```js
s94.load(function(){
	//TODO....	
})
//简便写法
$(function(){
	//TODO....	
})
```

<p id="Ready"></p>

## **new s94.Ready(f)** 
- f `Function` 队列执行的回调函数，方法接收两个参数(next, data)
	- next `Function` 表示队列中的下一个方法，用于在需要的地方和时候异步执行。或者f方法直接return非underfind数据也可以等同于执行next(如果f中没有执行next的，同时return的是underfind。表示终止流程，意味着，队列中后面的方法不再会执行。)
	- data `Object` 表示上一个方法传递过来的数据，可能是上一个f中`next([data])`执行的传参，也可能是上一个f中return的非underfind数据
- 返回 `s94.Ready` 对象
>创建函数队列对象，`s94.Ready`的原型方法`then`可以用于插入下一个需要执行的方法

>`s94.Ready`和`Promise`类似，但是在处理大量异步执行队列的时候，`s94.Ready`更加简洁。`Promise`有两个状态指示，主要异步优化，可以直接获取异步操作句柄，方便调用异步返回结果。而`s94.Ready`的只有一个用来表示执行下一个方法，具体的判断和是否终止执行队列，需要用户自己在回到函数里面判断，主要用于队列执行的流程，例如动画等需要按步骤进行的异步操作
```js
var ready = new s94.Ready(function(next){
	//TODO....	
})
//简便写法
var ready = $(function(next){
	//TODO....	
})
//解和then的用法
var r = $(function(next, data){
	console.log('选择食物中。。。');
	setTimeout(function () {
		console.log('下好订单了，顶单号:1');
		next(1);
	},1000)
}).then(function(next, data){
	console.log('收到订单，顶单号:'+data+'。开始制作');
		setTimeout(function () {
			console.log('制作完成，开始准备派送，排送员:XXX');
			next('XXX');next('XX2X');
		},1000)
}).then(function(next, data){
	console.log('排送员:'+data+'接到商品，开始派送');
		setTimeout(function(){
			console.log('商品送达，接收人没在，放在了存放点，取件码：123');
			next('123');
		},1000)
})
setTimeout(function(){
	r.then(function(next, data){
		console.log('想起来要去取件，查看取件码：'+data)
	})
},5000)
```

<p id="extend"></p>

## **s94.extend(obj, data[, options])** 
- obj `Object` 需要扩展的对象
- data `Object` {key: value}，包含扩展的键、值
- options `Object` 属性描述符，具体参考[Object.defineProperty()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) ,只能规定数据描述符的configurable、enumerable、writable这三个参数
- 返回 `Underfind` 
>对obj对象进行扩展
```js
var Obj = function(name, age){
	this.name = name || '未知';
	this.age = age || 0;
}
//普通的对象扩展不够精细，扩展的属性或方法是否可修改，是否枚举这些都无法控制
Obj.prototype.myname = function(){
	console.log(this.name);
}
//使用Object.defineProperty()做精细的扩展，使myname方法不能修改，不能删除，但是可以枚举
Object.defineProperty(Obj.prototype, 'myname', {
	value: function(){
		console.log(this.name);
	},
	enumerable: true,
})
//s94.extend是Object.defineProperty()方法的简化，并且方便批量扩展多个属性或者方法
s94.extend(Obj.prototype, {
	myname: function(){
		console.log(this.name);
	},
	myage: function(){
		console.log(this.age);
	},
},{enumerable: true});
```

## **s94.fn.prototype.extend(data[, options])** 
>对s94.fn.prototype对象进行扩展的版本
```js
	s94.fn.extend(data);
	//等同写法
	s94.extend(s94.fn.prototype, data);
	//示例
	s94.fn.extend({getName: function(){
		return this[0].nodeName;
	}})
	console.log(s94('.class').getName())
```

<p id="type"></p>

## **s94.type(obj)** 
- obj `Object` 判断的数据
- 返回 `String` 数据类型，就是对象的名称
>返回obj参数的数据类型
```js
s94.type({a:1}); // Object
s94.type([1,2]); // Array
s94.type(new Date()); // Date

function Obj(){}
s94.type(new Obj()); // Obj
```

<p id="each"></p>

## **s94.each(obj, callback[, thisArg])** 
- obj `Object` 遍历的对象
- callback `Function` 遍历时执行的回调函数，接收三个参数，类似Array.prototype.forEach，函数返回false终止遍历
- thisArg `Object` callback执行的this
- 返回 `Underfind` 
>遍历obj对象（for in的语法糖）
```js
var obj = {a:1, b:2}

s94.each(obj, function(row, i, o){
	//row 正在处理的当前元素。
	//i 当前元素的键值。
	//o 正在操作的对象，等同于obj
	console.log(i+':'+row)
});
//打印 a:1
//打印 a:2

s94.each(obj, function(row, i, o){
	//row 正在处理的当前元素。
	//i 当前元素的键值。
	//o 正在操作的对象，等同于obj
	console.log(i+':'+row);
	return false;
});
//打印 a:1
```
## **s94.fn.prototype.each(callback[, thisArg])** 
- callback `Function` 遍历时执行的回调函数，接收三个参数，类似Array.prototype.forEach，函数返回false终止遍历
- thisArg `Object` callback执行的this
- 返回 `Underfind` 
>s94对象的each方法扩展
```html
<div class="class"></div>
<div class="class"><p></p><p></p></div>
```
```js
s94('.class').each(function(row, i, o){
	//row 正在处理的当前Node元素。
	//i 当前元素的序号。
	//o 正在操作的s94对象，等同于s94('.class')
	console.log(i+':'+row)
})
//打印 0:[object HTMLDivElement]
//打印 1:[object HTMLDivElement]
```

<p id="eachloop"></p>

## **s94.eachloop(obj, childkey, callback[, thisArg])** 
- obj `Object` 遍历的对象
- childkey `String` 需要递归遍历的属性名，为空表示直接递归遍历正在处理的当前元素。
- callback `Function` 遍历时执行的回调函数，接收四个参数，相比于s94.each，第四个参数记录了键值路径，函数返回false终止遍历，返回underfind不递归遍历当前元素
- thisArg `Object` callback执行的this
- 返回 `Underfind` 
>遍历obj对象（for in的语法糖）
```js
var obj = {
	a: 'a',
	arr: [1,2,3],
	obj: {a:1, b:2}
}
s94.eachloop(obj, '', function(row, i, o, ks){
	//row 正在处理的当前元素。
	//i 当前元素的键值。
	//o 正在操作的对象，等同于obj
	//ks 键值路径
	console.log(ks+':'+row);
	return true
})
//a:a
//arr:1,2,3
//arr,0:1
//arr,1:2
//arr,2:3
//obj:[object Object]
//obj,a:1
//obj,b:2

var list = [
	{name: 'dir1',open:false, child:[
		{name: 'file1'},
		{name: 'file2'}
	]},
	{name: 'dir2',open:true, child:[
		{name: 'file3'},
		{name: 'file4'}
	]},
]
s94.eachloop(list, 'child', function(row, i, o, ks){
	console.log(row.name);
	if(row.open) return true;
});
//dir1
//dir2
//file3
//file4
```
## **s94.fn.prototype.eachloop(callback[, thisArg])** 
- callback `Function` 遍历时执行的回调函数，接收四个参数，相比于s94.each，第四个参数记录了键值路径，函数返回false终止遍历，返回underfind不递归遍历当前元素
- thisArg `Object` callback执行的this
- 返回 `Underfind` 
>s94对象的eachloop方法扩展，childkey为children
```html
<div class="class"></div>
<div class="class"><p></p><p></p></div>
```
```js
s94('.class').eachloop( function(row, i, o, ks){
	console.log(ks+':'+row.nodeName);
	return true;
});
//
//打印 0:DIV
//打印 1:DIV
//打印 1,0:P
//打印 1,1:P
```

<p id="eachlimit"></p>

## **s94.eachlimit(obj, op)** 
- obj `Object` 遍历的对象
- op `Function`|`Object` 配置参数，如果为`Function`，表示op.each
	- limit `Number` 限制同时执行的数量，默认为100
	- each `Function` 遍历执行的回调函数，each(next, row, k)，当前遍历执行完成后，调用next表示进行下一个row的遍历
	- over `Function` 遍历结束后的回调函数，over(obj)
- 返回 `Underfind` 
>限制遍历obj对象，主要用于不能同时遍历的情况，例如大批量的ajax请求，可以用eachlimit防止同时请求数量太多
```js
var obj = [
	{name: 'name1', url: 'url1'},
	{name: 'name2', url: 'url2'},
	{name: 'name3', url: 'url3'},
	{name: 'name4', url: 'url4'},
	{name: 'name5', url: 'url5'},
	//......
	{name: 'name10000', url: 'url10000'},
]

s94.eachlimit(obj, {
	limit: 50,
	each: function(next, row, k){
		$.ajax({
			url: row.url,
			success: function(res){
				row.res = res;
				next();
			}
		})
	},
	over: function(){
		alert('下载完成')
	}
});
```

<p id="type"></p>

## **s94.merge(obj1[, obj2 ,...])** 
- obj1、obj2 `Object` 用于合并的多个对象
- 返回 `Object` 合并后的对象
>合并多个对象，支持合并数组和对象。返回新的对象，不改变传入的对象
```js
var obj1 = {a:1,b:2};
var obj2 = [1,2];

var res1 = s94.merge(obj1, obj2);
var res2 = s94.merge(obj2, obj1);

console.log( s94.type(res1), res1 );//打印Object {0: 1, 1: 2, a: 1, b: 2, length: 2, push: ƒ}
console.log( s94.type(res2), res2 );//打印Array (2) [1, 2, a: 1, b: 2]
```

<p id="sort"></p>

## **s94.sort(arr, ace)** 
- arr `Array` 排序的数组
- ace `Function` 判断的回调方法ace(a, b)，返回表示a,b是否按顺序排列
- 返回 `Array` 排序后的数组
>使用自定义的规则对数组进行排序，用于弥补Array.prototype.sort()的不足
```js
var arr = ['10','23','2','3','1'];
console.log( arr.sort() ); //打印['1', '10', '2', '23', '3']
console.log( s94.sort(arr, function(a, b){
	return Number(a) < Number(b);
}) ); //打印['1', '2', '3', '10', '23']
//倒序
console.log( s94.sort(arr, function(a, b){
	return Number(a) > Number(b);
}) ); //打印['23', '10', '3', '2', '1']
```

<p id="trim"></p>

## **s94.trim(str[, mask])** 
- str `String` 操作的字符串
- mask `String` 额外需要去除的对应字符
- 返回 `Object` 合并后的对象
>去除字符串首尾的空格或者其他字符串
```js
var str = '$ hello world ';

console.log( s94.trim(str) );//打印$ hello world
console.log( s94.trim(str, 'd$') );//打印hello worl
```

<p id="reparam"></p>

## **s94.reparam(str)** 
- str `String` 操作的字符串
- 返回 `Object` 转化后的对象
>把urlparam类型字符串转化成对象
```js
var str = 'name=name1&pass=123456';
console.log( s94.reparam(str) );//打印{name: "name1", pass: "123456"}

//比较复杂的
var str = 'a=a&arr[]=1&arr[]=2&arr[]=3&obj[a]=1&obj[b]=2';
console.log( s94.reparam(str) );//打印{a: "a", arr: Array(3), obj: {…}}
```

<p id="param"></p>

## **s94.param(obj)** 
- str `String` 操作的对象
- 返回 `Object` 转化后的字符串
>把对象转化成urlparam类型字符串
```js

var str = 'name=name1&pass=123456';
var obj = s94.reparam(str);

console.log( obj );//打印{name: "name1", pass: "123456"}
console.log( s94.param(obj) );//打印name=name1&pass=123456

//比较复杂的
var obj = {
	a: 'a',
	arr: [1,2,3],
	obj: {a:1, b:2}
}
var str =  s94.param(obj);
console.log( str );//打印a=a&arr[0]=1&arr[1]=2&arr[2]=3&obj[a]=1&obj[b]=2
```

<p id="url"></p>

## **s94.url(str[, base])** 
- str `String` 是一个表示绝对或相对 URL字符串
- base `String` 如果str是一个相对URL，将以此地址为基础
- 返回 `URL` URL对象，包含字段有href,protocol,username,password,host,hostname,port,origin,pathname,search,hash
>创建URL对象
```js

s94.url('../index.html', 'http://localhost/html/s94.html');
// hash: ""
// host: "localhost"
// hostname: "localhost"
// href: "http://localhost/index.html"
// origin: "http://localhost"
// password: ""
// pathname: "/index.html"
// port: ""
// protocol: "http:"
// search: ""
// searchParams: URLSearchParams {}
// username: ""
```

<p id="encode"></p>

## **s94.encode(data)** 
- data `Object` 编码对象
- 返回 `String` 编码后的编码成36位字符串(包含小写英文、数字)
>把data编码成36位字符串(包含小写英文、数字)，主要是用来压缩对象，并且避免重复
```js
console.log(s94.encode('123'));//打印1e3h5k6789abcdefghijklmnopqrstuvwxyz
console.log(s94.encode('321'));//打印1g3h5i6789abcdefghijklmnopqrstuvwxyz
var obj = {
	a: 'a',
	arr: [1,2,3],
	obj: {a:1, b:2}
}
console.log(s94.encode(obj));//打印6w568l9dfqidknk0kxoanoptqtvjxpzz0z11
```

<p id="new_cache"></p>

## **new s94.Cache(engine)** 
- engine `Object` 设定的Cache的引擎，包含方法setItem、getItem、removeItem参考[Storage](https://developer.mozilla.org/zh-CN/docs/Web/API/Storage)。默认为window.sessionStorage
- 返回 `Object` 缓存示例，包含:
  - get(name, def) 获取缓存名为`name`的缓存值，如果缓存不存在，返回`def`
  - set(kv, timeout) 按`kv`的键值关系设定缓存，键和值分别表示缓存名和对应的值，`timeout`为过期的时间戳(毫秒)，判定为false时表示永久
  -remove(name) 移除缓存缓存`name`

<p id="cache"></p>

## **s94.cache(name_kv[, def_timeout][, engine])** 
- name_kv `String|Object` 缓存名称或者设定缓存的键值对象。如果传入`String`表示获取缓存的`name`，如果传入键值对象，表示设定缓存的`ky`
- def_timeout `mixed` 获取缓存的缺省值`def`，或者缓存过期的时间戳`timeout`
- engine `Object` 设定的Cache的引擎
- 返回 `mixed` 如果是获取缓存，返回对应的缓存值，如果缓存数据不存在，返回缺省值。如果传入value，返回underfind

<p id="cache.clean"></p>

## **s94.cache.remove(name[, engine])** 
- name `String` 缓存名称
- engine `Object` 设定的Cache的引擎
- 返回 `Underfind` 

>缓存数据或者提取缓存的数据
```js
s94.cache({'name1':123});
console.log(s94.cache('name1'));//打印123
s94.cache.remove('name1');//移除缓存

//使用其他引擎-方式1
var c = new s94.Cache(localStorage);
c.set({'name2':456});
console.log(c.get('name2'));//打印456
c.remove('name2');//移除缓存
//使用其他引擎-方式2
s94.cache({'name3':789}, 0, localStorage);
console.log(s94.cache('name3', undefined, localStorage));//打印789
s94.cache.remove('name3', localStorage);//移除缓存

//使用自定义引擎
var engine = {
	setItem: function(keyName, keyValue){
		//设定缓存操作...
	},
	getItem: function(keyName){
		//获取缓存操作...
	},
	removeItem: function(keyName){
		//移除缓存操作...
	}
}
s94.cache({'name4':789}, 0, engine);
//。。。。。。
```

<p id="ajax"></p>

## **s94.ajax(setup)** 
- setup `Object|String` 配置对象，也可以单传入url
	- type `String` 请求类型，不分大小写，GET,POST,JSONP，默认GET
	- url `String` 请求地址
	- data `Object` 请求发送数据
	- headers `Object` 请求的header
	- jsonp `String` 如果是jsonp请求，请求附加的参数的键值，默认为callback
	- jsonpCallback `String` 如果是jsonp请求，请求附加的参数的值，默认为`'jsonp_'+(new Date().getTime())`
	- async  `Boolean` 是否异步，默认true
	- global  `Boolean` 是否全局广播事件，默认true
	- cache  `Boolean` 是否缓存数据，默认false
	- refresh  `Boolean` 如果缓存数据，当网络请求结果和缓存的数据不同时，是否刷新(再次调用success)，默认true
	- progress  `Function` 进度事件回调函数，接收一个参数[ProgressEvent](https://developer.mozilla.org/zh-CN/docs/Web/API/ProgressEvent)
	- beforeSend  `Function` 请求执行前执行的回调函数
	- success  `Function` 请求成功的回调，接收一个参数，表示响应数据，如果响应数据类型为json，会调用JSON.parse
	- error  `Function` 请求出错的回调函数，接收一个参数，表示错误信息
	- complete  `Function` 请求完成的回到函数，接收一个参数，表示请求是否成功
- 返回 `Object` 修改后的setup,添加了属性cleanCache，xhr。同时也是所有回调函数的this
>ajax同步或者异步请求
```js
s94.ajax({
	url: 'url.....',
	cache: true,
	success: function(res){
		if(res.code!=1) {
			this.cleanCache(); //当返回结果错误后，清理缓存，避免多次报错处理
		}
		console.log(res);
	}
})
```

<p id="loadJs"></p>

## **s94.loadJs(setup[, callback])** 
- setup `String|Array|Object` 配置对象，也可以单传入src
	- src `String|Array` 加载js的地址，多个地址用数组
	- refresh `Boolean` 是否刷新，如果刷新，则需要引入的js已经存在同样会引入
	- load `Function` 每个js加载成功后，会执行的回调函数，传入一个参数，当前加载的js节点对象
	- error `Function` 当某个js加载失败后会执行的回调函数，传入一个参数，当前加载的js节点对象
- callback `Function` 当src中的所有js加载完成后执行的回调函数，传入一个参数，加载的所有js节点列表数组
- 返回 `underfind` 
>异步加载js文件，加载完成执行回调
```js
s94.loadJs(['js1.js','js2.js'], function(){
	console.log('加载完成了')
})
```

<p id="screenOffsetPage"></p>

## **s94.screenOffsetPage([to, op, callback])** 
- to `Number|Object` 偏移跳转到坐标to,格式{x:像素,y:像素}，如果传入`Number`单表示Y坐标
- op `Object|Number` {speed: 执行速度(px/s)}或者{time: 执行时间(毫秒)，传入`Number`表示time
- callback `Function` 动画执行结束后执行的回调函数
- 返回 `Object` 偏移量{x: X偏移量,y: Y偏移量}
>屏幕相对于页面的偏移，或者滚动到指定位置
```js
console.log(s94.screenOffsetPage());//打印{x: 0, y: 0}

//执行滚动到500px处,速度哦1000px/s
s94.screenOffsetPage(500, {speed: 1000});
```

<p id="domOffsetPage"></p>

## **s94.domOffsetPage(dom)** 
- dom `Node` 节点对象
- 返回 `Object` 偏移量{x: X偏移量,y: Y偏移量}
>元素相对于页面的偏移
```js
console.log( s94.domOffsetPage(document.querySelector('.class')) );//打印{x: 0, y: 0}
//便捷写法
console.log( s94('.class').domOffsetPage() );//打印{x: 0, y: 0}
```

<p id="domOffsetParent"></p>

## **s94.domOffsetParent(dom[, parent])** 
- dom `Node` 节点对象
- parent `Node` 父节点对象，默认为dom.parentNode
- 返回 `Object` 偏移量{x: X偏移量,y: Y偏移量}
>元素dom相对于父级元素parent的偏移
```js
console.log( s94.domOffsetParent(document.querySelector('.class'), document.querySelector('body')) );//打印{x: 0, y: 0}
//便捷写法
console.log( s94('.class').domOffsetParent(document.querySelector('body')) );//打印{x: 0, y: 0}
```

<p id="eventOffsetScreen"></p>

## **s94.eventOffsetScreen([e])** 
- e `Event` 事件对象，默认为window.event
- 返回 `Object` 偏移量{x: X偏移量,y: Y偏移量}
>获取事件触发定位，相对于屏幕
```js
console.log( s94.eventOffsetScreen() );//打印{x: 20, y: 58}
```

<p id="eventOffsetTarget"></p>

## **s94.eventOffsetTarget([e])** 
- e `Event` 事件对象，默认为window.event
- 返回 `Object` 偏移量{x: X偏移量,y: Y偏移量}
>获取事件触发定位，相对于触发DOM节点
```js
console.log( s94.eventOffsetTarget() );//打印{x: 20, y: 58}
```

<p id="eventOffsetDom"></p>

## **s94.eventOffsetDom(dom[, e])** 
- dom `Node` 节点对象
- e `Event` 事件对象，默认为window.event
- 返回 `Object` 偏移量{x: X偏移量,y: Y偏移量}
>获取事件触发定位，相对于DOM节点，如果
```js
console.log( s94.eventOffsetDom(document.querySelector('.class') );//打印{x: 20, y: 58}
//便捷写法
console.log( s94('.class').eventOffsetDom() );//打印{x: 20, y: 58}
```

<p id="date"></p>

## **s94.date(fmt[, time])** 
- fmt `String` 格式化样式模板，如果模板需要[YMDHISWymdhisw]字符串的，需要在前面加\
	- Y|y 表示年份
	- M|m 表示月份(1-12)，大写的表示有前导0的，
	- D|d 表示当月的第几天(1-31)，大写的表示有前导0的，
	- H|h 表示小时数量(0-23)，大写的表示有前导0的，
	- I|i 表示分钟(0-59)，大写的表示有前导0的，
	- S|s 表示秒(0-59)，大写的表示有前导0的，
	- W|w 表示星期几，大写的表示汉字的(一-日)，小写的表示数字(1-7)
- time `String|Number` 需要格式化的时间，参数格式参考[new Date()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date)，默认为当前时间
- 返回 `String` 格式化后的时间日期字符串
>格式化时间日期
```js
console.log( s94.date( 'Y-M-D H:I:S') );//打印2022-06-15 09:11:18
//指定时间
console.log( s94.date( 'Y-M-D H:I:S', 1655255526000) );//打印2022-06-15 09:12:06
console.log( s94.date( 'Y-M-D H:I:S', '2022-06-15T09:12:06') );//打印2022-06-15 09:12:06
//模板中需要[YMDHISWymdhisw]字符串
console.log( s94.date( '<\\span>m-d W</\\span>', 1655255526000) );//打印<span>6-15 三</span>
```

<p id="strtodate"></p>

## **s94.strtodate(str, fmt)** 
- str `String` 转化的字符串
- fmt `String` 格式化样式模板，格式等同s94.date
- 返回 `Date` 日期对象
>格式化时间日期
```js
var str = s94.date( 'Y-M-D H:I:S');
console.log( s94.strtodate( str, 'Y-M-D H:I:S') );//打印Wed Jun 15 2022 09:12:06 GMT+0800 (中国标准时间)

//字符串中没有指定的数据，会按最小值替换
console.log( s94.strtodate('<span>09:12:06</span>', '<\\span>H:I:S</\\span>') );//打印Thu Jan 01 1970 09:12:06 GMT+0800 (中国标准时间)
```

<p id="autoRequire"></p>

## **s94.autoRequire(data)** 
- data `Object` 注册的自动加载模块{key: moduleName}
- 返回 `underfind`
>自动加载模块注册，注册时，页面不会加载模块，只会在第一次使用时require需要的模块
```js
s94.autoRequire({
	Vue: 'Vue',//模块名称的方式
	imgclip: '/node_modules/s94-imgclip/s94.ImgClip.js',//模块文件路径的方式
	md5: 'md5'
})
//注册后，可以直接使用s94.[key]调用
//调用的模块才会加载，仅注册，没调用的模块，不会加载
var app = s94.Vue.createApp({}); //加载Vue模块，并且创建APP
var imgclip = new $.ImgClip(document.querySelector('#imgclip'));//加载s94.ImgClip.js，并创建剪切组件
//由于md5模块没有调用，所有，页面中不会加载md5模块相关的js
```


<p id="clip"></p>

## **clip([type, quality])**

>toBase64的别名
```js
console.log(imgclip.clip()); //data:image/png;base64,iVBOR.....
```

<p id="toBlob"></p>

## **toBlob(callback[, type, quality])**
- callback `Function` 回调函数，用于接收裁剪后图片的Blob数据
- type `String` 表示生成图片类型[jpg,png,webp]。(**默认值**:png)
- quality `Number` 表示生成图片质量[0-1] (**默认值**:0.92)
- 返回 `Promise`|`underfind`
>输出裁剪图片，返回图片的blob数据
```js
imgclip.toBlob(function(blobData){
	console.log(blobData);
});
//支持使用Promise异步调用
imgclip.toBlob().then(function(blobData){
	console.log(blobData);
});
```

---
_Source: https://npm.io/package/s94-web · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
