前言
JS封装了一套常用的类型检测工具库,可以判断常见的dom对象,String以及Function对象。
工具库特点
- 通过ES6语法进行导入导出,方便使用。
- 按需加载,只需要加载使用到的函数
- 类型检测基本全覆盖
- 不断进行扩充
项目结构
|– root (项目根目录)
—| is.js (类型检测库)
—| other.js (业务代码)
业务代码
is.js
/**
* Check if args is a Document element
* @param {Object} elem
* @returns {Boolean}
*/
exports.isDocument = function (elem) {
return elem !== undefined &&
elem instanceof Document &&
elem.nodeType === 9
}
/**
* Check if args is a HTML Node
* @param {Object} elem
* @returns {Boolean}
*/
exports.isNode = function (elem) {
return elem !== undefined &&
elem instanceof HTMLElement &&
elem.nodeType === 1
}
/**
* Check if args is a list of HTML Node
* @param {Array} eList
*/
exports.isNodeList = function (eList = {}) {
let type = Object.prototype.toString.call(eList)
return eList !== undefined &&
(type === '[object HTMLCollection]' || type === '[object HTMLCollection]') &&
length in eList &&
(eList.length === 0 || exports.isNode(eList[0]))
}
/**
* Check if args is a string
* @param {Object} val
*/
exports.isString = function (val = '') {
return typeof val === 'string' ||
val instanceof String
}
/**
* Check if args is a function
* @param {Object} val
*/
exports.isFn = function (val) {
return val !== undefined &&
typeof val === 'function' &&
Object.prototype.toString.call(val) === '[object Function]'
}
other.js
import {isDocument, isNode, isNodeList, isString, isFn} from './is.js'
let list = document.getElementsByTagName('div')
isDocument(document) // 判断dom对象 true
isNode(list[0]) // 判断node节点 true
isNodeList(list) // 判断node集合 true
isString("new String('123')") // eslint-disable-line true
isFn(window.alert) // 判断函数类型 true
let a = isDocument(document)
console.log('a', a) // true
delegate.js
import delegate from 'delegate'
import { isString, isFn, isNode, isNodeList } from './isType'
/**
* EventListener delegate
* @export
* @param {*} target
* @param {String} type
* @param {Function} callback
* @returns {Object}
*/
export function listen (target, type, callback) {
if (!target || !type || !callback) {
throw new Error('arguments cannot be empty')
}
if (!isString(type)) {
throw new TypeError('type must be a String')
}
if (!isFn(callback)) {
throw new TypeError('callback must be a Function')
}
// There are three situations of target
if (isString(target)) {
console.log('target is String')
return listenSelector(target, type, callback)
} else if (isNode(target)) {
console.log('target is Node')
return listenNode(target, type, callback)
} else if (isNodeList(target)) {
console.log('target is NodeList')
return listenNodeList(target, type, callback)
} else {
throw new TypeError('target must be String|Node|NodeList')
}
}
/**
* typeof target is string
* @param {String} target
* @param {String} type
* @param {Function} callback
* @return {Object}
*/
const listenSelector = function (target, type, callback) {
return delegate(document.body, target, type, callback, false)
}
/**
* typeof target is node
* @param {Object} node
* @param {String} type
* @param {Function} callback
* @return {Object}
*/
const listenNode = function (node = {}, type = '', callback) {
node.addEventListener(type, callback)
return {
destroy () {
node.removeEventListener(type, callback)
}
}
}
/**
* typeof target is nodeList
* @param {Array} nodeList
* @param {String} type
* @param {Object} callback
*/
const listenNodeList = function (nodeList = [], type = '', callback) {
Array.prototype.forEach.call(nodeList, (node) => {
node.addEventListener(type, callback)
})
return {
destroy () {
Array.prototype.forEach.call(nodeList, (node) => {
node.removeEventListener(type, callback)
})
}
}
}