├── .gitignore ├── date.js ├── desktouch.js ├── es5 ├── artmpl.js ├── cookie.js ├── date.html ├── jq.validate.js ├── json2.js ├── jsonp.js ├── jtool.js ├── myfocus.js ├── mymd5.js ├── qrcode.js ├── query.html ├── query.js ├── share.js ├── storage.js ├── test.html └── xml2json.js ├── ie8 ├── jsonp.js ├── query.js └── storage.js ├── img ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg └── 5.jpg ├── jsonp.js ├── object.js ├── perf.html ├── perf.js ├── query.js └── storage.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /date.js: -------------------------------------------------------------------------------- 1 | // 获取date字符函数 2 | function getDateStr(date) { 3 | if (!(date instanceof Date)) { 4 | throw '必须为Date'; 5 | } 6 | 7 | const isoStr = date.toISOString(); 8 | return isoStr.slice(0, 10); 9 | } 10 | 11 | // 获取倒计时函数 12 | function getTimespan(ts) { 13 | const now = new Date(); 14 | const today = new Date(getDateStr(now)); 15 | const tmpDate = new Date(+today + ts); 16 | return tmpDate.toISOString().slice(11, 19); 17 | } 18 | 19 | // 获取多久以前函数 20 | function getBeforeTime(opts = {}) { 21 | // 如参数为日期 22 | if (opts instanceof Date) { 23 | opts = { 24 | date: opts 25 | }; 26 | } 27 | // 配置项 28 | opts = Object.assign({}, getBeforeTime.defaults, opts); 29 | const { date, splitReg, units, type, rightNow, ago } = opts; 30 | 31 | // 目标时间 32 | if (!(date instanceof Date)) { 33 | throw '必须为Date'; 34 | } 35 | 36 | // 时间间隔 37 | const timeSpan = Date.now() - date; 38 | // 时间间隔提取出的年月日等数字信息 39 | const spanNums = new Date(timeSpan).toISOString().split(splitReg); 40 | // 时间原点提取提取出的年月日等数字信息 41 | const originNums = new Date(0).toISOString().split(splitReg); 42 | 43 | // 获取的多少年月日前信息数组 44 | const rsArray = spanNums.map((item, index) => item -= originNums[index]); 45 | 46 | switch (type) { 47 | // x年x月x天 48 | case 1: { 49 | return units.map((item, index) => rsArray[index] + item).join('') + ago; 50 | } 51 | // [年, 月, 日] 52 | case 2: { 53 | return rsArray; 54 | } 55 | // x年前或者x月 56 | case 3: { 57 | let rsStr = rightNow; 58 | for (let i = 0, len = rsArray.length; i < len; i++) { 59 | const item = rsArray[i]; 60 | if (item) { 61 | rsStr = item + units[i]; 62 | break; 63 | } 64 | } 65 | return rsStr + ago; 66 | } 67 | } 68 | } 69 | getBeforeTime.defaults = { 70 | splitReg: /[^\d]/, 71 | // 年月日等单位信息 72 | units: ['年', '月', '天', '小时', '分', '秒'], 73 | // 返回数据类型(1: x年x月x天前, 2: [年, 月, 日], 3: x年前或者x月前) 74 | type: 3, 75 | // 刚刚信息 76 | rightNow: '刚刚', 77 | // 以前信息 78 | ago: '前' 79 | }; 80 | 81 | 82 | // 日期相关处理对象 83 | export default { 84 | // 获取date字符函数 85 | getDateStr, 86 | // 获取倒计时函数 87 | getTimespan, 88 | // 获取多久以前函数 89 | getBeforeTime 90 | }; 91 | -------------------------------------------------------------------------------- /desktouch.js: -------------------------------------------------------------------------------- 1 | /* 2 | * desktouch.js 3 | * 桌面浏览器模拟touch事件 4 | * */ 5 | (function() { 6 | 7 | //阻止函数 8 | function preventAll(evt) { 9 | evt.preventDefault(); 10 | evt.stopPropagation(); 11 | } 12 | 13 | //mouse事件转touch 14 | function mouseToTouch(type, evt, target) { 15 | target || (target = evt.target); 16 | 17 | //除文本域以外preventAll 18 | if (!/(select|input|textarea)/i.test(target.tagName)) { 19 | preventAll(evt); 20 | } 21 | 22 | var event = document.createEvent('Event'); 23 | event.initEvent(type, true, true); 24 | 25 | //非touchend添加touches 26 | if (type !== 'touchend') { 27 | var touch = { 28 | pageX: evt.pageX, 29 | pageY: evt.pageY, 30 | target: target 31 | }; 32 | event.touches = event.changedTouches = event.targetTouches = [touch]; 33 | } 34 | 35 | //添加事件的其他属性 36 | for (var p in evt) { 37 | event[p] === undefined && (event[p] = evt[p]); 38 | } 39 | 40 | event.isFromMouse = true; 41 | target.dispatchEvent(event); 42 | } 43 | 44 | var isDowned = false, 45 | isFirstMove = false, 46 | isMoved = false, 47 | lastTarget = null; 48 | 49 | document.addEventListener('mousedown', function(evt) { 50 | isDowned = true; 51 | lastTarget = evt.target; 52 | 53 | mouseToTouch('touchstart', evt); 54 | isFirstMove = true; 55 | isMoved = false; 56 | }, true); 57 | 58 | document.addEventListener('mousemove', function(evt) { 59 | if (!isDowned) { 60 | return; 61 | } 62 | if (isFirstMove) { 63 | isFirstMove = false; 64 | return; 65 | } 66 | 67 | mouseToTouch('touchmove', evt); 68 | isMoved = true; 69 | }, true); 70 | 71 | document.addEventListener('mouseup', function(evt) { 72 | if (!isDowned) { 73 | return; 74 | } 75 | 76 | mouseToTouch('touchend', evt, lastTarget); 77 | lastTarget = null; 78 | isDowned = false; 79 | }, true); 80 | 81 | document.addEventListener('click', function(evt) { 82 | if (!evt.isFromMouse && evt.target === lastTarget) { 83 | preventAll(evt); 84 | } 85 | if (isMoved) { 86 | preventAll(evt); 87 | isMoved = false; 88 | } 89 | }, true); 90 | 91 | 92 | //禁用所有移动端不存在的事件 93 | ['drag', 'dragstart', 'dragenter', 'dragover', 'dragleave', 'dragend', 'drop', 'selectstart'].forEach(function(type) { 94 | document.addEventListener(type, preventAll, true); 95 | }); 96 | 97 | })(); 98 | -------------------------------------------------------------------------------- /es5/artmpl.js: -------------------------------------------------------------------------------- 1 | /*!art-template - Template Engine | http://aui.github.com/artTemplate/*/ 2 | !function(){function a(a){return a.replace(t,"").replace(u,",").replace(v,"").replace(w,"").replace(x,"").split(y)}function b(a){return"'"+a.replace(/('|\\)/g,"\\$1").replace(/\r/g,"\\r").replace(/\n/g,"\\n")+"'"}function c(c,d){function e(a){return m+=a.split(/\n/).length-1,k&&(a=a.replace(/\s+/g," ").replace(//g,"")),a&&(a=s[1]+b(a)+s[2]+"\n"),a}function f(b){var c=m;if(j?b=j(b,d):g&&(b=b.replace(/\n/g,function(){return m++,"$line="+m+";"})),0===b.indexOf("=")){var e=l&&!/^=[=#]/.test(b);if(b=b.replace(/^=[=#]?|[\s;]*$/g,""),e){var f=b.replace(/\s*\([^\)]+\)/,"");n[f]||/^(include|print)$/.test(f)||(b="$escape("+b+")")}else b="$string("+b+")";b=s[1]+b+s[2]}return g&&(b="$line="+c+";"+b),r(a(b),function(a){if(a&&!p[a]){var b;b="print"===a?u:"include"===a?v:n[a]?"$utils."+a:o[a]?"$helpers."+a:"$data."+a,w+=a+"="+b+",",p[a]=!0}}),b+"\n"}var g=d.debug,h=d.openTag,i=d.closeTag,j=d.parser,k=d.compress,l=d.escape,m=1,p={$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1},q="".trim,s=q?["$out='';","$out+=",";","$out"]:["$out=[];","$out.push(",");","$out.join('')"],t=q?"$out+=text;return $out;":"$out.push(text);",u="function(){var text=''.concat.apply('',arguments);"+t+"}",v="function(filename,data){data=data||$data;var text=$utils.$include(filename,data,$filename);"+t+"}",w="'use strict';var $utils=this,$helpers=$utils.$helpers,"+(g?"$line=0,":""),x=s[0],y="return new String("+s[3]+");";r(c.split(h),function(a){a=a.split(i);var b=a[0],c=a[1];1===a.length?x+=e(b):(x+=f(b),c&&(x+=e(c)))});var z=w+x+y;g&&(z="try{"+z+"}catch(e){throw {filename:$filename,name:'Render Error',message:e.message,line:$line,source:"+b(c)+".split(/\\n/)[$line-1].replace(/^\\s+/,'')};}");try{var A=new Function("$data","$filename",z);return A.prototype=n,A}catch(B){throw B.temp="function anonymous($data,$filename) {"+z+"}",B}}var d=function(a,b){return"string"==typeof b?q(b,{filename:a}):g(a,b)};d.version="3.0.0",d.config=function(a,b){e[a]=b};var e=d.defaults={openTag:"<%",closeTag:"%>",escape:!0,cache:!0,compress:!1,parser:null},f=d.cache={};d.render=function(a,b){return q(a,b)};var g=d.renderFile=function(a,b){var c=d.get(a)||p({filename:a,name:"Render Error",message:"Template not found"});return b?c(b):c};d.get=function(a){var b;if(f[a])b=f[a];else if("object"==typeof document){var c=document.getElementById(a);if(c){var d=(c.value||c.innerHTML).replace(/^\s*|\s*$/g,"");b=q(d,{filename:a})}}return b};var h=function(a,b){return"string"!=typeof a&&(b=typeof a,"number"===b?a+="":a="function"===b?h(a.call(a)):""),a},i={"<":"<",">":">",'"':""","'":"'","&":"&"},j=function(a){return i[a]},k=function(a){return h(a).replace(/&(?![\w#]+;)|[<>"']/g,j)},l=Array.isArray||function(a){return"[object Array]"==={}.toString.call(a)},m=function(a,b){var c,d;if(l(a))for(c=0,d=a.length;d>c;c++)b.call(a,a[c],c,a);else for(c in a)b.call(a,a[c],c)},n=d.utils={$helpers:{},$include:g,$string:h,$escape:k,$each:m};d.helper=function(a,b){o[a]=b};var o=d.helpers=n.$helpers;d.onerror=function(a){var b="Template Error\n\n";for(var c in a)b+="<"+c+">\n"+a[c]+"\n\n";"object"==typeof console&&console.error(b)};var p=function(a){return d.onerror(a),function(){return"{Template Error}"}},q=d.compile=function(a,b){function d(c){try{return new i(c,h)+""}catch(d){return b.debug?p(d)():(b.debug=!0,q(a,b)(c))}}b=b||{};for(var g in e)void 0===b[g]&&(b[g]=e[g]);var h=b.filename;try{var i=c(a,b)}catch(j){return j.filename=h||"anonymous",j.name="Syntax Error",p(j)}return d.prototype=i.prototype,d.toString=function(){return i.toString()},h&&b.cache&&(f[h]=d),d},r=n.$each,s="break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined",t=/\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|\s*\.\s*[$\w\.]+/g,u=/[^\w$]+/g,v=new RegExp(["\\b"+s.replace(/,/g,"\\b|\\b")+"\\b"].join("|"),"g"),w=/^\d[^,]*|,\d[^,]*/g,x=/^,+|,+$/g,y=/^$|,+/;"function"==typeof define?define(function(){return d}):"undefined"!=typeof exports?module.exports=d:this.template=d}(); -------------------------------------------------------------------------------- /es5/cookie.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | //cookie操作对象 4 | var cookie = (function () { 5 | 6 | var document = window.document, 7 | encodeURIComponent = window.encodeURIComponent, 8 | decodeURIComponent = window.decodeURIComponent, 9 | toString = {}.toString, 10 | Date = window.Date; 11 | 12 | /** 13 | * 设置cookie函数 14 | * @param {string} key 键 15 | * @param {string} val 值 16 | * @param {Date|number} days 过期时间|过期天数 17 | * @param {number} hours 过期小时数 18 | */ 19 | function setItem(key, val, days, hours) { 20 | var str = key + '=' + encodeURIComponent(val); 21 | 22 | var expire; 23 | //days参数是一个日期 24 | if (toString.call(days) === '[object Date]') { 25 | expire = days; 26 | } 27 | //过期天数 28 | else if (typeof days === 'number') { 29 | expire = new Date(); 30 | expire.setDate(expire.getDate() + days); 31 | } 32 | //过期小时数 33 | else if (typeof hours === 'number') { 34 | expire = new Date(); 35 | expire.setHours(expire.getHours() + hours); 36 | } 37 | 38 | expire && (str += ';expires=' + expire.toUTCString()); 39 | document.cookie = str; 40 | } 41 | 42 | //获取 43 | function getItem(key) { 44 | var cookie = document.cookie, 45 | index = cookie.indexOf(key + '='); 46 | 47 | if (index !== -1) { 48 | var start = index + key.length + 1, 49 | end = cookie.indexOf(';', start); 50 | 51 | //最后一个 52 | end === -1 && (end = cookie.length); 53 | return decodeURIComponent(cookie.slice(start, end)); 54 | } 55 | } 56 | 57 | //清除 58 | function removeItem(key) { 59 | document.cookie = key + '=_;expires=' + new Date().toUTCString(); 60 | } 61 | 62 | return { 63 | setItem: setItem, 64 | getItem: getItem, 65 | removeItem: removeItem 66 | }; 67 | })(); 68 | 69 | 70 | //CommonJS 71 | if (typeof exports === 'object') { 72 | return module.exports = cookie; 73 | } 74 | 75 | //添加到全局 76 | window.cookie = cookie; 77 | 78 | })(window); -------------------------------------------------------------------------------- /es5/date.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 测试 6 | 7 | 10 | 11 | 12 |
13 | 14 |
15 | 16 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /es5/jq.validate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jq.validate.js 3 | * 验证插件 4 | */ 5 | (function (window, $) { 6 | 7 | var $doc = $(document); 8 | 9 | //格式验证对象 10 | var patrn = { 11 | tel : { 12 | txt: '手机', 13 | reg: /(^1[34578]\d{9}$)|(^(([0\+]\d{2,3})?(0\d{2,3}))(\d{7,8})(-(\d{3,}))?$)/ 14 | }, 15 | email : { 16 | txt: '邮箱', 17 | reg: /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/ 18 | }, 19 | idcard: { 20 | txt: '身份证', 21 | reg: /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{4}$/ 22 | } 23 | }; 24 | 25 | 26 | $.validate = function (opts) { 27 | opts = $.extend({}, $.validate.defaults, opts); 28 | 29 | //配置项 30 | var $inputs = opts.$inputs, 31 | rsType = opts.rsType, 32 | $msg = opts.$msg, 33 | validated = opts.validated, 34 | unValidated = opts.unValidated, 35 | isShowMsg = opts.isShowMsg, 36 | fieldNullable = opts.fieldNullable, 37 | isFocus = opts.isFocus; 38 | 39 | //验证不通过函数 40 | function onError(msg, $input) { 41 | //验证不通过回调 42 | typeof unValidated === 'function' && unValidated(msg); 43 | //显示验证信息 44 | isShowMsg && ($msg ? $msg.text(msg) : alert(msg)); 45 | //焦点 46 | isFocus && $input[0].focus(); 47 | $input.addClass('error'); 48 | } 49 | 50 | var rs, isRsObj = rsType === 'object'; 51 | //遍历输入元素 52 | for (var i = 0, len = $inputs.length; i < len; i++) { 53 | var $input = $inputs.eq(i), 54 | inputEl = $input[0], 55 | //优先读取data-value属性,否则表单元素读取value属性,否则读取text 56 | value = $input.filter('[data-value]').length > 0 ? $input.attr('data-value') : (isFormEl(inputEl) ? inputEl.value : $input.text()), 57 | type = $input.attr('type'), 58 | msg = $input.attr('data-msg'), 59 | field = inputEl.id || $input.attr('data-field'); 60 | 61 | //重置输入框样式 62 | $input.removeClass('error'); 63 | 64 | //非空验证(data-msg属性非空) 65 | if (msg && value === '') { 66 | return onError(msg + '不能为空', $input); 67 | } 68 | 69 | //格式验证 70 | var ptn = patrn[type]; 71 | if (ptn && !ptn.reg.test(value)) { 72 | return onError(ptn.txt + '格式无效', $input); 73 | } 74 | 75 | //如果字段不能为空时,值为空就跳过保存值 76 | if (!fieldNullable && value === '') { 77 | continue; 78 | } 79 | //保存值 80 | rs || (rs = isRsObj ? {} : []); 81 | isRsObj ? field && (rs[field] = value) : rs.push(value); 82 | } 83 | //验证通过回调 84 | typeof validated === 'function' && validated(rs); 85 | 86 | return rs; 87 | }; 88 | $.validate.defaults = { 89 | //输入元素 90 | $inputs : null, 91 | //结果类型(默认为对象,否则为数组) 92 | rsType : 'object', 93 | //显示信息元素 94 | $msg : null, 95 | //验证通过回调 96 | validated : null, 97 | //验证不通过回调 98 | unValidated : null, 99 | //是否显示提示信息 100 | isShowMsg : true, 101 | //字段可为空 102 | fieldNullable: true, 103 | //是否焦点(默认为移动端不焦点,pc端焦点) 104 | isFocus : !/(iPhone|iPod|android)/i.test(navigator.userAgent) 105 | }; 106 | //判断是否为表单元素函数 107 | var isFormEl = $.validate.isFormEl = function (el) { 108 | return /(select|input|textarea)/i.test(el.tagName); 109 | }; 110 | 111 | 112 | $.fn.validate = function (opts) { 113 | opts = $.extend({}, $.fn.validate.defaults, opts); 114 | 115 | //配置项 116 | var btnOkSel = opts.btnOkSel, 117 | inputSel = opts.inputSel; 118 | 119 | //每个元素执行 120 | return this.each(function () { 121 | 122 | //变量 123 | var $this = $(this), 124 | $inputs = $this.find(inputSel).not('.not'); 125 | 126 | //初始化函数 127 | function init() { 128 | 129 | //初始化事件 130 | initEvent(); 131 | } 132 | 133 | //初始化事件函数 134 | function initEvent() { 135 | 136 | //确定点击 137 | $doc.on('click', btnOkSel, function () { 138 | $.validate($.extend({}, opts, { 139 | $inputs: $inputs 140 | })); 141 | }); 142 | } 143 | 144 | 145 | //初始化 146 | init(); 147 | 148 | }); 149 | }; 150 | $.fn.validate.defaults = { 151 | //确定按钮选择器 152 | btnOkSel: '.btn_ok', 153 | //输入元素选择 154 | inputSel: 'input,select,textarea' 155 | }; 156 | 157 | })(window, $); -------------------------------------------------------------------------------- /es5/json2.js: -------------------------------------------------------------------------------- 1 | /* 2 | json2.js 3 | 2014-02-04 4 | 5 | Public Domain. 6 | 7 | NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 8 | 9 | See http://www.JSON.org/js.html 10 | 11 | 12 | This code should be minified before deployment. 13 | See http://javascript.crockford.com/jsmin.html 14 | 15 | USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO 16 | NOT CONTROL. 17 | 18 | 19 | This file creates a global JSON object containing two methods: stringify 20 | and parse. 21 | 22 | JSON.stringify(value, replacer, space) 23 | value any JavaScript value, usually an object or array. 24 | 25 | replacer an optional parameter that determines how object 26 | values are stringified for objects. It can be a 27 | function or an array of strings. 28 | 29 | space an optional parameter that specifies the indentation 30 | of nested structures. If it is omitted, the text will 31 | be packed without extra whitespace. If it is a number, 32 | it will specify the number of spaces to indent at each 33 | level. If it is a string (such as '\t' or ' '), 34 | it contains the characters used to indent at each level. 35 | 36 | This method produces a JSON text from a JavaScript value. 37 | 38 | When an object value is found, if the object contains a toJSON 39 | method, its toJSON method will be called and the result will be 40 | stringified. A toJSON method does not serialize: it returns the 41 | value represented by the name/value pair that should be serialized, 42 | or undefined if nothing should be serialized. The toJSON method 43 | will be passed the key associated with the value, and this will be 44 | bound to the value 45 | 46 | For example, this would serialize Dates as ISO strings. 47 | 48 | Date.prototype.toJSON = function (key) { 49 | function f(n) { 50 | // Format integers to have at least two digits. 51 | return n < 10 ? '0' + n : n; 52 | } 53 | 54 | return this.getUTCFullYear() + '-' + 55 | f(this.getUTCMonth() + 1) + '-' + 56 | f(this.getUTCDate()) + 'T' + 57 | f(this.getUTCHours()) + ':' + 58 | f(this.getUTCMinutes()) + ':' + 59 | f(this.getUTCSeconds()) + 'Z'; 60 | }; 61 | 62 | You can provide an optional replacer method. It will be passed the 63 | key and value of each member, with this bound to the containing 64 | object. The value that is returned from your method will be 65 | serialized. If your method returns undefined, then the member will 66 | be excluded from the serialization. 67 | 68 | If the replacer parameter is an array of strings, then it will be 69 | used to select the members to be serialized. It filters the results 70 | such that only members with keys listed in the replacer array are 71 | stringified. 72 | 73 | Values that do not have JSON representations, such as undefined or 74 | functions, will not be serialized. Such values in objects will be 75 | dropped; in arrays they will be replaced with null. You can use 76 | a replacer function to replace those with JSON values. 77 | JSON.stringify(undefined) returns undefined. 78 | 79 | The optional space parameter produces a stringification of the 80 | value that is filled with line breaks and indentation to make it 81 | easier to read. 82 | 83 | If the space parameter is a non-empty string, then that string will 84 | be used for indentation. If the space parameter is a number, then 85 | the indentation will be that many spaces. 86 | 87 | Example: 88 | 89 | text = JSON.stringify(['e', {pluribus: 'unum'}]); 90 | // text is '["e",{"pluribus":"unum"}]' 91 | 92 | 93 | text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); 94 | // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' 95 | 96 | text = JSON.stringify([new Date()], function (key, value) { 97 | return this[key] instanceof Date ? 98 | 'Date(' + this[key] + ')' : value; 99 | }); 100 | // text is '["Date(---current time---)"]' 101 | 102 | 103 | JSON.parse(text, reviver) 104 | This method parses a JSON text to produce an object or array. 105 | It can throw a SyntaxError exception. 106 | 107 | The optional reviver parameter is a function that can filter and 108 | transform the results. It receives each of the keys and values, 109 | and its return value is used instead of the original value. 110 | If it returns what it received, then the structure is not modified. 111 | If it returns undefined then the member is deleted. 112 | 113 | Example: 114 | 115 | // Parse the text. Values that look like ISO date strings will 116 | // be converted to Date objects. 117 | 118 | myData = JSON.parse(text, function (key, value) { 119 | var a; 120 | if (typeof value === 'string') { 121 | a = 122 | /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); 123 | if (a) { 124 | return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], 125 | +a[5], +a[6])); 126 | } 127 | } 128 | return value; 129 | }); 130 | 131 | myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { 132 | var d; 133 | if (typeof value === 'string' && 134 | value.slice(0, 5) === 'Date(' && 135 | value.slice(-1) === ')') { 136 | d = new Date(value.slice(5, -1)); 137 | if (d) { 138 | return d; 139 | } 140 | } 141 | return value; 142 | }); 143 | 144 | 145 | This is a reference implementation. You are free to copy, modify, or 146 | redistribute. 147 | */ 148 | 149 | /*jslint evil: true, regexp: true */ 150 | 151 | /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, 152 | call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, 153 | getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, 154 | lastIndex, length, parse, prototype, push, replace, slice, stringify, 155 | test, toJSON, toString, valueOf 156 | */ 157 | 158 | 159 | // Create a JSON object only if one does not already exist. We create the 160 | // methods in a closure to avoid creating global variables. 161 | 162 | if (typeof JSON !== 'object') { 163 | JSON = {}; 164 | } 165 | 166 | (function () { 167 | 'use strict'; 168 | 169 | function f(n) { 170 | // Format integers to have at least two digits. 171 | return n < 10 ? '0' + n : n; 172 | } 173 | 174 | if (typeof Date.prototype.toJSON !== 'function') { 175 | 176 | Date.prototype.toJSON = function () { 177 | 178 | return isFinite(this.valueOf()) 179 | ? this.getUTCFullYear() + '-' + 180 | f(this.getUTCMonth() + 1) + '-' + 181 | f(this.getUTCDate()) + 'T' + 182 | f(this.getUTCHours()) + ':' + 183 | f(this.getUTCMinutes()) + ':' + 184 | f(this.getUTCSeconds()) + 'Z' 185 | : null; 186 | }; 187 | 188 | String.prototype.toJSON = 189 | Number.prototype.toJSON = 190 | Boolean.prototype.toJSON = function () { 191 | return this.valueOf(); 192 | }; 193 | } 194 | 195 | var cx, 196 | escapable, 197 | gap, 198 | indent, 199 | meta, 200 | rep; 201 | 202 | 203 | function quote(string) { 204 | 205 | // If the string contains no control characters, no quote characters, and no 206 | // backslash characters, then we can safely slap some quotes around it. 207 | // Otherwise we must also replace the offending characters with safe escape 208 | // sequences. 209 | 210 | escapable.lastIndex = 0; 211 | return escapable.test(string) ? '"' + string.replace(escapable, function (a) { 212 | var c = meta[a]; 213 | return typeof c === 'string' 214 | ? c 215 | : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 216 | }) + '"' : '"' + string + '"'; 217 | } 218 | 219 | 220 | function str(key, holder) { 221 | 222 | // Produce a string from holder[key]. 223 | 224 | var i, // The loop counter. 225 | k, // The member key. 226 | v, // The member value. 227 | length, 228 | mind = gap, 229 | partial, 230 | value = holder[key]; 231 | 232 | // If the value has a toJSON method, call it to obtain a replacement value. 233 | 234 | if (value && typeof value === 'object' && 235 | typeof value.toJSON === 'function') { 236 | value = value.toJSON(key); 237 | } 238 | 239 | // If we were called with a replacer function, then call the replacer to 240 | // obtain a replacement value. 241 | 242 | if (typeof rep === 'function') { 243 | value = rep.call(holder, key, value); 244 | } 245 | 246 | // What happens next depends on the value's type. 247 | 248 | switch (typeof value) { 249 | case 'string': 250 | return quote(value); 251 | 252 | case 'number': 253 | 254 | // JSON numbers must be finite. Encode non-finite numbers as null. 255 | 256 | return isFinite(value) ? String(value) : 'null'; 257 | 258 | case 'boolean': 259 | case 'null': 260 | 261 | // If the value is a boolean or null, convert it to a string. Note: 262 | // typeof null does not produce 'null'. The case is included here in 263 | // the remote chance that this gets fixed someday. 264 | 265 | return String(value); 266 | 267 | // If the type is 'object', we might be dealing with an object or an array or 268 | // null. 269 | 270 | case 'object': 271 | 272 | // Due to a specification blunder in ECMAScript, typeof null is 'object', 273 | // so watch out for that case. 274 | 275 | if (!value) { 276 | return 'null'; 277 | } 278 | 279 | // Make an array to hold the partial results of stringifying this object value. 280 | 281 | gap += indent; 282 | partial = []; 283 | 284 | // Is the value an array? 285 | 286 | if (Object.prototype.toString.apply(value) === '[object Array]') { 287 | 288 | // The value is an array. Stringify every element. Use null as a placeholder 289 | // for non-JSON values. 290 | 291 | length = value.length; 292 | for (i = 0; i < length; i += 1) { 293 | partial[i] = str(i, value) || 'null'; 294 | } 295 | 296 | // Join all of the elements together, separated with commas, and wrap them in 297 | // brackets. 298 | 299 | v = partial.length === 0 300 | ? '[]' 301 | : gap 302 | ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' 303 | : '[' + partial.join(',') + ']'; 304 | gap = mind; 305 | return v; 306 | } 307 | 308 | // If the replacer is an array, use it to select the members to be stringified. 309 | 310 | if (rep && typeof rep === 'object') { 311 | length = rep.length; 312 | for (i = 0; i < length; i += 1) { 313 | if (typeof rep[i] === 'string') { 314 | k = rep[i]; 315 | v = str(k, value); 316 | if (v) { 317 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 318 | } 319 | } 320 | } 321 | } else { 322 | 323 | // Otherwise, iterate through all of the keys in the object. 324 | 325 | for (k in value) { 326 | if (Object.prototype.hasOwnProperty.call(value, k)) { 327 | v = str(k, value); 328 | if (v) { 329 | partial.push(quote(k) + (gap ? ': ' : ':') + v); 330 | } 331 | } 332 | } 333 | } 334 | 335 | // Join all of the member texts together, separated with commas, 336 | // and wrap them in braces. 337 | 338 | v = partial.length === 0 339 | ? '{}' 340 | : gap 341 | ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' 342 | : '{' + partial.join(',') + '}'; 343 | gap = mind; 344 | return v; 345 | } 346 | } 347 | 348 | // If the JSON object does not yet have a stringify method, give it one. 349 | 350 | if (typeof JSON.stringify !== 'function') { 351 | escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; 352 | meta = { // table of character substitutions 353 | '\b': '\\b', 354 | '\t': '\\t', 355 | '\n': '\\n', 356 | '\f': '\\f', 357 | '\r': '\\r', 358 | '"' : '\\"', 359 | '\\': '\\\\' 360 | }; 361 | JSON.stringify = function (value, replacer, space) { 362 | 363 | // The stringify method takes a value and an optional replacer, and an optional 364 | // space parameter, and returns a JSON text. The replacer can be a function 365 | // that can replace values, or an array of strings that will select the keys. 366 | // A default replacer method can be provided. Use of the space parameter can 367 | // produce text that is more easily readable. 368 | 369 | var i; 370 | gap = ''; 371 | indent = ''; 372 | 373 | // If the space parameter is a number, make an indent string containing that 374 | // many spaces. 375 | 376 | if (typeof space === 'number') { 377 | for (i = 0; i < space; i += 1) { 378 | indent += ' '; 379 | } 380 | 381 | // If the space parameter is a string, it will be used as the indent string. 382 | 383 | } else if (typeof space === 'string') { 384 | indent = space; 385 | } 386 | 387 | // If there is a replacer, it must be a function or an array. 388 | // Otherwise, throw an error. 389 | 390 | rep = replacer; 391 | if (replacer && typeof replacer !== 'function' && 392 | (typeof replacer !== 'object' || 393 | typeof replacer.length !== 'number')) { 394 | throw new Error('JSON.stringify'); 395 | } 396 | 397 | // Make a fake root object containing our value under the key of ''. 398 | // Return the result of stringifying the value. 399 | 400 | return str('', {'': value}); 401 | }; 402 | } 403 | 404 | 405 | // If the JSON object does not yet have a parse method, give it one. 406 | 407 | if (typeof JSON.parse !== 'function') { 408 | cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; 409 | JSON.parse = function (text, reviver) { 410 | 411 | // The parse method takes a text and an optional reviver function, and returns 412 | // a JavaScript value if the text is a valid JSON text. 413 | 414 | var j; 415 | 416 | function walk(holder, key) { 417 | 418 | // The walk method is used to recursively walk the resulting structure so 419 | // that modifications can be made. 420 | 421 | var k, v, value = holder[key]; 422 | if (value && typeof value === 'object') { 423 | for (k in value) { 424 | if (Object.prototype.hasOwnProperty.call(value, k)) { 425 | v = walk(value, k); 426 | if (v !== undefined) { 427 | value[k] = v; 428 | } else { 429 | delete value[k]; 430 | } 431 | } 432 | } 433 | } 434 | return reviver.call(holder, key, value); 435 | } 436 | 437 | 438 | // Parsing happens in four stages. In the first stage, we replace certain 439 | // Unicode characters with escape sequences. JavaScript handles many characters 440 | // incorrectly, either silently deleting them, or treating them as line endings. 441 | 442 | text = String(text); 443 | cx.lastIndex = 0; 444 | if (cx.test(text)) { 445 | text = text.replace(cx, function (a) { 446 | return '\\u' + 447 | ('0000' + a.charCodeAt(0).toString(16)).slice(-4); 448 | }); 449 | } 450 | 451 | // In the second stage, we run the text against regular expressions that look 452 | // for non-JSON patterns. We are especially concerned with '()' and 'new' 453 | // because they can cause invocation, and '=' because it can cause mutation. 454 | // But just to be safe, we want to reject all unexpected forms. 455 | 456 | // We split the second stage into 4 regexp operations in order to work around 457 | // crippling inefficiencies in IE's and Safari's regexp engines. First we 458 | // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we 459 | // replace all simple value tokens with ']' characters. Third, we delete all 460 | // open brackets that follow a colon or comma or that begin the text. Finally, 461 | // we look to see that the remaining characters are only whitespace or ']' or 462 | // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. 463 | 464 | if (/^[\],:{}\s]*$/ 465 | .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') 466 | .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') 467 | .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { 468 | 469 | // In the third stage we use the eval function to compile the text into a 470 | // JavaScript structure. The '{' operator is subject to a syntactic ambiguity 471 | // in JavaScript: it can begin a block or an object literal. We wrap the text 472 | // in parens to eliminate the ambiguity. 473 | 474 | j = eval('(' + text + ')'); 475 | 476 | // In the optional fourth stage, we recursively walk the new structure, passing 477 | // each name/value pair to a reviver function for possible transformation. 478 | 479 | return typeof reviver === 'function' 480 | ? walk({'': j}, '') 481 | : j; 482 | } 483 | 484 | // If the text is not JSON parseable, then a SyntaxError is thrown. 485 | 486 | throw new SyntaxError('JSON.parse'); 487 | }; 488 | } 489 | }()); 490 | -------------------------------------------------------------------------------- /es5/jsonp.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | // 跨域请求对象 4 | var jsonp = (function () { 5 | 6 | var document = window.document, 7 | encodeURIComponent = window.encodeURIComponent, 8 | bodyEl = document.body, 9 | headEl = document.head, 10 | JSON = window.JSON; 11 | 12 | // 获取uid函数 13 | var getUid = (function () { 14 | var uid = 0; 15 | return function () { 16 | return ++uid; 17 | } 18 | })(); 19 | 20 | // 加载js函数 21 | function getScript(url, fn) { 22 | var isJs = /(\.js)$/.test(url), 23 | scriptEl = document.createElement('script'); 24 | 25 | // type 26 | scriptEl.type = 'text/javascript'; 27 | 28 | // onload 29 | scriptEl.onload = function () { 30 | typeof fn === 'function' && fn(); 31 | !isJs && headEl.removeChild(scriptEl); 32 | }; 33 | 34 | // 请求 35 | scriptEl.src = url; 36 | headEl.appendChild(scriptEl); 37 | } 38 | 39 | // 对象转查询字符串函数 40 | function obj2str(obj) { 41 | var array = []; 42 | for (var p in obj) { 43 | array.push(p + '=' + encodeURIComponent(obj[p])); 44 | } 45 | return array.join('&'); 46 | } 47 | 48 | // 扩展函数 49 | var extend = (function () { 50 | var tmpArray = [], 51 | forEach = tmpArray.forEach, 52 | slice = tmpArray.slice; 53 | 54 | return function (obj) { 55 | // $.extend({}, defaults[, obj]) 56 | forEach.call(slice.call(arguments, 1), function (item) { 57 | for (var p in item) { 58 | obj[p] = item[p]; 59 | } 60 | }); 61 | return obj; 62 | }; 63 | })(); 64 | 65 | // 回调函数 66 | function callback(rs, opts) { 67 | //回调函数 68 | var cb = opts.callback; 69 | typeof cb === 'function' && cb(rs); 70 | 71 | //成功或失败回调函数 72 | var success = opts.success, 73 | error = opts.error; 74 | rs.status === 200 ? typeof success === 'function' && success(rs.data) : typeof error === 'function' && error(rs.msg); 75 | } 76 | 77 | 78 | // get数据函数 79 | function get(opts) { 80 | opts = extend({}, get.defaults, opts); 81 | 82 | var cbName = 'jsonpcb' + getUid(); 83 | 84 | // 将回调函数添加到全局变量 85 | window[cbName] = function (rs) { 86 | // 回调 87 | callback(rs, opts); 88 | 89 | // 释放回调函数 90 | window[cbName] = null; 91 | }; 92 | 93 | // url中添加callback 94 | var url = opts.url; 95 | url += (url.indexOf('?') < 0 ? '?' : '&') + 'callback=' + cbName; 96 | 97 | //拼接data 98 | var data = opts.data; 99 | data && (url += '&' + obj2str(data)); 100 | 101 | getScript(url); 102 | } 103 | 104 | // get数据默认配置项 105 | get.defaults = {}; 106 | 107 | 108 | // push数据函数 109 | var push = (function () { 110 | // 回调函数对象 111 | var msgcb = {}; 112 | 113 | // 绑定消息事件 114 | window.addEventListener('message', function (evt) { 115 | var data = JSON.parse(evt.data); 116 | msgcb[data.id](data.rs); 117 | }, false); 118 | 119 | return function (opts) { 120 | opts = extend({}, push.defaults, opts); 121 | 122 | // iframe元素 123 | var ifrId = 'jsonpifr' + getUid(), ifrEl, 124 | tmpEl = document.createElement('div'); 125 | tmpEl.innerHTML = ''; 126 | ifrEl = tmpEl.childNodes[0]; 127 | bodyEl.appendChild(ifrEl); 128 | 129 | // 响应函数 130 | msgcb[ifrId] = function (rs) { 131 | // 回调 132 | callback(JSON.parse(rs), opts); 133 | 134 | // 释放回调函数 135 | msgcb[ifrId] = null; 136 | 137 | // 删除节点 138 | bodyEl.removeChild(ifrEl); 139 | !formId && bodyEl.removeChild(formEl); 140 | }; 141 | 142 | // form元素 143 | var formId = opts.formId, formEl; 144 | // 带file的form提交 145 | if (formId) { 146 | formEl = document.getElementById(formId); 147 | formEl.enctype = 'multipart/form-data'; 148 | } 149 | else { 150 | formEl = document.createElement('form'); 151 | formEl.style.display = 'none'; 152 | } 153 | 154 | // 请求的url 155 | var url = opts.url; 156 | formEl.action = url + (url.indexOf('?') !== -1 ? '&' : '?') + 'jsonp=' + ifrId; 157 | formEl.method = opts.method; 158 | formEl.target = ifrId; 159 | //遍历data,加到form 160 | var data = opts.data; 161 | for (var p in data) { 162 | var inputEl = document.createElement('input'); 163 | 164 | inputEl.type = 'hidden'; 165 | inputEl.name = p; 166 | inputEl.value = data[p]; 167 | formEl.appendChild(inputEl); 168 | } 169 | 170 | // 提交 171 | !formId && bodyEl.appendChild(formEl); 172 | formEl.submit(); 173 | }; 174 | 175 | })(); 176 | 177 | //push数据默认配置项 178 | push.defaults = { 179 | method: 'POST' 180 | }; 181 | 182 | 183 | return { 184 | getScript: getScript, 185 | get: get, 186 | push: push 187 | }; 188 | 189 | })(); 190 | 191 | 192 | //CommonJS 193 | if (typeof exports === 'object') { 194 | return module.exports = jsonp; 195 | } 196 | 197 | //添加到全局 198 | window.jsonp = jsonp; 199 | 200 | })(window); -------------------------------------------------------------------------------- /es5/jtool.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | //文档对象 3 | var document = window.document, 4 | //location 5 | location = window.location, 6 | //是否ie6 7 | isIE6 = !-[1,] && !window.XMLHttpRequest, 8 | //是否为ie8- 9 | isLteIE8 = !document.addEventListener; 10 | 11 | //log函数 12 | function log(o) { 13 | try { 14 | console.log(o); 15 | } catch (e) { 16 | } 17 | } 18 | 19 | //是否为函数 20 | function isFunction(fn) { 21 | return typeof fn === 'function'; 22 | } 23 | 24 | //显示信息函数 25 | function showMsg(o, msgEl) { 26 | msgEl ? (msgEl.innerHTML = o) : alert(o); 27 | } 28 | 29 | //合并配置项函数 30 | function mergeOpts(opts, defaults) { 31 | //合并 32 | for (var p in defaults) { 33 | !opts.hasOwnProperty(p) && (opts[p] = defaults[p]); 34 | } 35 | } 36 | 37 | //异步加载js函数 38 | function loadJs(opts) { 39 | var url = opts.url, 40 | fn = opts.fn, 41 | //是否js文件 42 | isJs = /(\.js)$/.exec(url), 43 | script = document.createElement('script'); 44 | 45 | script.type = 'text/javascript'; 46 | if (script.readyState) { 47 | script.onreadystatechange = function () { 48 | if (script.readyState == 'loaded' || script.readyState == 'complete') { 49 | script.onreadystatechange = null; 50 | isFunction(fn) && fn(); 51 | !isJs && script.parentNode.removeChild(script); 52 | } 53 | }; 54 | } 55 | else { 56 | script.onload = function () { 57 | isFunction(fn) && fn(); 58 | !isJs && script.parentNode.removeChild(script); 59 | }; 60 | } 61 | script.src = url; 62 | document.getElementsByTagName('head')[0].appendChild(script); 63 | } 64 | 65 | //跨域请求函数 66 | function jsonp(url, fn) { 67 | loadJs({ 68 | url: url, 69 | fn : fn 70 | }); 71 | } 72 | 73 | 74 | //工具类属性或方法 75 | var jtool = (function () { 76 | var jtool, 77 | guid = 0; 78 | 79 | //pv监测 80 | function pvCheck(tab) { 81 | var url = 'http://js.app.gd.sohu.com:8080/pv.gif?', 82 | host = location.host, 83 | href = location.href, 84 | referrer = document.referrer; 85 | 86 | referrer.length === 0 && (referrer = 'null'); 87 | href = href + '&tab=' + encodeURIComponent(tab); 88 | url += (host + '|' + href + '|' + referrer); 89 | 90 | loadJs({ 91 | url: url 92 | }); 93 | } 94 | 95 | //获取参数 96 | function getQueryString(key) { 97 | key = key.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]'); 98 | 99 | var regex = new RegExp('[\\?&]' + key + '=([^&#]*)'), 100 | qs = regex.exec(location.href); 101 | 102 | return (qs == null ? '' : qs[1]); 103 | } 104 | 105 | //表单验证 106 | function formValid(opts, isNoFocus) { 107 | var $items, 108 | $context = opts.contextEl, 109 | msgEl = opts.msgEl, 110 | rs = { 111 | status: 1, 112 | data : {} 113 | }, 114 | data = rs.data; 115 | 116 | if (!($context && $context.html && $context.length > 0)) { 117 | log('context为空,或不为jq对象,或jq对象为空'); 118 | return { 119 | status: -1 120 | }; 121 | } 122 | 123 | //遍历输入项 124 | $items = $context.find('input,textarea,select').not('.not'); 125 | for (var i = 0, len = $items.length; i < len; i++) { 126 | var $item = $items.eq(i), 127 | item = $item[0], 128 | field = $item.attr('data-field') || item.id, 129 | msg = $item.attr('data-msg') || field, 130 | itemValue = item.value; 131 | 132 | //非空验证 133 | if ($item.hasClass('notnull') && itemValue === '') { 134 | showMsg(item.nodeName.toLowerCase() === 'select' ? ('请选择' + msg) : (msg + '不能为空'), msgEl); 135 | rs.status = -1; 136 | !isNoFocus && item.focus(); 137 | break; 138 | } 139 | 140 | //电话验证 141 | if (field === 'tel') { 142 | var patrnPhone = /^(([0\+]\d{2,3}-)?(0\d{2,3})-)(\d{7,8})(-(\d{3,}))?$/, 143 | patrnMobile = /^1[358]\d{9}$/; 144 | 145 | if (!(patrnPhone.exec(itemValue) || patrnMobile.exec(itemValue))) { 146 | showMsg(msg + '格式无效', msgEl); 147 | rs.status = -1; 148 | !isNoFocus && item.focus(); 149 | break; 150 | } 151 | } 152 | 153 | //email验证 154 | if (field === 'email') { 155 | var patrnEmail = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/; 156 | 157 | if (!patrnEmail.exec(itemValue)) { 158 | rs.status = -1; 159 | showMsg(msg + '格式无效', msgEl); 160 | !isNoFocus && item.focus(); 161 | break; 162 | } 163 | } 164 | 165 | data[field] = itemValue; 166 | } 167 | return rs; 168 | } 169 | 170 | //其他平台登陆 171 | function otherLogin(provider, ru) { 172 | var url = 'http://passport.sohu.com/openlogin/request.action?provider=' + provider + '&appid=1030&hun=1&ru=' + (ru || location.href); 173 | location.href = url; 174 | } 175 | 176 | //刷新页脚 177 | function refreshPager(opts) { 178 | //$pager 179 | var $pager = opts.$pager, 180 | //页码数据 181 | pages = opts.pages, 182 | //总记录数 183 | sum = pages.sum, 184 | //总页数 185 | maxpage = pages.maxpage, 186 | //页码 187 | page = pages.page, 188 | //分页数据 189 | pagerData = opts.pagerData, 190 | //刷新列表 191 | refreshList = opts.refreshList; 192 | 193 | if (maxpage > 1) { 194 | var array = []; 195 | //总记录数 196 | array.push('共' + sum + '条'); 197 | //上一页 198 | if (page != 1) { 199 | array.push('上一页'); 200 | } 201 | //计算分页页码 202 | var i, len; 203 | if (page < 7) { 204 | i = 0; 205 | len = maxpage >= 10 ? 10 : maxpage; 206 | } 207 | else { 208 | if (maxpage - page > 4) { 209 | i = page - 6; 210 | len = page + 4; 211 | } 212 | else { 213 | i = maxpage - 10; 214 | i < 0 && (i = 0); 215 | len = maxpage; 216 | } 217 | } 218 | //首页 219 | if (i > 0) { 220 | array.push('1 ...'); 221 | } 222 | //页码 223 | for (; i < len; i++) { 224 | var index = i + 1, 225 | str = index == page ? ' class="selected"' : ''; 226 | array.push('' + index + ''); 227 | } 228 | //尾页 229 | if (maxpage > len) { 230 | array.push('... ' + maxpage + ''); 231 | } 232 | //下一页 233 | if (page != maxpage) { 234 | array.push('下一页'); 235 | } 236 | 237 | //页码点击事件 238 | $pager.html(array.join('')).fadeIn().find('a').bind('click', function () { 239 | var page = this.getAttribute('data-page'); 240 | switch (page) { 241 | case 'prev': 242 | { 243 | pagerData.page--; 244 | break; 245 | } 246 | case 'next': 247 | { 248 | pagerData.page++; 249 | break; 250 | } 251 | default: 252 | { 253 | pagerData.page = +page; 254 | } 255 | } 256 | refreshList(); 257 | }); 258 | } 259 | 260 | } 261 | 262 | //获取flash对象函数 263 | function getFlashEl(flashId) { 264 | if (navigator.appName.indexOf('Micosoft') !== -1) { 265 | return document[flashId]; 266 | } 267 | else { 268 | return document.embeds[flashId] || window[flashId]; 269 | } 270 | } 271 | 272 | 273 | //初始化对象 274 | jtool = { 275 | //1.info 276 | constructor: 'jtool', 277 | ver : '1.0', 278 | 279 | //2.属性 280 | //是否ie 281 | isLteIE8: isLteIE8, 282 | //是否ie6 283 | isIE6 : isIE6, 284 | 285 | //3.方法 286 | //是否为函数 287 | isFunction : isFunction, 288 | //显示信息函数 289 | showMsg : showMsg, 290 | //合并配置项函数 291 | mergeOpts : mergeOpts, 292 | //异步加载js 293 | loadJs : loadJs, 294 | //跨域请求 295 | jsonp : jsonp, 296 | //pv监测 297 | pvCheck : pvCheck, 298 | //获取参数 299 | getQueryString: getQueryString, 300 | //表单验证 301 | formValid : formValid, 302 | //其他平台登陆 303 | otherLogin : otherLogin, 304 | //刷新页脚 305 | refreshPager : refreshPager, 306 | //获取flash对象函数 307 | getFlashEl : getFlashEl, 308 | //获取guid函数 309 | getGuid : function () { 310 | return guid++; 311 | } 312 | }; 313 | 314 | //返回对象 315 | return jtool; 316 | 317 | })(); 318 | 319 | 320 | //数据请求类 321 | jtool.proxy = (function () { 322 | var proxy, pushData; 323 | 324 | //初始化对象 325 | proxy = { 326 | //状态对应信息 327 | statusMsg: { 328 | 100: '正常', 329 | 101: '执行异常', 102: '参数有误', 330 | 201: '只能通过内部访问', 202: '接口关闭', 331 | 301: '接口授权码有误', 302: '接口过期', 332 | 401: '当前用户未登录访问', 402: '当前用户未授权访问', 333 | 501: '电话号码已存在', 502: '投票次数已用完' 334 | }, 335 | //默认配置 336 | defaults : { 337 | method : 'get', 338 | isShowMsg: false, 339 | ru : location.protocol + '//' + location.host + '/static/v3/jtool.html' 340 | } 341 | }; 342 | 343 | //提交数据函数 344 | pushData = (function () { 345 | var statusMsg = proxy.statusMsg; 346 | 347 | //get 348 | function get(opts) { 349 | //请求地址 350 | var url = opts.url, 351 | //传输数据 352 | data = opts.data, 353 | //是否显示信息 354 | isShowMsg = opts.isShowMsg, 355 | //显示消息的元素 356 | msgEl = opts.msgEl, 357 | //正常返回时回调函数 358 | success = opts.success, 359 | //异常返回时回调函数 360 | error = opts.error, 361 | //回调函数(成功或者失败都调用) 362 | callback = opts.callback, 363 | //接口验证标识 364 | code = opts.code, 365 | //uid 366 | uid = jtool.getGuid(), 367 | //接收结果的全局变量名 368 | rsName = 'jtoolrs' + uid; 369 | 370 | //添加vname参数 371 | url += (url.indexOf('?') === -1 ? '?' : '&') + 'vname=' + rsName; 372 | 373 | //将数据拼接成参数 374 | for (var p in data) { 375 | url += '&' + p + '=' + encodeURIComponent(data[p]); 376 | } 377 | 378 | //添加code参数 379 | code && (url += '&code=' + code); 380 | 381 | //请求数据 382 | jsonp(url, function () { 383 | var rs = window[rsName], 384 | status = +rs.status; 385 | 386 | //判断返回结果 387 | switch (status) { 388 | //正常返回 389 | case 100: 390 | { 391 | isFunction(success) && success(rs); 392 | break; 393 | } 394 | //其他情况 395 | default: 396 | { 397 | isShowMsg && showMsg(statusMsg[status], msgEl); 398 | isFunction(error) && error(rs); 399 | } 400 | } 401 | //回调 402 | isFunction(callback) && callback(rs); 403 | //请求完成后触发 404 | var onEnd = opts.onEnd; 405 | isFunction(onEnd) && onEnd(); 406 | 407 | //释放全局变量 408 | try { 409 | window[rsName] = null; 410 | delete window[rsName]; 411 | } 412 | catch (e) { 413 | } 414 | }); 415 | } 416 | 417 | //post 418 | function post(opts) { 419 | //请求地址 420 | var url = opts.url, 421 | //传输数据 422 | data = opts.data, 423 | //是否显示信息 424 | isShowMsg = opts.isShowMsg, 425 | //显示消息的元素 426 | msgEl = opts.msgEl, 427 | //正常返回时回调函数 428 | success = opts.success, 429 | //异常返回时回调函数 430 | error = opts.error, 431 | //回调函数(成功或者失败都调用) 432 | callback = opts.callback, 433 | //接口验证标识 434 | code = opts.code, 435 | //处理后回路路径 436 | ru = opts.ru, 437 | //form元素id 438 | formId = opts.formId, 439 | //uid 440 | uid = jtool.getGuid(), 441 | //回调函数名 442 | callbackName = 'jtoolcb' + uid, 443 | //iframe元素id 444 | ifrId = 'jtoolifr' + uid, 445 | //iframe元素 446 | ifrEl, 447 | //form元素 448 | formEl = formId ? document.getElementById(formId) : formEl = document.createElement('form'), 449 | //body元素 450 | body = document.body; 451 | 452 | 453 | //添加ru的callback参数 454 | ru += (ru.indexOf('?') === -1 ? '?' : '&') + 'callback=' + callbackName; 455 | 456 | //添加ru参数 457 | url += (url.indexOf('?') === -1 ? '?' : '&') + 'ru=' + ru; 458 | 459 | //添加code参数 460 | code && (url += '&code=' + code); 461 | 462 | //iframe 463 | if (isLteIE8) { 464 | ifrEl = document.createElement(''); 465 | //ie6,7里通过ifrEl.name设置属性会变成submitName属性,为解决这一bug,故分两个版本 466 | } 467 | else { 468 | ifrEl = document.createElement('iframe'); 469 | ifrEl.id = ifrId; 470 | ifrEl.name = ifrId; 471 | ifrEl.style.display = 'none'; 472 | } 473 | //添加dom 474 | body.appendChild(ifrEl); 475 | 476 | //form 477 | formEl.action = url; 478 | formEl.method = 'post'; 479 | formEl.target = ifrId; 480 | !formId && (formEl.style.display = 'none'); 481 | 482 | //遍历data,并加到form表单域 483 | for (var p in data) { 484 | if (data.hasOwnProperty(p)) { 485 | var txtEl = document.createElement('input'); 486 | 487 | txtEl.type = 'hidden'; 488 | txtEl.name = p; 489 | txtEl.value = data[p]; 490 | formEl.appendChild(txtEl); 491 | } 492 | } 493 | 494 | //添加dom 495 | !formId && body.appendChild(formEl);//必须将form添加到html里,否则在ie里将出现"无操作权限" 496 | //提交 497 | formEl.submit(); 498 | 499 | //回调函数 500 | window[callbackName] = function (rs) { 501 | var status = +rs.status; 502 | switch (status) { 503 | //正常返回 504 | case 100: 505 | { 506 | isFunction(success) && success(rs); 507 | break; 508 | } 509 | //特殊状态901 510 | case 901: 511 | { 512 | setTimeout(function () { 513 | post(opts); 514 | }, 50); 515 | break; 516 | } 517 | //其他情况 518 | default: 519 | { 520 | isShowMsg && showMsg(statusMsg[status], msgEl); 521 | isFunction(error) && error(rs); 522 | } 523 | } 524 | 525 | //回调 526 | isFunction(callback) && callback(rs); 527 | //请求完成后触发 528 | var onEnd = opts.onEnd; 529 | isFunction(onEnd) && onEnd(); 530 | 531 | //释放全局变量 532 | try { 533 | window[callbackName] = null; 534 | delete window[callbackName]; 535 | } 536 | catch (e) { 537 | } 538 | 539 | //移除节点 540 | ifrEl.parentNode.removeChild(ifrEl); 541 | !formId && formEl.parentNode.removeChild(formEl); 542 | }; 543 | } 544 | 545 | //返回函数 546 | return function (opts, defaults) { 547 | //初始化一个空对象 548 | !opts && (opts = {}); 549 | 550 | //与小默认配置合并配置项 551 | mergeOpts(opts, defaults); 552 | 553 | //与大默认配置合并配置项 554 | mergeOpts(opts, proxy.defaults); 555 | 556 | //请求前触发 557 | var onStart = opts.onStart; 558 | isFunction(onStart) && onStart(); 559 | 560 | //get或者post 561 | setTimeout(function () { 562 | opts.method === 'get' ? get(opts) : post(opts); 563 | }, isIE6 ? (jtool.getGuid() * 10) : 0); 564 | }; 565 | 566 | })(); 567 | 568 | 569 | //扩展属性 570 | //提交数据 571 | proxy.pushData = pushData; 572 | 573 | //通行证 574 | proxy.passport = (function () { 575 | var defaults = { 576 | api : 'http://app.gd.sohu.com/minisite/public/passport/20140220/', 577 | code: 'b6e569482459b0f6691302ecc67c4a85' 578 | }; 579 | 580 | return { 581 | //检测 582 | check: function (opts) { 583 | defaults.method = 'get'; 584 | defaults.url = defaults.api + 'get.php?act=check'; 585 | 586 | pushData(opts, defaults); 587 | }, 588 | 589 | //登陆 590 | login: function (opts) { 591 | defaults.method = 'post'; 592 | defaults.url = defaults.api + 'put.php?act=login'; 593 | 594 | pushData(opts, defaults); 595 | }, 596 | 597 | //退出 598 | logout: function (opts) { 599 | defaults.method = 'get'; 600 | defaults.url = 'http://app.gd.sohu.com/minisite/SohuPassport/logout.php'; 601 | 602 | pushData(opts, defaults); 603 | }, 604 | 605 | //资料读取 606 | viewdata: function (opts) { 607 | defaults.method = 'get'; 608 | defaults.url = defaults.api + 'get.php?act=view'; 609 | 610 | pushData(opts, defaults); 611 | }, 612 | 613 | //资料填写 614 | filldata: function (opts) { 615 | defaults.method = 'post'; 616 | defaults.url = defaults.api + 'put.php?act=view'; 617 | 618 | pushData(opts, defaults); 619 | } 620 | }; 621 | 622 | })(); 623 | 624 | //内部用户 625 | proxy.sohuInc = (function () { 626 | var defaults = { 627 | api : 'http://app.gzsas.sohu.com/minisite/public/sohu-inc/20140218/', 628 | code: 'b6e569482459b0f6691302ecc67c4a85' 629 | }; 630 | 631 | return { 632 | //检测 633 | check: function (opts) { 634 | defaults.method = 'get'; 635 | defaults.url = defaults.api + 'get.php?act=check'; 636 | 637 | pushData(opts, defaults); 638 | }, 639 | 640 | //登陆 641 | login: function (opts) { 642 | defaults.method = 'post'; 643 | defaults.url = defaults.api + 'put.php?act=login'; 644 | 645 | pushData(opts, defaults); 646 | }, 647 | 648 | //退出 649 | logout: function (opts) { 650 | defaults.method = 'get'; 651 | defaults.url = defaults.api + 'put.php?act=logout'; 652 | 653 | pushData(opts, defaults); 654 | } 655 | }; 656 | 657 | })(); 658 | 659 | //图片处理 660 | proxy.pic = (function () { 661 | var defaults = { 662 | code: 'b6e569482459b0f6691302ecc67c4a85', 663 | api : 'http://app.gd.sohu.com/minisite/public/pic/' 664 | }; 665 | 666 | return { 667 | //上传 668 | upload: function (opts) { 669 | defaults.method = 'post'; 670 | defaults.url = defaults.api + 'put.php?act=upload'; 671 | 672 | pushData(opts, defaults); 673 | }, 674 | 675 | //读取(比较特殊,返回的是一个图片链接) 676 | view: function (opts) { 677 | var data, 678 | code = defaults.code, 679 | url = defaults.api + 'get.php?act=show'; 680 | 681 | !opts && (opts = {}); 682 | 683 | //加code参数 684 | code && (url += '&code=' + code); 685 | 686 | //加传入参数 687 | data = opts.data; 688 | for (var p in opts.data) { 689 | url += '&' + p + '=' + data[p]; 690 | } 691 | 692 | return url; 693 | }, 694 | 695 | //旋转 696 | rotate: function (opts) { 697 | defaults.method = 'get'; 698 | defaults.url = defaults.api + 'get.php?act=rotate'; 699 | 700 | pushData(opts, defaults); 701 | } 702 | }; 703 | 704 | })(); 705 | 706 | //获奖信息 707 | proxy.lottery = (function () { 708 | var defaults = { 709 | code: 'aa1c9153608a7755b7c20e97c0eade27', 710 | api : 'http://app.gd.sohu.com/minisite/public/lottery/20140227/' 711 | }; 712 | 713 | return { 714 | //获奖名单 715 | list: function (opts) { 716 | defaults.method = 'get'; 717 | defaults.url = defaults.api + 'get.php?act=list'; 718 | 719 | pushData(opts, defaults); 720 | } 721 | }; 722 | })(); 723 | 724 | 725 | //返回对象 726 | return proxy; 727 | })(); 728 | 729 | 730 | //flash数据请求类 731 | jtool.flashProxy = (function () { 732 | var flashProxy, flashEl, 733 | proxy = jtool.proxy; 734 | 735 | //flash就绪调用函数 736 | function flashReady(flashId) { 737 | flashEl = jtool.getFlashEl(flashId); 738 | } 739 | 740 | //数据交互函数 741 | function pushData(opts) { 742 | proxy.pushData({ 743 | url : opts.url, 744 | method : opts.method, 745 | data : opts.data, 746 | callback: function (rs) { 747 | flashEl[opts.callback](rs); 748 | } 749 | }); 750 | } 751 | 752 | //初始化对象 753 | flashProxy = { 754 | flashReady: flashReady, 755 | pushData : pushData 756 | }; 757 | 758 | //返回对象 759 | return flashProxy; 760 | })(); 761 | 762 | 763 | //CommonJS 764 | if (typeof exports === 'object') { 765 | module.exports = jtool; 766 | return; 767 | } 768 | 769 | //添加到全局变量 770 | window.jtool = jtool; 771 | 772 | })(window); -------------------------------------------------------------------------------- /es5/myfocus.js: -------------------------------------------------------------------------------- 1 | /* 2 | * myFocus JavaScript Library v2.0.1 3 | * Open source under the BSD & GPL License 4 | * 5 | * Copyright 2012, Koen Lee 6 | * http://cosmissy.com/ 7 | * 8 | * Date: 2012/05/26 9 | * edit by songjj 10 | */ 11 | (function () { 12 | //DOM基础操作函数 13 | var $id = function (id) { 14 | return typeof id === 'string' ? document.getElementById(id) : id; 15 | }, 16 | $tag = function (tag, parentNode) { 17 | return ($id(parentNode) || document).getElementsByTagName(tag); 18 | }, 19 | $tag_ = function (tag, parentNode) { 20 | return $getChild(tag, parentNode, 'tag'); 21 | }, 22 | $class = function (className, parentNode) { 23 | var doms = $tag('*', parentNode), arr = []; 24 | for (var i = 0, l = doms.length; i < l; i++) { 25 | if (hasClass(className, doms[i])) { 26 | arr.push(doms[i]); 27 | } 28 | } 29 | return arr; 30 | }, 31 | $class_ = function (className, parentNode) { 32 | return $getChild(className, parentNode); 33 | }, 34 | $getChild = function (selector, parentNode, type) { 35 | var arr = [], fn = type === 'tag' ? $tag : $class, doms = fn(selector, parentNode), len = doms.length; 36 | for (var i = 0; i < len; i++) { 37 | if (doms[i].parentNode === parentNode) arr.push(doms[i]); 38 | i += fn(selector, doms[i]).length; 39 | } 40 | return arr; 41 | }, 42 | hasClass = function (className, node) { 43 | return eval('/(^|\\s)' + className + '(\\s|$)/').test(node.className); 44 | }; 45 | //定义myFocus全局变量 46 | myFocus = function (settings) { 47 | return new myFocus.constr(settings); 48 | }; 49 | //扩展 50 | myFocus.extend = function () { 51 | var arg = arguments, len = arg.length; 52 | if (this === myFocus) {//作为方法扩展,如果只有一个参数扩展本身 53 | if (len === 1) dest = myFocus, i = 0;//扩展myFocus类 54 | else dest = arg[0], i = 1; 55 | } else {//扩展引用对象本身 56 | dest = this, i = 0; 57 | } 58 | for (i; i < len; i++) { 59 | for (var p in arg[i]) { 60 | dest[p] = arg[i][p];//dest属性最低 61 | } 62 | } 63 | return dest; 64 | }; 65 | myFocus.extend({ 66 | defConfig: {//全局默认设置 67 | pattern: 'mF_fancy',//风格样式 68 | trigger: 'click',//触发切换模式['click'(鼠标点击)|'mouseover'(鼠标悬停)] 69 | txtHeight: 'default',//文字层高度设置[num(数字,单位像素,0表示隐藏文字层,省略设置即为默认高度)] 70 | wrap: true,//是否保留边框(有的话)[true|false] 71 | auto: true,//是否自动播放(切换)[true|false] 72 | time: 4,//每次停留时间[num(数字,单位秒)] 73 | index: 0,//开始显示的图片序号(从0算起)[num(数字)] 74 | loadIMGTimeout: 3,//载入图片的最长等待时间(Loading画面时间)[num(数字,单位秒,0表示不等待直接播放)] 75 | delay: 100,//触发切换模式中'mouseover'模式下的切换延迟[num(数字,单位毫秒)] 76 | __focusConstr__: true//程序构造参数 77 | }, 78 | constr: function (settings) {//构造函数 79 | var e = settings, len = e && e.length; 80 | if (e instanceof myFocus.constr) return e;//myFocus::[] 81 | this.length = 0; 82 | if (!e || (e.sort && !len) || (e.item && !len)) {//null/array::[]/nodeList::[] 83 | Array.prototype.push.call(this); 84 | } else if (e.__focusConstr__) {//new myFocus 85 | e = $id(e.id); 86 | Array.prototype.push.call(this, e); 87 | this.settings = settings; 88 | this.HTMLUList = $tag('li', $tag('ul', e)[0]); 89 | this.HTMLUListLength = this.HTMLUList.length; 90 | } else if (len) {//nodeList/Array/字符串 91 | for (var i = 0; i < len; i++) Array.prototype.push.call(this, e[i]); 92 | } else {//node 93 | Array.prototype.push.call(this, e); 94 | } 95 | return this; 96 | }, 97 | fn: {splice: [].splice},//原形 98 | pattern: {},//风格集 99 | config: {}//参数集 100 | }); 101 | myFocus.constr.prototype = myFocus.fn; 102 | myFocus.fn.extend = myFocus.pattern.extend = myFocus.config.extend = myFocus.extend; 103 | myFocus.fn.extend({//DOM 104 | find: function (selector) {//选择器只应用基本查找,暂不考虑用querySelectorAll 105 | var parent = this, isChild = false, $ = myFocus; 106 | var arr = this.parseSelector(selector); 107 | if (this.length) for (var i = 0, len = arr.length; i < len; i++) { 108 | var dom = [], s = arr[i]; 109 | switch (s.charAt(0)) { 110 | case '>'://children 111 | isChild = true; 112 | break; 113 | case '.'://class 114 | var cls = s.slice(1); 115 | var fn = isChild ? $class_ : $class; 116 | $(parent).each(function () { 117 | dom = dom.concat(fn(cls, this)); 118 | }); 119 | isChild = false; 120 | break; 121 | case '#'://id 122 | var id = s.slice(1), e = $id(id); 123 | if (e) dom.push($id(id)); 124 | isChild = false; 125 | break; 126 | default://tag(支持'tag.class'寻找,不支持也不建议用'tag#id'寻找,请用'#id') 127 | var fn = isChild ? $tag_ : $tag, sArr = s.split('.'); 128 | var tag = sArr[0], cls = sArr[1]; 129 | $(parent).each(function () { 130 | var arr = fn(tag, this); 131 | for (var i = 0, len = arr.length; i < len; i++) { 132 | if (cls && !hasClass(cls, arr[i])) continue; 133 | dom.push(arr[i]); 134 | } 135 | }); 136 | isChild = false; 137 | } 138 | if (!isChild) parent = dom;//循环赋值父元素 139 | } 140 | return $(parent); 141 | }, 142 | parent: function () { 143 | return myFocus(this[0].parentNode); 144 | }, 145 | html: function (s) { 146 | if (typeof s !== 'undefined') { 147 | this[0].innerHTML = s; 148 | return this; 149 | } 150 | else return this[0].innerHTML; 151 | }, 152 | each: function (fn) { 153 | var doms = this; 154 | for (var i = 0, len = doms.length; i < len; i++) { 155 | var flag = fn.call(doms[i], i); 156 | if (flag === false) break; 157 | if (flag === true) continue; 158 | } 159 | return this; 160 | }, 161 | eq: function (n) { 162 | return myFocus(this[n]); 163 | }, 164 | parseSelector: function (selector) { 165 | var chunker = /(([^[\]'"]+)+\]|\\.|([^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g; 166 | var parts = [], m; 167 | while ((m = chunker.exec(selector)) !== null) { 168 | parts.push(m[1]);//存储匹配的字符串信息 169 | } 170 | return parts; 171 | }, 172 | wrap: function (html) {//每次只wrap一个元素,多个请用each 173 | var o = this[0], e = document.createElement('div'); 174 | e.innerHTML = html; 175 | var wrap = e.firstChild; 176 | o.parentNode.replaceChild(wrap, o); 177 | wrap.appendChild(o); 178 | return this; 179 | }, 180 | addHtml: function (html) { 181 | var parent = this[0]; 182 | var e = document.createElement('div'); 183 | e.innerHTML = html; 184 | var dom = e.childNodes[0]; 185 | parent.appendChild(dom); 186 | return myFocus(dom); 187 | }, 188 | addList: function (className, type) { 189 | var li = this.HTMLUList, n = this.HTMLUListLength; 190 | var strArr = ['
    ']; 191 | for (var i = 0; i < n; i++) { 192 | var img = $tag('img', li[i])[0], html; 193 | switch (type) { 194 | case 'num': 195 | html = '' + (i + 1) + ''; 196 | break;//b标签主要是为了做透明背景,下同 197 | case 'txt': 198 | html = img ? li[i].innerHTML.replace(/\/i, img.alt) + '

    ' + img.getAttribute("text") + '

    ' : ''; 199 | break; 200 | case 'thumb': 201 | html = img ? '' : ''; 202 | break; 203 | default: 204 | html = ''; 205 | } 206 | strArr.push('
  • ' + html + '
  • '); 207 | } 208 | strArr.push('
'); 209 | return this.addHtml(strArr.join('')); 210 | }, 211 | addListNum: function (className) { 212 | return this.addList(className || 'num', 'num');//默认class=num 213 | }, 214 | addListTxt: function (className) { 215 | return this.addList(className || 'txt', 'txt');//默认class=txt 216 | }, 217 | addListThumb: function (className) { 218 | return this.addList(className || 'thumb', 'thumb');//默认class=thumb 219 | }, 220 | remove: function () { 221 | var o = this[0]; 222 | if (o) o.parentNode.removeChild(o); 223 | }, 224 | repeat: function (n) { 225 | var n = n || 2, pNode = this[0].parentNode, html = pNode.innerHTML, s = []; 226 | for (var i = 0; i < n; i++) s.push(html); 227 | pNode.innerHTML = s.join(''); 228 | return myFocus(pNode).find(this[0].nodeName); 229 | } 230 | }); 231 | myFocus.fn.extend({//CSS 232 | css: function (css) {//可获值或设值 233 | var o = this[0], value, arr = [';'], isIE = myFocus.isIE; 234 | if (!o) return this; 235 | if (typeof css === 'string') {//获得css属性值,返回值不带单位 236 | if (css === 'float') css = isIE ? 'styleFloat' : 'cssFloat'; 237 | if (!(value = o.style[css])) value = (isIE ? o.currentStyle : getComputedStyle(o, ''))[css]; 238 | if (css === 'opacity' && value === undefined) value = 1;//仅为在IE中得到默认值1 239 | if (value === 'auto' && (css === 'width' || css === 'height')) value = o['offset' + css.replace(/\w/i, function (a) { 240 | return a.toUpperCase() 241 | })]; 242 | var numVal = parseFloat(value); 243 | return isNaN(numVal) ? value : numVal; 244 | } else {//设置css属性值,不支持('height','300px')形式,请变成-->({height:'300px'}),可以不带单位px 245 | for (var p in css) { 246 | if (typeof css[p] === 'number' && !this.cssNumber[p]) css[p] += 'px'; 247 | arr.push(p.replace(/([A-Z])/g, '-$1') + ':' + css[p] + ';'); 248 | if (p === 'opacity') arr.push('filter:alpha(opacity=' + css[p] * 100 + ')'); 249 | } 250 | o.style.cssText += arr.join(''); 251 | return this; 252 | } 253 | }, 254 | setOpacity: function (value) {//仅用于animate要求高效的核心算法中,其它情况可用css()代替 255 | this[0].style.opacity = value, this[0].style.filter = 'alpha(opacity=' + value * 100 + ')'; 256 | }, 257 | setAnimateStyle: function (value, prop, m) {//仅用于animate要求高效的核心算法中,其它情况可用css()代替 258 | this[0].style[prop] = Math[m](value) + 'px'; 259 | }, 260 | addClass: function (className) { 261 | this[0].className += ' ' + className; 262 | return this; 263 | }, 264 | removeClass: function (className) { 265 | var o = this[0], cls = className && o.className, reg = "/\\s*\\b" + className + "\\b/g"; 266 | o.className = cls ? cls.replace(eval(reg), '') : ''; 267 | return this; 268 | }, 269 | cssNumber: { 270 | fillOpacity: true, 271 | fontWeight: true, 272 | lineHeight: true, 273 | opacity: true, 274 | orphans: true, 275 | widows: true, 276 | zIndex: true, 277 | zoom: true 278 | }//不加px的css,参考jQuery 279 | }); 280 | myFocus.fn.extend({//Animate 281 | animate: function (attr, value, time, type, funcBefore, funcAfter) {//value支持相对增值'+=100',相对减值'-=100'形式 282 | var $o = this, o = $o[0], isOpacity = attr === 'opacity', diffValue = false; 283 | funcBefore && funcBefore.call(o); 284 | if (typeof value === 'string') { 285 | if (/^[+-]=\d+/.test(value)) value = value.replace('=', ''), diffValue = true; 286 | value = parseFloat(value); 287 | } 288 | var oriVal = $o.css(attr),//原始属性值 289 | b = isNaN(oriVal) ? 0 : oriVal,//开始值,无值时为0 290 | c = diffValue ? value : value - b,//差值 291 | d = time,//总运行时间 292 | e = this.easing[type],//缓动类型 293 | m = c > 0 ? 'ceil' : 'floor',//取最大绝对值 294 | timerId = '__myFocusTimer__' + attr,//计数器id 295 | setProperty = $o[isOpacity ? 'setOpacity' : 'setAnimateStyle'],//属性设置方法 296 | origTime = (new Date) * 1;//原始时间值 297 | o[timerId] && clearInterval(o[timerId]); 298 | o[timerId] = setInterval(function () { 299 | var t = (new Date) - origTime;//已运行时间 300 | if (t <= d) { 301 | setProperty.call($o, e(t, b, c, d), attr, m); 302 | } else { 303 | setProperty.call($o, b + c, attr, m);//设置最终值 304 | clearInterval(o[timerId]), o[timerId] = null; 305 | funcAfter && funcAfter.call(o); 306 | } 307 | }, 13); 308 | return this; 309 | }, 310 | fadeIn: function (time, type, fn) { 311 | if (typeof time !== 'number') fn = time, time = 400;//默认400毫秒 312 | if (typeof type === 'function') fn = type, type = ''; 313 | this.animate('opacity', 1, time, type || 'linear', function () { 314 | myFocus(this).css({display: 'block', opacity: 0}); 315 | }, fn); 316 | return this; 317 | }, 318 | fadeOut: function (time, type, fn) { 319 | if (typeof time !== 'number') fn = time, time = 400;//默认400毫秒 320 | if (typeof type === 'function') fn = type, type = ''; 321 | this.animate('opacity', 0, time, type || 'linear', null, function () { 322 | this.style.display = 'none'; 323 | fn && fn.call(this); 324 | }); 325 | return this; 326 | }, 327 | slide: function (params, time, type, fn) { 328 | if (typeof time !== 'number') fn = time, time = 800;//默认800毫秒 329 | if (typeof type === 'function') fn = type, type = ''; 330 | for (var p in params) this.animate(p, params[p], time, type || 'easeOut', null, fn); 331 | return this; 332 | }, 333 | stop: function () {//停止所有运动 334 | var o = this[0]; 335 | for (var p in o) if (p.indexOf('__myFocusTimer__') !== -1) o[p] && clearInterval(o[p]); 336 | return this; 337 | }, 338 | easing: { 339 | linear: function (t, b, c, d) { 340 | return c * t / d + b; 341 | }, 342 | swing: function (t, b, c, d) { 343 | return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; 344 | }, 345 | easeIn: function (t, b, c, d) { 346 | return c * (t /= d) * t * t * t + b; 347 | }, 348 | easeOut: function (t, b, c, d) { 349 | return -c * ((t = t / d - 1) * t * t * t - 1) + b; 350 | }, 351 | easeInOut: function (t, b, c, d) { 352 | return ((t /= d / 2) < 1) ? (c / 2 * t * t * t * t + b) : (-c / 2 * ((t -= 2) * t * t * t - 2) + b); 353 | } 354 | } 355 | }); 356 | myFocus.fn.extend({//Method(fn) 357 | bind: function (type, fn) { 358 | myFocus.addEvent(this[0], type, fn); 359 | return this; 360 | }, 361 | play: function (funcLastFrame, funcCurrentFrame, seamless) { 362 | var this_ = this, p = this_.settings, n = this_.HTMLUListLength, t = p.time * 1000, seamless = seamless || false,//是否无缝 363 | fl = myFocus(this_.HTMLUList).css('float'), isLevel = fl === 'left',//仅支持'left'方向和'top'方向 364 | direction = isLevel ? 'left' : 'top', distance = isLevel ? p.width : p.height,//运动距离 365 | indexLast = 0, indexCurrent = p.index;//帧索引值,默认0 366 | this_.find('.loading').remove();//删除loading... 367 | this_.run = function (value) {//循环运动函数,支持+-=value 368 | funcLastFrame && funcLastFrame(indexLast, n);//运行前一帧 369 | indexCurrent = typeof value === 'string' ? indexLast + parseInt(value.replace('=', '')) : value;//fixed index 370 | if (indexCurrent <= -1) {//prev run 371 | indexCurrent = n - 1;//转到最后一帧 372 | if (seamless) this_.HTMLUList[0].parentNode.style[direction] = -n * distance + 'px';//无缝的UL定位 373 | } 374 | if (indexCurrent >= n) {//next run 375 | if (!seamless) indexCurrent = 0;//非无缝时转到第一帧 376 | if (indexCurrent >= 2 * n) {//无缝 377 | this_.HTMLUList[0].parentNode.style[direction] = -(n - 1) * distance + 'px';//无缝的UL定位 378 | indexCurrent = n; 379 | } 380 | } 381 | if (seamless && indexLast >= n && indexCurrent < n) indexCurrent += n;//无缝时的按钮点击(保持同一方向) 382 | funcCurrentFrame && funcCurrentFrame(indexCurrent, n, indexLast);//运行当前帧 383 | this_.runIndex = indexLast = indexCurrent;//保存已运行的帧索引 384 | }; 385 | try { 386 | this_.run(indexCurrent) 387 | } catch (e) { 388 | setTimeout(function () { 389 | this_.run(indexCurrent) 390 | }, 0) 391 | } 392 | ;//运行... 393 | if (p.auto) {//自动切换 394 | this_.runTimer = setInterval(function () { 395 | this_.run('+=1') 396 | }, t);//默认递增运行每帧 397 | this_.bind('mouseover', function () {//绑定事件 398 | clearInterval(this_.runTimer); 399 | }).bind('mouseout', function () { 400 | if (!this_.isStop) this_.runTimer = setInterval(function () { 401 | this_.run('+=1') 402 | }, t); 403 | }); 404 | } 405 | this_.find('a').each(function () {//去除IE链接虚线 406 | this.onfocus = function () { 407 | this.blur(); 408 | } 409 | }); 410 | }, 411 | bindControl: function ($btnList, params) {//params={thumbShowNum:'略缩图显示数目(如果有)',isRunning:'运行中的标记(当需要判断时)'} 412 | var this_ = this, p = this_.settings, type = p.trigger, delay = p.delay, par = params || {}, tsNum = par.thumbShowNum || p.thumbShowNum; 413 | var run = function () { 414 | if (this.index !== this_.runIndex && !par.isRunning) { 415 | this_.run(this.index); 416 | return false;//阻止冒泡&默认事件 417 | } 418 | }; 419 | $btnList.each(function (i) { 420 | this.index = i;//记录自身索引 421 | var o = this, $o = myFocus(o); 422 | if (type === 'click') { 423 | $o.bind('mouseover', function () { 424 | $o.addClass('hover'); 425 | }).bind('mouseout', function () { 426 | $o.removeClass('hover'); 427 | }).bind('click', run); 428 | } else if (type === 'mouseover') { 429 | $o.bind('mouseover', function () { 430 | if (delay === 0) run.call(o); 431 | else $btnList.mouseoverTimer = setTimeout(function () { 432 | run.call(o) 433 | }, delay); 434 | }).bind('mouseout', function () { 435 | $btnList.mouseoverTimer && clearTimeout($btnList.mouseoverTimer); 436 | }); 437 | } else { 438 | alert('myFocus Error Setting(trigger) : \"' + type + '\"'); 439 | return false; 440 | } 441 | ; 442 | }); 443 | if (tsNum) {//thumb 444 | var fl = $btnList.css('float'), isLevel = fl === 'left' || fl === 'right'; 445 | $btnList.dir = isLevel ? 'left' : 'top';//方向 446 | $btnList.n = this_.HTMLUListLength;//总数 447 | $btnList.showNum = tsNum;//显示数目 448 | $btnList.showStart = p.index;//显示的开始索引 449 | $btnList.showEnd = $btnList.showStart + tsNum - 1;//显示的结尾索引 450 | $btnList.distance = $btnList.css(isLevel ? 'width' : 'height');//运动距离 451 | $btnList.slideBody = $btnList.parent();//运动对象(ul) 452 | } 453 | }, 454 | scrollTo: function (i, time) { 455 | var n = this.n, dir = this.dir, $ul = this.slideBody, css = {};//总数/方向/滑动body(ul)/样式 456 | if (i >= this.showEnd) {//next 457 | this.showEnd = i < n - 1 ? i + 1 : i; 458 | 459 | this.showStart = this.showEnd - this.showNum + 1; 460 | } else if (i <= this.showStart) {//prev 461 | this.showStart = i > 0 ? i - 1 : 0; 462 | this.showEnd = this.showStart + this.showNum - 1; 463 | } 464 | css[dir] = -this.showStart * this.distance; 465 | $ul.slide(css, time || 500, 'easeOut'); 466 | return this; 467 | } 468 | }); 469 | myFocus.extend({//Init 470 | set: function (p, callback) { 471 | var F = this, id = p.id, oStyle = F.initBaseCSS(id); 472 | /*----added begin----*/ 473 | //将数据格式换为html 474 | var data = p.data; 475 | if (data && data instanceof Array) { 476 | var myFocus = document.getElementById(id); 477 | var html = p.isHideLoading ? '' : '
请稍候...
'; 478 | html += '
    '; 479 | for (var i = 0, len = data.length; i < len; i++) { 480 | var item = data[i]; 481 | var href = item.href || ''; 482 | var src = item.src || ''; 483 | var thumb = item.thumb || ''; 484 | var alt = item.alt || ''; 485 | var text = item.text || ''; 486 | html += '
  • ' + alt + '
  • ' 487 | } 488 | html += '
'; 489 | myFocus.innerHTML = html; 490 | } 491 | /*----added end----*/ 492 | p.pattern = p.pattern || F.defConfig.pattern; 493 | p.__clsName = p.pattern + '_' + id; 494 | F.addEvent(window, 'load', function () { 495 | F.onloadWindow = true 496 | }); 497 | F.loadPattern(p, function () { 498 | p = F.extend({}, F.defConfig, F.config[p.pattern], p);//收集完整参数 499 | F.getBoxReady(p, function () { 500 | var $o = F($id(id)); 501 | p.width = p.width || $o.css('width'), p.height = p.height || $o.css('height');//获得box高/宽 502 | F.initCSS(p, $o, oStyle);//css 503 | F.initHTML($o);//html 504 | $o.addClass(p.pattern + ' ' + p.__clsName);//+className 505 | F.getIMGReady(p, function () { 506 | F.pattern[p.pattern](p, F);//运行pattern代码 507 | callback && callback(); 508 | }); 509 | }); 510 | }); 511 | }, 512 | onloadWindow: false, 513 | loadPattern: function (p, callback) { 514 | if (this.pattern[p.pattern]) { 515 | callback(); 516 | return; 517 | }//如果已加载pattern 518 | var path = this.getFilePath() + 'mf_pattern/' + p.pattern; 519 | var js = document.createElement("script"), css = document.createElement("link"), src = path + '.js', href = path + '.css'; 520 | js.type = "text/javascript", js.src = src; 521 | css.rel = "stylesheet", css.href = href; 522 | var head = $tag('head')[0], isSuccess = 0, timeout = 3000;//超时3秒 523 | head.appendChild(css); 524 | head.appendChild(js); 525 | js.onload = js.onreadystatechange = function () { 526 | if (!js.readyState || js.readyState == "loaded" || js.readyState == "complete") callback(), isSuccess = 1; 527 | }; 528 | setTimeout(function () { 529 | if (!isSuccess) alert('Failed to load: ' + src); 530 | }, timeout); 531 | }, 532 | getFilePath: function () { 533 | var path = ''; 534 | var scripts = $tag("script"); 535 | for (var i = 0, len = scripts.length; i < len; i++) { 536 | var src = scripts[i].src; 537 | if (src && /myfocus*?.\.js/i.test(src)) { 538 | path = src; 539 | break; 540 | } 541 | } 542 | ; 543 | return path.slice(0, path.lastIndexOf('/') + 1); 544 | }, 545 | getBoxReady: function (p, fn) { 546 | var F = this; 547 | (function () { 548 | try { 549 | if (F.isIE) $id(p.id).doScroll(); 550 | else $id(p.id).innerHTML; 551 | fn(); 552 | } catch (e) { 553 | if (!F.onloadWindow) setTimeout(arguments.callee, 0); 554 | } 555 | })(); 556 | }, 557 | getIMGReady: function (p, callback) { 558 | var t = p.loadIMGTimeout; 559 | var box = $id(p.id), img = $tag('img', box), len = img.length, count = 0, done = false; 560 | if (!t || !len) { 561 | callback(); 562 | return; 563 | }//无延迟 564 | for (var i = 0; i < len; i++) { 565 | img[i].onload = function () { 566 | count += 1; 567 | if (count == len && !done) { 568 | done = true, callback(); 569 | } 570 | }; 571 | if (this.isIE) img[i].src = img[i].src;//修复IE BUG 572 | } 573 | ; 574 | var t = t * 1000; 575 | setTimeout(function () { 576 | if (!done) { 577 | done = true, callback(); 578 | } 579 | }, t); 580 | }, 581 | initCSS: function (p, $o, oStyle) { 582 | var css = [], w = p.width || '', h = p.height || ''; 583 | if (p.wrap) $o.wrap('
'); 584 | css.push('.' + p.__clsName + ' *{margin:0;padding:0;border:0;list-style:none;}.' + p.__clsName + '{position:relative;width:' + w + 'px;height:' + h + 'px;overflow:hidden;font:12px/1.5 Verdana;text-align:left;background:#fff;visibility:visible!important;}.' + p.__clsName + ' .loading{position:absolute;z-index:9999;width:100%;height:100%;color:#666;text-align:center;padding-top:' + 0.26 * h + 'px;background:#fff;}.' + p.__clsName + ' .pic{position:relative;width:' + w + 'px;height:' + h + 'px;overflow:hidden;}.' + p.__clsName + ' .txt li{width:' + w + 'px;height:' + p.txtHeight + 'px!important;overflow:hidden;}'); 585 | //if(p.autoZoom) css.push('.'+p.__clsName+' .pic li{text-align:center;width:'+w+'px;height:'+h+'px;}');//缩放图片居中 586 | try { 587 | oStyle.styleSheet.cssText = css.join('') 588 | } catch (e) { 589 | oStyle.innerHTML = css.join('') 590 | } 591 | }, 592 | initBaseCSS: function (id) { 593 | var s = '#' + id + ' *{display:none}', oStyle = document.createElement('style'); 594 | oStyle.type = 'text/css'; 595 | try { 596 | oStyle.styleSheet.cssText = s 597 | } catch (e) { 598 | oStyle.innerHTML = s 599 | } 600 | var oHead = $tag('head', document)[0]; 601 | oHead.insertBefore(oStyle, oHead.firstChild); 602 | return oStyle; 603 | }, 604 | initHTML: function ($o) { 605 | var $load = $o.find('.loading'), $img = $load.find('img'), img = $img[0]; 606 | if ($img.length) { 607 | $load.addHtml('

' + img.alt + '

'); 608 | if (!img.getAttribute('src')) img.style.display = 'none'; 609 | } 610 | } 611 | }); 612 | myFocus.extend({//Method(myFocus) 613 | isIE: !!(document.all && navigator.userAgent.indexOf('Opera') === -1),//!(+[1,]) BUG IN IE9+? 614 | addEvent: function (o, type, fn) { 615 | var ie = this.isIE, e = ie ? 'attachEvent' : 'addEventListener', t = (ie ? 'on' : '') + type; 616 | o[e](t, function (e) { 617 | var e = e || window.event, flag = fn.call(o, e); 618 | if (flag === false) { 619 | if (ie) e.cancelBubble = true, e.returnValue = false; 620 | else e.stopPropagation(), e.preventDefault(); 621 | } 622 | }, false); 623 | } 624 | }); 625 | //支持JQ 626 | if (typeof jQuery !== 'undefined') { 627 | jQuery.fn.extend({ 628 | myFocus: function (p, fn) { 629 | if (!p) p = {}; 630 | p.id = this[0].id; 631 | if (!p.id) p.id = this[0].id = 'mF__ID__'; 632 | myFocus.set(p, fn); 633 | } 634 | }); 635 | } 636 | })(); -------------------------------------------------------------------------------- /es5/mymd5.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | /* 4 | * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message 5 | * Digest Algorithm, as defined in RFC 1321. 6 | * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002. 7 | * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet 8 | * Distributed under the BSD License 9 | * See http://pajhome.org.uk/crypt/md5 for more info. 10 | */ 11 | 12 | /* 13 | * Configurable variables. You may need to tweak these to be compatible with 14 | * the server-side, but the defaults work in most cases. 15 | */ 16 | var hexcase = 0; 17 | /* base-64 pad character. "=" for strict RFC compliance */ 18 | var chrsz = 8; 19 | /* bits per input character. 8 - ASCII; 16 - Unicode */ 20 | 21 | /* 22 | * These are the functions you'll usually want to call 23 | * They take string arguments and return either hex or base-64 encoded strings 24 | */ 25 | function hex_md5(s) { 26 | return binl2hex(core_md5(str2binl(s), s.length * chrsz)); 27 | } 28 | 29 | /* 30 | * Calculate the MD5 of an array of little-endian words, and a bit length 31 | */ 32 | function core_md5(x, len) { 33 | /* append padding */ 34 | x[len >> 5] |= 0x80 << ((len) % 32); 35 | x[(((len + 64) >>> 9) << 4) + 14] = len; 36 | 37 | var a = 1732584193; 38 | var b = -271733879; 39 | var c = -1732584194; 40 | var d = 271733878; 41 | 42 | for (var i = 0; i < x.length; i += 16) { 43 | var olda = a; 44 | var oldb = b; 45 | var oldc = c; 46 | var oldd = d; 47 | 48 | a = md5_ff(a, b, c, d, x[i], 7, -680876936); 49 | d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586); 50 | c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819); 51 | b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330); 52 | a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897); 53 | d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426); 54 | c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341); 55 | b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983); 56 | a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416); 57 | d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417); 58 | c = md5_ff(c, d, a, b, x[i + 10], 17, -42063); 59 | b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162); 60 | a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682); 61 | d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101); 62 | c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290); 63 | b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329); 64 | 65 | a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510); 66 | d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632); 67 | c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713); 68 | b = md5_gg(b, c, d, a, x[i], 20, -373897302); 69 | a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691); 70 | d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083); 71 | c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335); 72 | b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848); 73 | a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438); 74 | d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690); 75 | c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961); 76 | b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501); 77 | a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467); 78 | d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784); 79 | c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473); 80 | b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734); 81 | 82 | a = md5_hh(a, b, c, d, x[i + 5], 4, -378558); 83 | d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463); 84 | c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562); 85 | b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556); 86 | a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060); 87 | d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353); 88 | c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632); 89 | b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640); 90 | a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174); 91 | d = md5_hh(d, a, b, c, x[i], 11, -358537222); 92 | c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979); 93 | b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189); 94 | a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487); 95 | d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835); 96 | c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520); 97 | b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651); 98 | 99 | a = md5_ii(a, b, c, d, x[i], 6, -198630844); 100 | d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415); 101 | c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905); 102 | b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055); 103 | a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571); 104 | d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606); 105 | c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523); 106 | b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799); 107 | a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359); 108 | d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744); 109 | c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380); 110 | b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649); 111 | a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070); 112 | d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379); 113 | c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259); 114 | b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551); 115 | 116 | a = safe_add(a, olda); 117 | b = safe_add(b, oldb); 118 | c = safe_add(c, oldc); 119 | d = safe_add(d, oldd); 120 | } 121 | return [a, b, c, d]; 122 | 123 | } 124 | 125 | /* 126 | * These functions implement the four basic operations the algorithm uses. 127 | */ 128 | function md5_cmn(q, a, b, x, s, t) { 129 | return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b); 130 | } 131 | 132 | function md5_ff(a, b, c, d, x, s, t) { 133 | return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); 134 | } 135 | 136 | function md5_gg(a, b, c, d, x, s, t) { 137 | return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); 138 | } 139 | 140 | function md5_hh(a, b, c, d, x, s, t) { 141 | return md5_cmn(b ^ c ^ d, a, b, x, s, t); 142 | } 143 | 144 | function md5_ii(a, b, c, d, x, s, t) { 145 | return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); 146 | } 147 | 148 | /* 149 | * Add integers, wrapping at 2^32. This uses 16-bit operations internally 150 | * to work around bugs in some JS interpreters. 151 | */ 152 | function safe_add(x, y) { 153 | var lsw = (x & 0xFFFF) + (y & 0xFFFF); 154 | var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 155 | return (msw << 16) | (lsw & 0xFFFF); 156 | } 157 | 158 | /* 159 | * Bitwise rotate a 32-bit number to the left. 160 | */ 161 | function bit_rol(num, cnt) { 162 | return (num << cnt) | (num >>> (32 - cnt)); 163 | } 164 | 165 | /* 166 | * Convert a string to an array of little-endian words 167 | * If chrsz is ASCII, characters >255 have their hi-byte silently ignored. 168 | */ 169 | function str2binl(str) { 170 | var bin = []; 171 | var mask = (1 << chrsz) - 1; 172 | for (var i = 0; i < str.length * chrsz; i += chrsz) 173 | bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (i % 32); 174 | return bin; 175 | } 176 | 177 | /* 178 | * Convert an array of little-endian words to a hex string. 179 | */ 180 | function binl2hex(binarray) { 181 | var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; 182 | var str = ""; 183 | for (var i = 0; i < binarray.length * 4; i++) { 184 | str += hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8 + 4)) & 0xF) + 185 | hex_tab.charAt((binarray[i >> 2] >> ((i % 4) * 8)) & 0xF); 186 | } 187 | return str; 188 | } 189 | 190 | 191 | //CommonJS 192 | if (typeof exports === 'object') { 193 | return module.exports = hex_md5; 194 | } 195 | 196 | //添加到全局对象 197 | window.mymd5 = hex_md5; 198 | })(window); 199 | -------------------------------------------------------------------------------- /es5/query.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | test 6 | 9 | 10 | 11 | 12 | 13 | 17 | 18 | -------------------------------------------------------------------------------- /es5/query.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | // 查询字符操作对象 4 | var query = (function () { 5 | var Object = window.Object, 6 | location = window.location, 7 | decodeURIComponent = window.decodeURIComponent, 8 | encodeURIComponent = window.encodeURIComponent, 9 | query = { 10 | queryData: parse(), 11 | getItem: getItem, 12 | parse: parse, 13 | stringify: stringify 14 | }; 15 | 16 | // 获取项 17 | function getItem(key) { 18 | if (!key) { 19 | return; 20 | } 21 | return query.queryData[key]; 22 | } 23 | 24 | // 查询字符转为对象 25 | function parse(str) { 26 | str || (str = location.search.slice(1)); 27 | 28 | var rs = {}; 29 | // 字符 30 | if (typeof str === 'string' && str) { 31 | str.split('&').forEach(function (item) { 32 | var kv = item.split('='), 33 | key = kv[0], 34 | val = kv[1]; 35 | val !== undefined && (rs[key] = decodeURIComponent(val)); 36 | }); 37 | } 38 | return rs; 39 | } 40 | 41 | // 对象转为查询字符 42 | function stringify(obj) { 43 | return Object.keys(obj).map(function (key) { 44 | return key + '=' + encodeURIComponent(obj[key]); 45 | }).join('&'); 46 | } 47 | 48 | return query; 49 | })(); 50 | 51 | 52 | // CommonJS 53 | if (typeof exports === 'object') { 54 | return module.exports = query; 55 | } 56 | 57 | // 添加到全局 58 | window.query = query; 59 | 60 | })(window); 61 | -------------------------------------------------------------------------------- /es5/share.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | var share = (function () { 4 | return function (url, txt, pic, provider, isGetUrl) { 5 | if (!provider) return; 6 | 7 | var toUrl; 8 | url = encodeURIComponent(url || ''); 9 | txt = encodeURIComponent(txt || ''); 10 | pic = encodeURIComponent(pic || ''); 11 | 12 | switch (provider) { 13 | case 'weibosohu': 14 | { 15 | toUrl = 'http://t.sohu.com/third/post.jsp?url=' + url + '&title=' + txt + '&pic=' + pic; 16 | break; 17 | } 18 | case 'weibosina': 19 | { 20 | toUrl = 'http://service.t.sina.com.cn/share/share.php?title=' + txt + url + '&pic=' + pic + '&searchPic=false'; 21 | break; 22 | } 23 | case 'qq': 24 | { 25 | toUrl = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=' + url + '&title=' + txt + '&desc=' + txt + '&summary=' + pic; 26 | break; 27 | } 28 | case 'tqq': 29 | { 30 | toUrl = 'http://v.t.qq.com/share/share.php?url=' + url + '&title=' + txt + '&pic=' + pic; 31 | break; 32 | } 33 | case 'renren': 34 | { 35 | toUrl = 'http://widget.renren.com/dialog/share?resourceUrl=' + pic + '&srcUrl=' + url + '&title=' + txt + '&description=' + txt; 36 | break; 37 | } 38 | case 'baishehui': 39 | { 40 | toUrl = 'http://bai.sohu.com/share/blank/addbutton.do?link=' + url + '&title=' + txt + '&pic=' + pic; 41 | break; 42 | } 43 | case 'douban': 44 | { 45 | toUrl = 'http://shuo.douban.com/!service/share?href=' + url + '&name=' + txt; 46 | break; 47 | } 48 | case 'kaixin001': 49 | { 50 | toUrl = 'http://www.kaixin001.com/rest/records.php?url=' + url + '&style=11&content=' + txt; 51 | break; 52 | } 53 | case '163': 54 | { 55 | toUrl = 'http://t.163.com/article/user/checkLogin.do?info=' + txt + url; 56 | break; 57 | } 58 | case '51': 59 | { 60 | toUrl = 'http://share.51.com/share/share.php?vaddr=' + url + '&title=' + txt + '&type=8&pic=' + pic; 61 | break; 62 | } 63 | case 'txpengyou': 64 | { 65 | toUrl = 'http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?to=pengyou&url=' + url + '&title=' + txt + '&desc=' + txt + '&summary=' + pic; 66 | break; 67 | } 68 | case 'tieba': 69 | { 70 | toUrl = 'http://tieba.baidu.com/f/commit/share/openShareApi?url=' + url + '&title=' + txt + '&desc=' + txt; 71 | break; 72 | } 73 | } 74 | 75 | return isGetUrl ? toUrl : window.open(toUrl); 76 | }; 77 | })(); 78 | 79 | 80 | //CommonJS 81 | if (typeof exports === 'object') { 82 | return module.exports = share; 83 | } 84 | 85 | //添加到全局 86 | window.share = share; 87 | 88 | })(window); -------------------------------------------------------------------------------- /es5/storage.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | //storage操作对象 4 | var storage = (function () { 5 | 6 | var localStorage = window.localStorage, 7 | Date = window.Date, 8 | toString = {}.toString, 9 | //过期时间前缀 10 | expirePrefix = '_expire_'; 11 | 12 | /** 13 | * 设置localStorage函数 14 | * @param {string} key 键 15 | * @param {string} val 值 16 | * @param {Date|number} days 过期时间|过期天数 17 | * @param {number} hours 过期小时数 18 | */ 19 | function setItem(key, val, days, hours) { 20 | //如设值为空 21 | if (val === undefined || val === null) { 22 | return; 23 | } 24 | 25 | var expire, now = new Date(); 26 | 27 | //days参数是一个日期 28 | if (toString.call(days) === '[object Date]') { 29 | expire = +days; 30 | } 31 | //过期天数 32 | else if (typeof days === 'number') { 33 | expire = now.setDate(now.getDate() + days); 34 | } 35 | //过期小时数 36 | else if (typeof hours === 'number') { 37 | expire = now.setHours(now.getHours() + hours); 38 | } 39 | //默认过期天数为1天 40 | else { 41 | expire = now.setDate(now.getDate() + 1); 42 | } 43 | 44 | localStorage.setItem(key, val); 45 | localStorage.setItem(expirePrefix + key, expire); 46 | } 47 | 48 | /** 49 | * 获取 50 | * @param {string} key 键 51 | * @returns {string} 值 52 | */ 53 | function getItem(key) { 54 | var date = new Date(), 55 | expire = localStorage.getItem(expirePrefix + key); 56 | 57 | //判断过期时间,如未过期 58 | if (expire && +expire > +date) { 59 | return localStorage.getItem(key); 60 | } 61 | //已过期就清除 62 | else { 63 | removeItem(key); 64 | return null; 65 | } 66 | } 67 | 68 | /** 69 | * 清除 70 | * @param {string} key 键 71 | */ 72 | function removeItem(key) { 73 | localStorage.removeItem(key); 74 | localStorage.removeItem(expirePrefix + key); 75 | } 76 | 77 | return { 78 | setItem: setItem, 79 | getItem: getItem, 80 | removeItem: removeItem 81 | }; 82 | })(); 83 | 84 | 85 | //CommonJS 86 | if (typeof exports === 'object') { 87 | return module.exports = storage; 88 | } 89 | 90 | //添加到全局 91 | window.storage = storage; 92 | 93 | })(window); -------------------------------------------------------------------------------- /es5/test.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | test 6 | 9 | 10 | 11 | 12 | 13 | 14 | aaaaaaa 15 | 16 | 17 | 35 | 36 | -------------------------------------------------------------------------------- /es5/xml2json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * https://github.com/sparkbuzz/jQuery-xml2json/blob/master/src/xml2json.js 3 | */ 4 | (function () { 5 | 6 | // default options based on https://github.com/Leonidas-from-XIV/node-xml2js 7 | var defaultOptions = { 8 | attrkey: '$', 9 | charkey: '_', 10 | normalize: false, 11 | explicitArray: false 12 | }; 13 | 14 | // extracted from jquery 15 | function parseXML(data) { 16 | var xml, tmp; 17 | if (!data || typeof data !== "string") { 18 | return null; 19 | } 20 | try { 21 | if (window.DOMParser) { // Standard 22 | tmp = new DOMParser(); 23 | xml = tmp.parseFromString(data, "text/xml"); 24 | } else { // IE 25 | xml = new ActiveXObject("Microsoft.XMLDOM"); 26 | xml.async = "false"; 27 | xml.loadXML(data); 28 | } 29 | } 30 | catch (e) { 31 | xml = undefined; 32 | } 33 | if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) { 34 | throw new Error("Invalid XML: " + data); 35 | } 36 | return xml; 37 | } 38 | 39 | function normalize(value, options) { 40 | if (!!options.normalize) { 41 | return (value || '').trim(); 42 | } 43 | return value; 44 | } 45 | 46 | function xml2jsonImpl(xml, options) { 47 | 48 | var i, result = {}, attrs = {}, node, child, name; 49 | result[options.attrkey] = attrs; 50 | 51 | if (xml.attributes && xml.attributes.length > 0) { 52 | for (i = 0; i < xml.attributes.length; i++) { 53 | var item = xml.attributes.item(i); 54 | attrs[item.nodeName] = item.value; 55 | } 56 | } 57 | 58 | // element content 59 | if (xml.childElementCount === 0) { 60 | result[options.charkey] = normalize(xml.textContent, options); 61 | } 62 | 63 | for (i = 0; i < xml.childNodes.length; i++) { 64 | node = xml.childNodes[i]; 65 | if (node.nodeType === 1) { 66 | 67 | if (node.attributes.length === 0 && node.childElementCount === 0) { 68 | child = normalize(node.textContent, options); 69 | } else { 70 | child = xml2jsonImpl(node, options); 71 | } 72 | 73 | name = node.nodeName; 74 | if (result.hasOwnProperty(name)) { 75 | // For repeating elements, cast/promote the node to array 76 | var val = result[name]; 77 | if (!Array.isArray(val)) { 78 | val = [val]; 79 | result[name] = val; 80 | } 81 | val.push(child); 82 | } else if (options.explicitArray === true) { 83 | result[name] = [child]; 84 | } else { 85 | result[name] = child; 86 | } 87 | } 88 | } 89 | 90 | return result; 91 | } 92 | 93 | /** 94 | * Converts an xml document or string to a JSON object. 95 | * @param xml 96 | * @param options 97 | * @returns {*} 98 | */ 99 | function xml2json(xml, options) { 100 | var n; 101 | 102 | if (!xml) { 103 | return xml; 104 | } 105 | 106 | options = options || {}; 107 | 108 | for (n in defaultOptions) { 109 | if (defaultOptions.hasOwnProperty(n) && options[n] === undefined) { 110 | options[n] = defaultOptions[n]; 111 | } 112 | } 113 | 114 | if (typeof xml === 'string') { 115 | xml = parseXML(xml).documentElement; 116 | } 117 | 118 | var root = {}; 119 | if (typeof xml.attributes === 'undefined' || xml.attributes === null) { 120 | root[xml.nodeName] = xml2jsonImpl(xml, options); 121 | } else if (xml.attributes && xml.attributes.length === 0 && xml.childElementCount === 0) { 122 | root[xml.nodeName] = normalize(xml.textContent, options); 123 | } else { 124 | root[xml.nodeName] = xml2jsonImpl(xml, options); 125 | } 126 | 127 | return root; 128 | } 129 | 130 | if (typeof exports !== 'undefined') { 131 | return module.exports = xml2json; 132 | } 133 | window.xml2json = xml2json; 134 | 135 | })(); 136 | -------------------------------------------------------------------------------- /ie8/jsonp.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | //跨域请求对象 4 | var jsonp = (function () { 5 | 6 | var document = window.document, 7 | bodyEl = document.body, 8 | JSON = window.JSON, 9 | //低于IE8 10 | isLteIE8 = !window.addEventListener; 11 | 12 | //获取uid函数 13 | var getUid = (function () { 14 | var uid = 0; 15 | return function () { 16 | return ++uid; 17 | } 18 | })(); 19 | 20 | //加载js函数 21 | var getScript = (function () { 22 | var headEl = document.getElementsByTagName('head')[0]; 23 | 24 | return function (url, fn) { 25 | var isJs = /(\.js)$/.test(url), 26 | scriptEl = document.createElement('script'); 27 | 28 | //type 29 | scriptEl.type = 'text/javascript'; 30 | 31 | //onload 32 | if (isLteIE8) { 33 | scriptEl.onreadystatechange = function () { 34 | if (scriptEl.readyState === 'loaded' || scriptEl.readyState === 'complete') { 35 | scriptEl.onreadystatechange = null; 36 | 37 | typeof fn === 'function' && fn(); 38 | !isJs && scriptEl.parentNode.removeChild(scriptEl); 39 | } 40 | }; 41 | } 42 | else { 43 | scriptEl.onload = function () { 44 | typeof fn === 'function' && fn(); 45 | !isJs && scriptEl.parentNode.removeChild(scriptEl); 46 | }; 47 | } 48 | 49 | //请求 50 | scriptEl.src = url; 51 | headEl.appendChild(scriptEl); 52 | }; 53 | })(); 54 | 55 | //对象转查询字符串函数 56 | function obj2str(obj) { 57 | var array = []; 58 | for (var p in obj) { 59 | array.push(p + '=' + encodeURIComponent(obj[p])); 60 | } 61 | return array.join('&'); 62 | } 63 | 64 | //扩展函数 65 | var extend = (function () { 66 | var tmpArray = [], 67 | forEach = tmpArray.forEach, 68 | slice = tmpArray.slice; 69 | 70 | return function (obj) { 71 | //$.extend({}, defaults[, obj]) 72 | forEach.call(slice.call(arguments, 1), function (item) { 73 | for (var p in item) { 74 | obj[p] = item[p]; 75 | } 76 | }); 77 | return obj; 78 | }; 79 | })(); 80 | 81 | //回调函数 82 | function callback(rs, opts) { 83 | //回调函数 84 | var cb = opts.callback; 85 | typeof cb === 'function' && cb(rs); 86 | 87 | //成功或失败回调函数 88 | var success = opts.success, 89 | error = opts.error; 90 | rs.status === 200 ? typeof success === 'function' && success(rs.data) : typeof error === 'function' && error(rs.msg); 91 | } 92 | 93 | 94 | //get数据函数 95 | function get(opts) { 96 | opts = extend({}, get.defaults, opts); 97 | 98 | var cbName = 'jsonpcb' + getUid(); 99 | 100 | //将回调函数添加到全局变量 101 | window[cbName] = function (rs) { 102 | //回调 103 | callback(rs, opts); 104 | 105 | //释放回调函数 106 | window[cbName] = null; 107 | }; 108 | 109 | //url中添加callback 110 | var url = opts.url; 111 | url += (url.indexOf('?') === -1 ? '?' : '&') + 'callback=' + cbName; 112 | 113 | //拼接data 114 | var data = opts.data; 115 | data && (url += '&' + obj2str(data)); 116 | 117 | getScript(url); 118 | } 119 | 120 | //get数据默认配置项 121 | get.defaults = {}; 122 | 123 | 124 | //push数据函数 125 | var push = (function () { 126 | //回调函数对象 127 | var msgcb = {}; 128 | 129 | //消息函数 130 | function onMsg(evt) { 131 | var data = JSON.parse(evt.data); 132 | msgcb[data.id](data.rs); 133 | } 134 | 135 | //绑定消息事件 136 | isLteIE8 ? window.attachEvent('onmessage', onMsg) : window.addEventListener('message', onMsg, false); 137 | 138 | return function (opts) { 139 | opts = extend({}, push.defaults, opts); 140 | 141 | //iframe 142 | var ifrId = 'jsonpifr' + getUid(), ifrEl, 143 | tmpEl = document.createElement('div'); 144 | tmpEl.innerHTML = ''; 145 | ifrEl = tmpEl.childNodes[0]; 146 | bodyEl.appendChild(ifrEl); 147 | 148 | //响应函数 149 | msgcb[ifrId] = function (rs) { 150 | //回调 151 | callback(JSON.parse(rs), opts); 152 | 153 | //释放回调函数 154 | msgcb[ifrId] = null; 155 | 156 | //删除节点 157 | bodyEl.removeChild(ifrEl); 158 | !formId && bodyEl.removeChild(formEl); 159 | }; 160 | 161 | //form 162 | var formId = opts.formId, formEl; 163 | //带file的form提交 164 | if (formId) { 165 | formEl = document.getElementById(formId); 166 | formEl.enctype = 'multipart/form-data'; 167 | } 168 | else { 169 | formEl = document.createElement('form'); 170 | formEl.style.display = 'none'; 171 | } 172 | var url = opts.url; 173 | formEl.action = url + (url.indexOf('?') !== -1 ? '&' : '?') + 'jsonp=' + ifrId; 174 | formEl.method = opts.method; 175 | formEl.target = ifrId; 176 | //遍历data,加到form 177 | var data = opts.data; 178 | for (var p in data) { 179 | var inputEl = document.createElement('input'); 180 | 181 | inputEl.type = 'hidden'; 182 | inputEl.name = p; 183 | inputEl.value = data[p]; 184 | formEl.appendChild(inputEl); 185 | } 186 | 187 | //提交 188 | !formId && bodyEl.appendChild(formEl); 189 | formEl.submit(); 190 | }; 191 | 192 | })(); 193 | 194 | //push数据默认配置项 195 | push.defaults = { 196 | method: 'POST' 197 | }; 198 | 199 | 200 | return { 201 | getScript: getScript, 202 | get: get, 203 | push: push 204 | }; 205 | 206 | })(); 207 | 208 | 209 | //CommonJS 210 | if (typeof exports === 'object') { 211 | return module.exports = jsonp; 212 | } 213 | 214 | //添加到全局 215 | window.jsonp = jsonp; 216 | 217 | })(window); -------------------------------------------------------------------------------- /ie8/query.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | //参数操作对象 4 | var query = (function () { 5 | var encodeURIComponent = window.encodeURIComponent, 6 | decodeURIComponent = window.decodeURIComponent, 7 | query = { 8 | allData: parse(), 9 | getItem: getItem, 10 | parse: parse, 11 | stringify: stringify 12 | }; 13 | 14 | //获取参数函数 15 | function getItem(key) { 16 | if (!key) { 17 | return; 18 | } 19 | return query.allData[key]; 20 | } 21 | 22 | //将对象转为参数字符函数 23 | function stringify(obj, isNotnull) { 24 | if (typeof obj !== 'object') return; 25 | 26 | var array = []; 27 | for (var p in obj) { 28 | var val = obj[p], 29 | kvStr = p + '=' + encodeURIComponent(val); 30 | 31 | //是否只拼接非空 32 | isNotnull ? val && array.push(kvStr) : array.push(kvStr); 33 | } 34 | return array.join('&'); 35 | } 36 | 37 | //将参数字符转为对象函数 38 | function parse(str) { 39 | str || (str = location.search.slice(1)); 40 | 41 | // 字符 42 | if (typeof str === 'string' && str) { 43 | var rs = {}, 44 | kvs = str.split('&'); 45 | for (var i = 0, len = kvs.length; i < len; i++) { 46 | var kv = kvs[i].split('='), 47 | key = kv[0], 48 | val = kv[1]; 49 | val !== undefined && (rs[key] = decodeURIComponent(val)); 50 | } 51 | return rs; 52 | } 53 | return null; 54 | } 55 | 56 | return { 57 | stringify: stringify, 58 | parse: parse, 59 | getItem: getItem 60 | }; 61 | })(); 62 | 63 | 64 | //CommonJS 65 | if (typeof exports === 'object') { 66 | return module.exports = query; 67 | } 68 | 69 | //添加到全局 70 | window.query = query; 71 | 72 | })(window); 73 | 74 | 75 | // 查询字符操作对象 76 | /* 77 | var query = (function() { 78 | var Object = window.Object, 79 | decodeURIComponent = window.decodeURIComponent, 80 | encodeURIComponent = window.encodeURIComponent; 81 | 82 | // 查询字符转为对象 83 | function parse(str) { 84 | str || (str = location.search.slice(1)); 85 | if (str) { 86 | var rs = {}; 87 | str.split('&').forEach(function(item) { 88 | var kvs = item.split('='); 89 | rs[kvs[0]] = decodeURIComponent(kvs[1]); 90 | }); 91 | return rs; 92 | } 93 | return null; 94 | } 95 | 96 | // 对象转为查询字符 97 | function stringify(obj) { 98 | Object.keys(obj).map(function(key) { 99 | return key + '=' + encodeURIComponent(obj[key]); 100 | }).join('&'); 101 | } 102 | 103 | return { 104 | parse: parse, 105 | stringify: stringify 106 | }; 107 | })();*/ 108 | -------------------------------------------------------------------------------- /ie8/storage.js: -------------------------------------------------------------------------------- 1 | (function (window) { 2 | 3 | //storage操作对象 4 | var storage = (function () { 5 | 6 | var localStorage = window.localStorage, 7 | Date = window.Date, 8 | toString = {}.toString, 9 | //过期时间前缀 10 | expirePrefix = '_expire_'; 11 | 12 | //IE8- 13 | if (!localStorage) { 14 | return; 15 | } 16 | 17 | /** 18 | * 设置localStorage函数 19 | * @param {string} key 键 20 | * @param {string} val 值 21 | * @param {Date|number} days 过期时间|过期天数 22 | * @param {number} hours 过期小时数 23 | */ 24 | function setItem(key, val, days, hours) { 25 | //如设值为空 26 | if (val === undefined || val === null) { 27 | return; 28 | } 29 | 30 | var expire, now = new Date(); 31 | 32 | //days参数是一个日期 33 | if (toString.call(days) === '[object Date]') { 34 | expire = +days; 35 | } 36 | //过期天数 37 | else if (typeof days === 'number') { 38 | expire = now.setDate(now.getDate() + days); 39 | } 40 | //过期小时数 41 | else if (typeof hours === 'number') { 42 | expire = now.setHours(now.getHours() + hours); 43 | } 44 | //默认过期天数为1天 45 | else { 46 | expire = now.setDate(now.getDate() + 1); 47 | } 48 | 49 | localStorage.setItem(key, val); 50 | localStorage.setItem(expirePrefix + key, expire); 51 | } 52 | 53 | //获取 54 | function getItem(key) { 55 | var date = new Date(), 56 | expire = localStorage.getItem(expirePrefix + key); 57 | 58 | //判断过期时间,如未过期 59 | if (expire && +expire > +date) { 60 | return localStorage.getItem(key); 61 | } 62 | //已过期就清除 63 | else { 64 | removeItem(key); 65 | return null; 66 | } 67 | } 68 | 69 | //清除 70 | function removeItem(key) { 71 | localStorage.removeItem(key); 72 | localStorage.removeItem(expirePrefix + key); 73 | } 74 | 75 | return { 76 | setItem: setItem, 77 | getItem: getItem, 78 | removeItem: removeItem 79 | }; 80 | })(); 81 | 82 | 83 | //CommonJS 84 | if (typeof exports === 'object') { 85 | return module.exports = storage; 86 | } 87 | 88 | //添加到全局 89 | window.storage = storage; 90 | 91 | })(window); -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/js/2861b6e188071037442ff185c3c33dd2460a3e3e/img/1.jpg -------------------------------------------------------------------------------- /img/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/js/2861b6e188071037442ff185c3c33dd2460a3e3e/img/2.jpg -------------------------------------------------------------------------------- /img/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/js/2861b6e188071037442ff185c3c33dd2460a3e3e/img/3.jpg -------------------------------------------------------------------------------- /img/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/js/2861b6e188071037442ff185c3c33dd2460a3e3e/img/4.jpg -------------------------------------------------------------------------------- /img/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soneway/js/2861b6e188071037442ff185c3c33dd2460a3e3e/img/5.jpg -------------------------------------------------------------------------------- /jsonp.js: -------------------------------------------------------------------------------- 1 | // 获取uid函数 2 | const getUid = (() => { 3 | let uid = 0; 4 | return () => ++uid; 5 | })(); 6 | 7 | // 获取?或者&号 8 | function getSymbol(url) { 9 | return url.indexOf('?') < 0 ? '?' : '&'; 10 | } 11 | 12 | // 判断是否为function函数 13 | function isFunction(fn) { 14 | return typeof fn === 'function'; 15 | } 16 | 17 | // 加载js函数 18 | const getScript = (() => { 19 | const headEl = document.head; 20 | const jsReg = /(\.js)$/; 21 | 22 | return (url, fn) => { 23 | const isJs = jsReg.test(url); 24 | const scriptEl = document.createElement('script'); 25 | 26 | // type 27 | scriptEl.type = 'text/javascript'; 28 | 29 | // onload 30 | scriptEl.onload = () => { 31 | isFunction(fn) && fn(); 32 | isJs || headEl.removeChild(scriptEl); 33 | }; 34 | 35 | // onerror 36 | scriptEl.onerror = (err) => { 37 | isFunction(fn) && fn(err); 38 | }; 39 | 40 | // 请求 41 | scriptEl.src = url; 42 | headEl.appendChild(scriptEl); 43 | }; 44 | })(); 45 | 46 | // get数据函数 47 | function get(opts) { 48 | // 配置项 49 | opts = Object.assign({}, get.defaults, opts); 50 | let { url, data } = opts; 51 | // callback可用于统计 52 | const { success, error, callback } = opts; 53 | 54 | // url判断 55 | if (!url) { 56 | return console.error('请求的url不能为空'); 57 | } 58 | 59 | // 回调函数名 60 | const cbName = `jsonpcb${getUid()}`; 61 | 62 | // 将回调函数添加到全局变量 63 | window[cbName] = (rs) => { 64 | // 回调 65 | isFunction(success) && success(rs); 66 | isFunction(callback) && callback(opts, rs); 67 | // 释放回调函数 68 | window[cbName] = null; 69 | }; 70 | 71 | // url中添加callback 72 | Object.assign(data || (data = {}), { 73 | callback: cbName 74 | }); 75 | 76 | // 拼接data 77 | if (data) { 78 | url += getSymbol(url) + Object.keys(data).map((item) => `${item}=${encodeURIComponent(data[item])}`).join('&'); 79 | } 80 | 81 | // 发起请求 82 | getScript(url, (err) => { 83 | // js加载出错 84 | if (err) { 85 | // 回调 86 | isFunction(error) && error(err); 87 | isFunction(callback) && callback(opts); 88 | // 释放回调函数 89 | window[cbName] = null; 90 | } 91 | }); 92 | } 93 | // get数据默认配置项 94 | get.defaults = {}; 95 | 96 | 97 | // post数据函数 98 | const post = (() => { 99 | // 回调函数对象 100 | const msgcb = {}; 101 | const bodyEl = document.body; 102 | // 临时元素 103 | const tmpEl = document.createElement('div'); 104 | 105 | // 绑定消息事件 106 | window.addEventListener('message', (evt) => { 107 | let { data } = evt; 108 | 109 | // data转对象 110 | typeof data === 'object' || (data = JSON.parse(data || null) || {}); 111 | 112 | // 回调函数 113 | const callback = msgcb[data.id]; 114 | isFunction(callback) && callback(data.rs); 115 | }); 116 | 117 | return (opts) => { 118 | // 配置项 119 | opts = Object.assign({}, post.defaults, opts); 120 | const { success, error, callback, formSelector, url, method, data, enctype } = opts; 121 | 122 | // iframe元素 123 | const ifrId = `postifr${getUid()}`; 124 | tmpEl.innerHTML = ``; 125 | const ifrEl = tmpEl.childNodes[0]; 126 | bodyEl.appendChild(ifrEl); 127 | 128 | // form元素 129 | let formEl; 130 | // 页面中已存在的form提交 131 | if (formSelector) { 132 | formEl = document.querySelector(formSelector); 133 | // 请求url中添加callback信息 134 | const { action } = formEl; 135 | formEl.action = `${action + getSymbol(action)}msgcb=${ifrId}`; 136 | } 137 | // 动态生成的form提交 138 | else { 139 | // 请求url 140 | const action = `${url + getSymbol(url)}msgcb=${ifrId}`; 141 | // 数据添加到form的input 142 | const inputHtml = data && Object.keys(data).map((key) => ``).join(''); 143 | tmpEl.innerHTML = `
${inputHtml}
`; 144 | formEl = tmpEl.childNodes[0]; 145 | } 146 | // target 147 | formEl.target = ifrId; 148 | // enctype 149 | enctype && (formEl.enctype = enctype); 150 | 151 | // message事件响应函数 152 | msgcb[ifrId] = (rs) => { 153 | // 回调 154 | isFunction(success) && success(rs); 155 | isFunction(callback) && callback(opts, rs); 156 | // 释放回调函数 157 | msgcb[ifrId] = null; 158 | 159 | // 删除节点 160 | bodyEl.removeChild(ifrEl); 161 | formSelector || bodyEl.removeChild(formEl); 162 | }; 163 | 164 | // iframe onload事件,主要处理请求失败 165 | ifrEl.onload = () => { 166 | // 延迟运行 167 | setTimeout(() => { 168 | // 如果回调还在,说明没有成功回调,即发生错误 169 | if (msgcb[ifrId]) { 170 | // 回调 171 | isFunction(error) && error(); 172 | isFunction(callback) && callback(opts); 173 | // 释放回调函数 174 | msgcb[ifrId] = null; 175 | 176 | // 删除节点 177 | bodyEl.removeChild(ifrEl); 178 | formSelector || bodyEl.removeChild(formEl); 179 | } 180 | }, 100); 181 | }; 182 | 183 | // 提交 184 | formSelector || bodyEl.appendChild(formEl); 185 | formEl.submit(); 186 | }; 187 | })(); 188 | // post数据默认配置项 189 | post.defaults = { 190 | method: 'POST' 191 | }; 192 | 193 | 194 | export default { 195 | // 加载js函数 196 | getScript, 197 | // get数据函数 198 | get, 199 | // post数据函数 200 | post 201 | }; 202 | -------------------------------------------------------------------------------- /object.js: -------------------------------------------------------------------------------- 1 | // 根据path安全取对象属性函数 2 | Object.getValByPath = (obj, path, defaultVal) => { 3 | const paths = path.split('.'); 4 | 5 | // 遍历路径 6 | const val = paths.reduce((prev, item) => { 7 | if (prev === undefined || prev === null) { 8 | return prev; 9 | } 10 | return prev[item]; 11 | }, obj); 12 | 13 | // 如拿到的值为undefined,返回默认值 14 | if (val === undefined) { 15 | return defaultVal; 16 | } 17 | return val; 18 | }; 19 | -------------------------------------------------------------------------------- /perf.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | perf test 5 | 49 | 50 | 51 | 52 | 53 |
54 | 55 |
56 | 57 | 58 |
59 |
60 |
61 | 62 |
63 |

正在加载...

64 |
65 |
66 | 67 | 68 | 69 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |
95 |
96 |

97 | 98 |

99 |

100 | 101 |

102 |
103 |

活动规则:

104 | 105 | 106 |

活动时间:

107 | 即日起-2014年5月19日 108 | 109 |

参与方式:

110 |

一、 许愿有奖

111 | 1. 登录本专题;
112 | 2. 在活动页面选择/填写个人梦想;
113 | 3. 选择一位圆梦大使
114 | 4. 提交作品并分享;
115 | 5. 参加转盘抽奖。
116 | ● 全新凯美瑞环游团,将从所有征集到的愿望中随机选取有意思的愿望,在环游世界的旅途中,在异国他乡尽其所能地为您实现梦想!
117 | ● 提交梦想后,别忘了在补填资料中留下您的梦想明细哦,比如TA的联系方式~;您的愿望一旦被选中,这些信息将帮助我们的圆梦大使为您实现梦想;主办方会为您严格保密此部分信息。
118 | ● “为可能 尽所能”跟搜狐自媒体人环游世界86天 119 | 【了解详情】 120 |

二、 分享有奖

121 | 1. 登录本专题;
122 | 2. 分享梦想作品;
123 | 3. 参加转盘抽奖。 124 |

三、有奖试驾

125 | 1. 除了提交愿望或者分享愿望作品,您还可以在“补填资料“或“有奖试驾”对话框中预约试驾全新凯美瑞,完成试驾信息填写的用户,均可参加试驾豪礼大抽奖。
126 | 2. 主办方将于5月21日进行抽奖,并在5月25日前公布获奖名单。
127 | 3. 每个手机号只能预约一次试驾,试驾信息提交后不能修改,请注意填写正确信息哦! 128 |

四、抽奖规则:

129 | 1、 用户只有在登录状态下参与互动,才能获得抽奖机会;
130 | 2、 上传一个愿望,获得3次转盘抽奖机会;单独分享愿望作品一次,获得1次转盘抽奖机会;每个账号每天最高获得15次转盘抽奖机会;
131 | 3、 活动奖品:
132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
奖品类别奖品设置奖品数量
试驾豪礼iPadmini 31
500元京东电子购物卡10
转盘抽奖100元手机充值话费30
50元手机充值话费30
小狐狸公仔一只50
活动定制T恤一件50
165 | (1)、所有奖品将于活动结束后统一派发。
166 | (2)、中奖信息会以网站公告的方式告知,请活动参与者密切关注活动网站。请获奖用户填写完整的个人信息,以确保奖品能准确送达;个人信息一旦提交,不可修改;若因用户资料填写不全或不正确,而导致奖品无法成功送达,视为自动放弃获奖机会,主办方不再补发礼品。
167 | (3)、100元及以上价值礼品,需凭身份证复印件(或扫描件/电子照片)领奖,身份证信息需与登记的个人信息吻合,否则视为自动放弃获奖机会。
168 | (4)、电子购物卡及手机话费充值等奖品,若在采购过程中遇到缺货等情况,将采用同类等值礼品替代。 169 | 170 |

活动声明:

171 | 1、本活动的主办方为 广汽丰田汽车有限公司(以下统一简称活动“主办方”),搜狐网为本活动的主办合作媒体。
172 | 2、主办方及搜狐网保留对本次活动所有作品(文字、照片、视频等)的出版权,用于印刷,广播,电子媒体或其他媒体,而不需要经过参赛者的许可,或支付参赛者任何费用。
173 | 3、主办方有权取消和删除任何违反规则、条例或侵犯版权的个人作品。
174 | 4、主办方将不承担任何由参赛者引起的侵犯版权或其它法律纠纷,并有权在需要时修改活动阶段,奖品及其规则,恕不另行通知。
175 | 5、所有用户参与活动时不得发布危害国家安全、泄露国家秘密的言论,不得侵犯国家、社会、集体和公民的合法权益,不得发布国家法律法规明令禁止的内容,如因留言导致任何法律纠纷,主办方及搜狐网均不承担责任。
176 | 6、主办方有权力在不通知用户的前提下删除违反、侵权、诽谤、不道德的言论。
177 | 7、如发现用户在活动中使用任何不正当手段参与活动,主办方有权不通知用户直接取消用户任何获奖资格。
178 | 8、所有活动参赛者视为接受上述规则和条例。
179 | 9、在法律允许的范围内,主办方对本次活动拥有最终解释权和决策权。 180 |
181 |
182 |
183 | 184 | 185 | 186 |
187 |
188 |

1.选择你的愿望

189 | 191 | 192 |

2.选择你的圆梦大使

193 | 195 | 确定提交 196 |
197 |
198 | 199 | 200 | 201 |
202 |
203 |

204 | 即日起-5月19日,登记试驾信息,
205 | 有机会赢取iPadmini3 及 电商购物卡哦!
206 | (活动详情请见 首页 [活动规则]) 207 |

208 | 209 | 210 | 211 | 214 | 215 | 216 | 217 | 221 | 222 | 223 | 224 | 227 | 228 | 229 | 230 | 233 | 234 | 235 | 236 | 239 | 240 |
*姓名 212 | 213 |
*手机 218 | 219 | 220 |
*省份 225 | 226 |
*城市 231 | 232 |
*经销商 237 | 238 |
241 | 确定提交 242 |
243 |
244 | 245 | 246 | 247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 | 点击加载更多 257 |
258 |
259 | 260 | 261 | 262 |
263 |
264 |
265 | 266 |
267 |

我的抽奖次数:loading...

268 |
269 | 270 | 271 | 272 |
273 | 375 |
376 | 377 | 378 | 379 |
380 |
381 |

382 | 383 |

384 |
385 |
386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 |
395 |
396 | 397 | 398 | 399 |
400 |
401 | 402 | 403 | 404 | 407 | 408 | 409 | 410 | 413 | 414 | 415 | 416 | 420 | 421 |
*姓名 405 | 406 |
*手机 411 | 412 |
备注 417 | 419 |
422 |

423 | 一旦提交,将不能更改,此信息关乎您中奖后派发奖品途径,请谨慎填写,确保无误! 424 |

425 |

426 | 完善以下试驾信息,
427 | 有机会赢取iPadmini3 及 电商购物卡哦!
428 | (活动详情请见 首页 [活动规则]) 429 |

430 |

试驾全新凯美瑞

431 | 432 | 433 | 434 | 437 | 438 | 439 | 440 | 443 | 444 | 445 | 446 | 449 | 450 |
省份 435 | 436 |
城市 441 | 442 |
经销商 447 | 448 |
451 | 确定提交 452 |
453 |
454 | 455 | 456 | 457 |
458 |
459 | 460 | 461 | 462 |
463 |
464 |

465 | 466 | 467 | 468 |

469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 |

478 |
479 |
480 | 481 | 482 | 483 | 484 | 485 | 486 | 504 | 505 | 506 |
507 | 508 | 509 | 510 | 551 | 552 |
553 | 554 | 555 |
556 | 557 |
558 | 559 | 560 |
561 | 562 | 563 | 564 | 565 | 566 |

567 | 568 | 569 |

570 | 571 |

572 | 573 | 574 | 687 | 688 | -------------------------------------------------------------------------------- /perf.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 3 | var perf = (function() { 4 | //打印函数 5 | function logPerfInfo(fn, times, start, end, msgEl) { 6 | var fnStr = fn + ''; 7 | 8 | fnStr = fnStr.slice(fnStr.indexOf('{') + 1); 9 | fnStr = fnStr.slice(0, fnStr.length - 1); 10 | 11 | var logStr = fnStr + '运行' + times + '次时长:' + (end - start).toFixed(2) + 'ms\n' + '运行结果:' + JSON.stringify(fn(), null, '\t'); 12 | msgEl ? msgEl.textContent += logStr + '\n' : console.log(logStr); 13 | } 14 | 15 | //支持performance 16 | var performance = window.performance; 17 | if (performance) { 18 | //performance.mark 19 | performance.mark || (performance.mark = performance.webkitMark || performance.msMark || performance.mozMark); 20 | 21 | //支持performance.mark 22 | if (performance.mark) { 23 | performance.getEntriesByName || (performance.getEntriesByName = performance.webkitGetEntriesByName || performance.msGetEntriesByName || performance.mozGetEntriesByName); 24 | 25 | return function(fn, times, msgEl) { 26 | //默认运行100万次 27 | times || (times = 999999); 28 | 29 | var rand = Date.now(); 30 | 31 | //开始时间 32 | performance.mark('start' + rand); 33 | for (var i = 0; i < times; i++) { 34 | fn(); 35 | } 36 | //结束时间 37 | performance.mark('end' + rand); 38 | 39 | var start = performance.getEntriesByName('start' + rand)[0].startTime, 40 | end = performance.getEntriesByName('end' + rand)[0].startTime; 41 | 42 | logPerfInfo(fn, times, start, end, msgEl); 43 | }; 44 | } 45 | } 46 | 47 | //不支持performance.mark 48 | return function(fn, times, msgEl) { 49 | //默认运行100万次 50 | times || (times = 999999); 51 | 52 | //开始时间 53 | var start = +new Date; 54 | for (var i = 0; i < times; i++) { 55 | fn(); 56 | } 57 | //结束时间 58 | var end = +new Date; 59 | 60 | logPerfInfo(fn, times, start, end, msgEl); 61 | }; 62 | 63 | })(); 64 | 65 | 66 | //CommonJS 67 | if (typeof exports === 'object') { 68 | return module.exports = perf; 69 | } 70 | 71 | window.perf = perf; 72 | 73 | })(); -------------------------------------------------------------------------------- /query.js: -------------------------------------------------------------------------------- 1 | // 所有的查询字符对象 2 | const queryData = parse(); 3 | 4 | // 获取项 5 | function getItem(key) { 6 | if (!key) { 7 | return; 8 | } 9 | return parse()[key]; 10 | } 11 | 12 | // 查询字符转为对象 13 | function parse(str) { 14 | str || (str = location.search.slice(1)); 15 | 16 | const rs = {}; 17 | // 字符 18 | if (typeof str === 'string' && str) { 19 | str.split('&').forEach((item) => { 20 | const kv = item.split('='); 21 | const key = kv[0]; 22 | const val = kv[1]; 23 | val !== undefined && (rs[key] = decodeURIComponent(val)); 24 | }); 25 | } 26 | return rs; 27 | } 28 | 29 | // 对象转为查询字符 30 | function stringify(obj) { 31 | return Object.keys(obj).map((key) => { 32 | return key + '=' + encodeURIComponent(obj[key]); 33 | }).join('&'); 34 | } 35 | 36 | 37 | // 查询字符处理类 38 | export default { 39 | getItem, 40 | parse, 41 | stringify 42 | }; 43 | 44 | export { queryData }; 45 | -------------------------------------------------------------------------------- /storage.js: -------------------------------------------------------------------------------- 1 | const { toString } = {}; 2 | // 过期时间前缀 3 | const expirePrefix = '_expire_'; 4 | 5 | /** 6 | * 设置localStorage函数 7 | * @param {string} key 键 8 | * @param {string} val 值 9 | * @param {Date|number} days 过期时间|过期天数 10 | * @param {number} hours 过期小时数 11 | */ 12 | function setItem(key, val, days, hours) { 13 | // 如设值为空 14 | if (val === undefined || val === null) { 15 | return; 16 | } 17 | 18 | let expire, 19 | now = new Date(); 20 | 21 | //days参数是一个日期 22 | if (toString.call(days) === '[object Date]') { 23 | expire = +days; 24 | } 25 | //过期天数 26 | else if (typeof days === 'number') { 27 | expire = now.setDate(now.getDate() + days); 28 | } 29 | //过期小时数 30 | else if (typeof hours === 'number') { 31 | expire = now.setHours(now.getHours() + hours); 32 | } 33 | //默认过期天数为1天 34 | else { 35 | expire = now.setDate(now.getDate() + 1); 36 | } 37 | 38 | localStorage.setItem(key, val); 39 | localStorage.setItem(expirePrefix + key, expire); 40 | } 41 | 42 | /** 43 | * 获取 44 | * @param {string} key 键 45 | * @returns {string} 值 46 | */ 47 | function getItem(key) { 48 | const date = new Date(), 49 | expire = localStorage.getItem(expirePrefix + key); 50 | 51 | //判断过期时间,如未过期 52 | if (expire && +expire > +date) { 53 | return localStorage.getItem(key); 54 | } 55 | //已过期就清除 56 | else { 57 | removeItem(key); 58 | return null; 59 | } 60 | } 61 | 62 | /** 63 | * 清除 64 | * @param {string} key 键 65 | */ 66 | function removeItem(key) { 67 | localStorage.removeItem(key); 68 | localStorage.removeItem(expirePrefix + key); 69 | } 70 | 71 | 72 | // storage操作对象 73 | export default { 74 | setItem, 75 | getItem, 76 | removeItem 77 | }; 78 | --------------------------------------------------------------------------------