前言
在看ecahrts-wordcloud插件源码,想要知道这个插件怎么处理数据的,以致于字符云显示的数据不全,且不是优先显示频率较大的字符的。还没找出来,发现了他有一些工具方法可以借鉴的,所以记下来备用。。。哈哈哈
1、判断是否是NaN
function eqNaN(value) {
return value !== value;
}
除了isNaN(),这样子也可以判断NaN。
2、判断是否是对象
function isObject(value) {
// Avoid a V8 JIT bug in Chrome 19-20.
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
var type = typeof value;
return type === 'function' || !!value && type == 'object';
}
3、判断是否是Dom
function isDom(value) {
return typeof value === 'object' && typeof value.nodeType === 'number' && typeof value.ownerDocument === 'object';
}
让我想到之前写的将字符串转为Dom的方法:
function parseDom (html) {
if (typeof html === 'string') { // 如果是字符串
var element = document.createElement('div')
element.innerHTML = html
return element.childNodes[0]
} else if (typeof html === 'object') {
return html
}
}
4、数组过滤
/**
* 数组过滤
* @param {Array} obj
* @param {Function} cb
* @param {*} [context]
* @return {Array}
*/
function filter(obj, cb, context) {
if (!(obj && cb)) {
return;
}
if (obj.filter && obj.filter === Array.prototype.filter) {
return obj.filter(cb, context);
} else {
var result = [];
for (var i = 0, len = obj.length; i < len; i++) {
if (cb.call(context, obj[i], i, obj)) {
result.push(obj[i]);
}
}
return result;
}
}
5、拷贝:纯对象,数组,类数组,数字,字符串,null,undefined这些可以被复制,但是不支持拷贝日期
var objToString = Object.prototype.toString
// 用于处理merge时无法遍历Date等对象的问题
var BUILTIN_OBJECT = {
'[object Function]': 1,
'[object RegExp]': 1,
'[object Date]': 1,
'[object Error]': 1,
'[object CanvasGradient]': 1,
'[object CanvasPattern]': 1,
// For node-canvas
'[object Image]': 1,
'[object Canvas]': 1
};
var TYPED_ARRAY = {
'[object Int8Array]': 1,
'[object Uint8Array]': 1,
'[object Uint8ClampedArray]': 1,
'[object Int16Array]': 1,
'[object Uint16Array]': 1,
'[object Int32Array]': 1,
'[object Uint32Array]': 1,
'[object Float32Array]': 1,
'[object Float64Array]': 1
};
var primitiveKey = '__ec_primitive__';
function isPrimitive(obj) {
return obj[primitiveKey];
}
function clone(source) {
if (source == null || typeof source != 'object') {
return source;
}
var result = source;
var typeStr = objToString.call(source);
if (typeStr === '[object Array]') { // 拷贝数组
result = [];
for (var i = 0, len = source.length; i < len; i++) {
result[i] = clone(source[i]);
}
} else if (TYPED_ARRAY[typeStr]) { // 拷贝类数组
var Ctor = source.constructor;
if (source.constructor.from) {
result = Ctor.from(source);
} else {
result = new Ctor(source.length);
for (var i = 0, len = source.length; i < len; i++) {
result[i] = clone(source[i]);
}
}
} else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) { // 拷贝对象
result = {};
for (var key in source) {
if (source.hasOwnProperty(key)) {
result[key] = clone(source[key]);
}
}
}
return result;
}
哈哈,这个真的好长,下面这个是自己写的深拷贝,比较简单,纯对象,数组,数字,字符串,null,undefined这些可以被复制
deepCopy = (list) => {
if (list !== 0 && !list) return
let newobj = list.constructor === Array ? [] : {}
if (typeof list !== 'object') {
return list
}
if (typeof HTMLElement === 'object' && list instanceof HTMLElement) return list
else if (list.nodeType === 1 && typeof list.nodeName === 'string') return list
for (let i in list) {
newobj[i] = typeof list[i] === 'object' ? deepCopy(list[i]) : list[i]
}
return newobj
}
================================ 分割线 ===================================
添加一些其他的工具函数吧
6、判断是否是颜色值的方法:
isColor = function (color, hasRgba = false) {
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
let regRgb = /^[rR][gG][Bb]?[\(]([\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),){2}[\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),?[\s]*(0\.\d{1,2}|1|0)?[\)]{1}$/g
let regRgba = /^[rR][gG][Bb][Aa]?[\(]([\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),){2}[\s]*(2[0-4][0-9]|25[0-5]|[01]?[0-9][0-9]?),?[\s]*(0\.\d{1,2}|1|0)?[\)]{1}$/g
if (hasRgba) {
return reg.test(color) || regRgb.test(color) || regRgba(color)
}
return reg.test(color) || regRgb.test(color)
}
7、十六进制转为rgba
OXToRGB = function (color) {
let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
let sColor = color.toLowerCase()
if (sColor && reg.test(sColor)) {
if (sColor.length === 4) {
let sColorNew = '#'
for (let i = 1; i < 4; i += 1) {
sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
}
sColor = sColorNew
}
// 处理六位的颜色值
let sColorChange = []
for (let i = 1; i < 7; i += 2) {
sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
}
return 'RGBA(' + sColorChange.join(',') + ',1)'
} else {
return sColor
}
}
8、高亮搜索结果的关键字
brightenKeyword = function (val, keyword) {
let len = val.toLowerCase().indexOf(keyword.toLowerCase())
if (keyword !== '' && len > -1) {
return `<span>${val.slice(0, len)}</span>
<span style="color:#2A70FE">${val.slice(len, len + keyword.length)}</span>
<span>${val.substr(len + keyword.length)}</span>`
}
return val
}
9、获取style样式
getStyle = (element, attr, NumberMode = 'int') => {
let target;
// scrollTop 获取方式不同,没有它不属于style,而且只有document.body才能用
if (attr === 'scrollTop') {
target = element.scrollTop;
} else if (element.currentStyle) {
target = element.currentStyle[attr];
} else {
target = document.defaultView.getComputedStyle(element, null)[attr];
}
// 在获取 opactiy 时需要获取小数 parseFloat
return NumberMode === 'float' ? parseFloat(target) : parseInt(target);
};
10、页面到达底部,加载更多
这里用到了上一个getStyle方法
loadMore = (element, callback) => {
let windowHeight = window.screen.height;
let height;
let setTop;
let paddingBottom;
let marginBottom;
let requestFram;
let oldScrollTop;
document.body.addEventListener('scroll', () => {
loadMore();
}, false);
// 运动开始时获取元素 高度 和 offseTop, pading, margin
element.addEventListener('touchstart', () => {
height = element.offsetHeight;
setTop = element.offsetTop;
paddingBottom = getStyle(element, 'paddingBottom');
marginBottom = getStyle(element, 'marginBottom');
}, {passive: true});
// 运动过程中保持监听 scrollTop 的值判断是否到达底部
element.addEventListener('touchmove', () => {
loadMore();
}, {passive: true});
// 运动结束时判断是否有惯性运动,惯性运动结束判断是非到达底部
element.addEventListener('touchend', () => {
oldScrollTop = document.body.scrollTop;
moveEnd();
}, {passive: true});
const moveEnd = () => {
requestFram = requestAnimationFrame(() => {
if (document.body.scrollTop !== oldScrollTop) {
oldScrollTop = document.body.scrollTop;
loadMore();
moveEnd();
} else {
cancelAnimationFrame(requestFram);
// 为了防止鼠标抬起时已经渲染好数据从而导致重获取数据,应该重新获取dom高度
height = element.offsetHeight;
loadMore();
}
});
};
const loadMore = () => {
if (document.body.scrollTop + windowHeight >= height + setTop + paddingBottom + marginBottom) {
callback();
}
};
};
11、判断是否是数组的方法
function isArray (value) {
return value && !value.propertyIsEnumerable('length') && typeof value === 'object' && typeof value.length === 'number'
}