1 2 3 4 5 6 7 8 9 10 11 12 |
/** * @function Determine if the image has been loaded. * @param img,callback */ function imgIsLoaded(img, callback) { var timer = setInterval(function () { if (img.complete) { callback(img) clearInterval(timer) } }, 50) } |
分类:前端
JS深度合并对象
1 2 3 4 5 6 7 8 9 10 11 12 |
/** * 如果target(也就是FirstOBJ[key])存在, * 且是对象的话再去调用deepObjectMerge, * 否则就是FirstOBJ[key]里面没这个对象,需要与SecondOBJ[key]合并 */ function deepObjectMerge(FirstOBJ, SecondOBJ) { // 深度合并对象 for (var key in SecondOBJ) { FirstOBJ[key] = FirstOBJ[key] && FirstOBJ[key].toString() === "[object Object]" ? deepObjectMerge(FirstOBJ[key], SecondOBJ[key]) : FirstOBJ[key] = SecondOBJ[key]; } return FirstOBJ; } |
JS判断当前DOM树是否加载完毕
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/** * @function Monitor whether the document tree is loaded. * @param fn */ function domReady(fn) { if (document.addEventListener) { // 标准浏览器 document.addEventListener('DOMContentLoaded', function () { //注销时间,避免重复触发 document.removeEventListener('DOMContentLoaded', arguments.callee, false); fn(); // 运行函数 }, false); } else if (document.attachEvent) { // IE浏览器 document.attachEvent('onreadystatechange', function () { if (document.readyState == 'complete') { document.detachEvent('onreadystatechange', arguments.callee); fn(); // 函数运行 } }); } } domReady(loadStart); |
被引用的外部JS存在window.onload时,判断当前页面是否已存在window.onload,并进行相应处理
JS Cookie相关操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
function setCookie(cookieName, cookieValue, expires) { // 设置Cookie function getCookieName(cookieName) { //获取并返回与 cookieName 同名的 cookie 名称,允许大小写不同,如果不存在这样的 cookie,就返回 cookieName var lowerCookieName = cookieName.toLowerCase(); //转换为小写 var cookieStr = document.cookie; // 获取当前cookie if (cookieStr == "") { return cookieName; } var cookieArr = cookieStr.split(";"); var pos = -1; for (var i = 0; i < cookieStr.length; i++) { pos = cookieArr[i].indexOf("="); if (pos > 0) { if (cookieArr[i].substring(0, pos).toLowerCase() == lowerCookieName) { return cookieArr[i].substring(0, pos); } } } return cookieName; } function writeCookie(cookieName, cookieValue, expires) { // 写cookie,不区分大小写 if (expires) { document.cookie = getCookieName(cookieName) + "=" + escape(cookieValue) + "; expires=" + expires.toGMTString(); } else { document.cookie = getCookieName(cookieName) + "=" + escape(cookieValue); } } function readCookie(cookieName, defaultValue) { //获取并返回 cookie 值,不区分大小写 var lowerCookieName = cookieName.toLowerCase(); var cookieStr = document.cookie; if (cookieStr == "") { return defaultValue; } var cookieArr = cookieStr.split("; "); var pos = -1; for (var i = 0; i < cookieArr.length; i++) { pos = cookieArr[i].indexOf("="); if (pos > 0) { if (cookieArr[i].substring(0, pos).toLowerCase() == lowerCookieName) { return unescape(cookieArr[i].substring(pos + 1, cookieArr[i].length)); } } } return defaultValue; } writeCookie(cookieName, cookieValue, expires); } |
原生ajax方法封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
/** * @function ajax request * @fields ajaxName:请求名称,method:请求方法,headers:setRequestHeader自定义部分,url:接口地址,async:是否异步请求,withCredentials:是否支持跨域发送cookie,dataType:数据类型 ,data:post请求参数 * @param data:{ajaxName:"ajaxNameString",headers:{},method:"GET/POST",url:"",async:true/false,withCredentials:true/false,dataType:"json",data:""} * @result ajaxName.responseText */ function ajaxRequest (data, callback) { data = data || {} data.dataType = data.dataType || 'json' var sendParams = null var headers = data.headers || {} var ajax = data.ajaxName // 新建请求 if (window.XMLHttpRequest) { ajax = new XMLHttpRequest() } else { ajax = new ActiveXObject('Microsoft.XMLHTTP') } // 打开请求 ajax.open(data.method.toUpperCase(), data.url, data.async) // 是否支持跨域发送cookie ajax.withCredentials = data.withCredentials ajax.setRequestHeader("Content-type", data.contentType || "application/x-www-form-urlencoded") // POST请求设置 if (data.method == 'POST') { for (var i in headers) { ajax.setRequestHeader(i, headers[i]) } if (data.data) { sendParams = data.data } } // 发送请求 ajax.send(sendParams ? sendParams : null) // 注册事件 ajax.onreadystatechange = function () { if (window.location.origin + '/login/index' === ajax.responseURL) { window.location.reload() window.location.href = window.location.origin + '/login/index' return } callback(ajax) } } /** * GET * @param ajaxName 请求名称 * @param requestUrl 请求接口地址 * @param async 是否异步请求 * @param callBack 回调函数 * @param contentType 请求类型 */ function ajaxGetData (ajaxName, requestUrl, async, callBack, contentType) { ajaxRequest({ ajaxName: ajaxName, contentType: contentType || "application/json;charset=utf-8", method: "GET", url: requestUrl, async: async, cache: false, withCredentials: true, dataType: "json" }, function callback (ajax) { if (ajax.status == 200 && ajax.readyState == 4) { callBack(ajax.responseText) } }) } /** * 拼接GET请求url参数 * @param url * @param params * @returns {string} */ function formateGetUrl (url, params) { var resultParams = '' for (var key in params) { resultParams = resultParams + '&' + key + '=' + params[key] } return url + '?' + resultParams.substr(1) } /** * POST * @param ajaxName 请求名称 * @param requestUrl 请求接口地址 * @param async 是否异步请求 * @param callBack 回调函数 * @param contentType 请求类型 */ function ajaxPostData (ajaxName, requestUrl, params, async, callBack, contentType) { var resultParams = '' if (!contentType || contentType === "application/x-www-form-urlencoded;charset=utf-8") { for (var key in params) { resultParams = resultParams + '&' + key + '=' + encodeURIComponent(params[key]) } } else { resultParams = params && JSON.stringify(params) } ajaxRequest({ ajaxName: ajaxName, headers: {}, contentType: contentType || "application/x-www-form-urlencoded;charset=utf-8", method: "POST", dataType: "json", url: requestUrl, processData: true, async: async, data: resultParams }, function callback (ajax) { if (ajax.status == 200 && ajax.readyState == 4) { callBack(ajax.responseText) } }) } |
JS格式化时间(支持小程序,兼容IOS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
const REGEX = /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/ /** * @function format time * @param val, format * @return {string} * @example * <template> * <div> * <span>{{item.time | formatTime('yyyy/MM/dd hh:mm:ss')}}</span> * </div> * </template> * import {formatTime} from '../../library/timeFormat' * export default { * filters: {formatTime} * } */ export const formatTime = (val, format) => { if (val) { /** * @instructions 如果不是时间戳格式,且含有字符 '-' 则将 '-' 替换成 '/' && 删除小数点及后面的数字 * @reason 将 '-' 替换成 '/' && 删除小数点及后面的数字 的原因是safari浏览器仅支持 '/' 隔开的时间格式 */ if (val.toString().indexOf('-') > 0) { val = val.replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '').replace(/(-)/g, '/') // 将 '-' 替换成 '/' val = val.slice(0, val.indexOf('.')) // 删除小数点及后面的数字 } let date = new Date(val) date.setHours(date.getHours() + 8) const [whole, yy, MM, dd, hh, mm, ss] = date.toISOString().match(REGEX) const year = new Date().getFullYear() const month = new Date().getMonth() + 1 const dates = new Date().getDate() if (format) { return format .replace('yyyy', yy) .replace('yy', yy.slice(2)) .replace('MM', MM) .replace('dd', dd) .replace('hh', hh) .replace('mm', mm) .replace('ss', ss) } else { return [yy, MM, dd].join('-') + ' ' + [hh, mm, ss].join(':') } } else { return '--' } } |
理解[].forEach.call()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
例子: let cols = document.querySelectorAll('ul li') [].forEach.call(cols, function (col, index) { // TODO } 分析: ① []是一个空数组,无论这个数组里的最初值是什么,它们都不会被使用到; ② forEach方法是一个数组方法,只有数组才能调用;完整写法:Array.prototype.forEach,Array.forEach为简写; ③ call方法: 语法:fun.call(thisArg, arg1, arg2, ...) 参数:thisArg:在 fun 函数运行时指定的this值; arg1, arg2, ... : 指定的参数列表; 综上:[]这个空数组里的值(当然,它没有值)是最初的this值,通过call方法,当这个空数组调用方法forEach时, cols里的值会取代空数组原先的this值。 通俗的说,就是cols需要使用forEach这个方法, 但是这个方法是一个数组方法,只有数组才能调用,于是通过call方法来了个偷梁换柱, 在数组调用forEach方法的时候,将数组里的this值替换成了cols的值,达成了目的。 |
解决React首屏加载白屏的问题
Cannot resolve symbol ‘Component’ & Cannot resolve symbol ‘PropTypes’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import React, { Component, PropTypes } from 'react' 报错:Cannot resolve symbol 'Component' Cannot resolve symbol 'PropTypes' 1.解决 Cannot resolve symbol 'Component' 安装依赖:npm install @types/react --save 调用方法:import React, { Component } from 'react' 2.解决 Cannot resolve symbol 'PropTypes' 安装依赖:npm install prop-types --save 调用方法:import PropTypes from 'prop-types' 注:React.PropTypes 自 React v15.5 起已弃用。请使用 prop-types 库代替。 |