1 - Html+Jquery

这个目录里面的内容均整理在2017年以前。有些内容已经不适合现在的项目了, 用之前需要整理和验证

1.1 - jquery插件开发

<!DOCTYPE html>
<html lang="en" >
<head>
    <meta charset="utf-8" />
    <title>HTML5 时钟</title>
    <link href="css/main.css" rel="stylesheet" type="text/css" />
    <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <style>
    .clocks {
      height: 500px;
      margin: 25px auto;
      position: relative;
      width: 500px;
    }
  </style>
</head>
<body>
    <ul>
    <li>
        <a href="http://www.webo.com/liuwayong">我的微博</a>
    </li>
    <li>
        <a href="http://http://www.cnblogs.com/Wayou/">我的博客</a>
    </li>
    <li>
        <a href="http://wayouliu.duapp.com/">我的小站</a>
    </li>
</ul>
<div>
    这是div标签
</div>
</body>
<script>
/*
1.直接扩展jquery 添加方法 sayHello();
*/
// $.extend({
//     sayHello: function(name) {
//         alert('Hello,' + (name ? name : 'Dude'));
//     }
// });
// $.sayHello(); //调用
// $.sayHello('Wayou'); //带参调用


/*
2.在全局空间定义myPlugin
*/
// $.fn.myPlugin = function(options) {
//     var defaults = {//定义默认参数
//         'color': 'red',
//         'fontSize': '12px'
//     };
//     var settings = $.extend({}, defaults, options);//合并用户的options 和默认的defaults到插件空间
//     return this.css({//返回方法,利于链式操作
//         'color': settings.color,
//         'fontSize': settings.fontSize
//     });
// }
// $(function(){
//     $('a').myPlugin({
//         'color': '#2C9929',
//         'fontSize': '36px'
//     });
//     $('div').myPlugin();
// })


/*
3.在全局空间中定义匿名函数,中定义一个插件
在匿名函数前面加一个";"是一个好的习惯
($, window, document, undefined)匿名函数的参数是为了防止其他人全局屏蔽这几个参数
*/
;(function($, window, document, undefined){
    //定义Beautifier的构造函数
    var Beautifier = function(ele, opt) {
        this.$element = ele,
        this.defaults = {
            'color': 'red',
            'fontSize': '12px',
            'textDecoration':'none'
        },
        this.options = $.extend({}, this.defaults, opt)
    }
    //定义Beautifier的方法
    Beautifier.prototype = {
        beautify: function() {
            return this.$element.css({
                'color': this.options.color,
                'fontSize': this.options.fontSize,
                'textDecoration': this.options.textDecoration
            });
        }
    }
    //在插件中使用Beautifier对象
    $.fn.myPlugin = function(options) {
        //创建Beautifier的实体
        var beautifier = new Beautifier(this, options);
        //调用其方法
        //return beautifier;//用于3.1调用
        return beautifier.beautify();//用于3.2调用
    }
})(jQuery, window, document);
//3.1调用
// $(function() {
//     $('a').myPlugin({
//         'color': '#2C9929',
//         'fontSize': '12px'
//     }).beautify();
// })
//3.2调用
$(function(){
    $('a').myPlugin({
        'color': '#2C9929',
        'fontSize': '20px',
        'textDecoration': 'underline'
    });
});
</script>
</html>

1.2 - js获取各种节点的方法

如何获取要更新的元素,是首先要解决的问题。令人欣慰的是,使用JavaScript获取节点的方法有很多种,这里简单做一下总结(以下方法在IE7和Firefox2.0.0.11测试通过):
1. 通过顶层document节点获取:
    (1) document.getElementById(elementId):该方法通过节点的ID,可以准确获得需要的元素,是比较简单快捷的方法。如果页面上含有多个相同id的节点,那么只返回第一个节点。
    如今,已经出现了如prototype、Mootools等多个JavaScript库,它们提供了更简便的方法:$(id),参数仍然是节点的id。这个方法可以看作是document.getElementById()的另外一种写法,不过$()的功能更为强大,具体用法可以参考它们各自的API文档。
    (2)document.getElementsByName(elementName):该方法是通过节点的name获取节点,从名字可以看出,这个方法返回的不是一个节点元素,而是具有同样名称的节点数组。然后,我们可以通过要获取节点的某个属性来循环判断是否为需要的节点。
    例如:在HTML中checkbox和radio都是通过相同的name属性值,来标识一个组内的元素。如果我们现在要获取被选中的元素,首先获取改组元素,然后循环判断是节点的checked属性值是否为true即可。
    (3)document.getElementsByTagName(tagName):该方法是通过节点的Tag获取节点,同样该方法也是返回一个数组,例如:document.getElementsByTagName('A')将会返回页面上所有超链接节点。在获取节点之前,一般都是知道节点的类型的,所以使用该方法比较简单。但是缺点也是显而易见,那就是返回的数组可能十分庞大,这样就会浪费很多时间。那么,这个方法是不是就没有用处了呢?当然不是,这个方法和上面的两个不同,它不是document节点的专有方法,还可以应用其他的节点,下面将会提到。
2、通过父节点获取:
    (1)parentObj.firstChild:如果节点为已知节点(parentObj)的第一个子节点就可以使用这个方法。这个属性是可以递归使用的,也就是支持parentObj.firstChild.firstChild.firstChild...的形式,如此就可以获得更深层次的节点。
    (2)parentObj.lastChild:很显然,这个属性是获取已知节点(parentObj)的最后一个子节点。与firstChild一样,它也可以递归使用。
    在使用中,如果我们把二者结合起来,那么将会达到更加令人兴奋的效果,即:parentObj.firstChild.lastChild.lastChild...
    (3)parentObj.childNodes:获取已知节点的子节点数组,然后可以通过循环或者索引找到需要的节点。
    注意:经测试发现,在IE7上获取的是直接子节点的数组,而在Firefox2.0.0.11上获取的是所有子节点即包括子节点的子节点。
    (4)parentObj.children:获取已知节点的直接子节点数组。
    注意:经测试,在IE7上,和childNodes效果一样,而Firefox2.0.0.11不支持。这也是为什么我要使用和其他方法不同样式的原因。因此不建议使用。
    (5)parentObj.getElementsByTagName(tagName):使用方法不再赘述,它返回已知节点的所有子节点中类型为指定值的子节点数组。例如:parentObj.getElementsByTagName('A')返回已知的子节点中的所有超链接。
3、通过临近节点获取:
    (1)neighbourNode.previousSibling:获取已知节点(neighbourNode)的前一个节点,这个属性和前面的firstChild、lastChild一样都似乎可以递归使用的。
    (2)neighbourNode.nextSibling:获取已知节点(neighbourNode)的下一个节点,同样支持递归。
4、通过子节点获取:
    (1)childNode.parentNode:获取已知节点的父节点。

上面提到的方法,只是一些基本的方法,如果使用了Prototype等JavaScript库,可能还获得其他不同的方法,例如通过节点的class获取等等。不过,如果能够灵活运用上面的各种方法,相信应该可以应付大部分的程序

1.3 - reset.css

@charset "utf-8";

/*css reset*/
body,nav,dl,dt,dd,p,h1,h2,h3,h4,ul,ol,li,input,button,textarea,footer{margin:0;padding:0}
body{font:16px/1.5 'Microsoft Yahei','Simsun';  color:#333;background:#fff;-webkit-text-size-adjust: none; min-width:320px;}
h1,h2,h3,h4,h5,h6{font-size:100%}
form{display:inline}
ul,ol{list-style:none}
a{text-decoration:none;color:#1a1a1a}
a:hover, a:active, a:focus{color:#1a1a1a;text-decoration: none;}
a:active{color:#1a1a1a;}
img{vertical-align:middle;border:0;-ms-interpolation-mode:bicubic;}
button,input,select,textarea{font-size:100%; vertical-align:middle;outline:none;}
textarea{resize:none}
button,input[type="button"],input[type="reset"],input[type="submit"] {cursor:pointer;-webkit-appearance:button;-moz-appearance:button}
input:focus:-moz-placeholder,input:focus::-webkit-input-placeholder {color:transparent}
button::-moz-focus-inner,input::-moz-focus-inner { padding:0; border:0}
table { border-collapse:collapse; border-spacing:0}
.fl{float:left;}.fr{float:right;}.hide{display:none;}.show{display: block;}
.ellipsis { white-space:nowrap; text-overflow:ellipsis; overflow:hidden}
.break { word-break:break-all; word-wrap:break-word}
header, footer, article, section, nav, menu, hgroup {display: block;clear:all;}
.clear {zoom:1;}
.clear:after {content:'';display:block;clear:both;height:0;}

.main{width: 100%;font-size: 62.5%;}

1.4 - 曾经的纯JavaScript基础

如题这是曾经纯JavaScript基础,有些写法语法和最新得瑟ES6语法不适用了。留作纪念吧!
控制台输出内容  console.log("content");

数据类型:
    Number(整数,浮点数,NaN, Infinity)
    Boolean
    null表示一个"空"的值
    undefined表示"未定义"
    NaN === NaN; // false
    isNaN(NaN); // true

一定要使用静态模式
    在文件或者脚本的最上面写上'use strict'
    之后定义变量必须使用var关键字,如果忘记写var则会在控制台报ReferenceError错误
    创建对象的构造函数,在strict模式下this.name = name将报错因为this绑定为undefined在非strict模式下this.name = name不报错因为this绑定为window于是无意间创建了全局变量name并且返回undefined这个结果更糟糕
字符串可以用 `` 支持多行模式
    alert(`多行
    字符串
    测试`);
字符串常用
    s.length;
    s.toUpperCase();//大写
    s.toLowerCase();//小写
    s.indexOf("..");搜索指定字符串出现的位置
    s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
    s.substring(7); // 从索引7开始到结束,返回'world'
数组常用
    arr.length;
    arr.indexOf(value);元素 value 的索引位置
    arr.slice();//对应string的substring函数
    push('A', 'B')向Array的末尾添加若干元素
    arr.pop();//删除数组最后的元素并返回它
    arr.unshift('A', 'B');//往Array的头部添加若干元素
    arr.shift();//删除数组第一个元素并返回
    arr.sort();//数组排序,具体在函数部分
    arr.reverse();//反转数组
    arr.concat(arr2);//连接两个数组
    arr.join('-');//用-将数组连接起来成字符串

对象常用
obj.属性key = 属性value;
delete obj.属性key
'属性key' in ojb;//属性key是否在obj中,继承的也算
obj.hasOwnProperty('属性key');只判断属性key是否在当前对象中

for (var i in 可迭代集合)
for...of//可以循环数组,map,set)
    for(var x of a)
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, 被迭代对象) {
    // element: 指向当前元素的值
    // index: 指向当前索引
    // 被迭代对象: 被迭代对象本身
    alert(element);
});


map--键值存储
m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);//初始化一个map
m.set('Adam', 67);
m.has('Adam');
m.get('Adam');
m.delete('Adam');

set--不重复集合
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
s.add(4)
s.delete(3);

函数
    arguments关键字,收集函数的所有参数到数组(这是隐藏的可以直接使用)
    rest关键字定义变量可以 function foo(a,b, ...rest)
        除了前两个参数,后面的存在rest数组中
    apply
        函数名.apply(被绑定对象, 函数参数)//这样使用时在函数体内的this关键字都是指向"被绑定对象"
    call -- 与apply区别
    apply()把参数打包成Array再传入
    call()把参数按顺序传入
    Math.max.apply(null, [3, 5, 4]); // 5
    Math.max.call(null, 3, 5, 4); // 5
    map() reduce()
    filter(匿名函数)//过滤,根据匿名函数返回Boolean值决定是否保留
    排序函数sort(),原则是按照(规定对于两个元素x和y如果认为x < y则返回-1如果认为x == y则返回0如果认为x > y则返回1这样排序算法就不用关心具体的比较过程而是根据比较结果直接排序),并且会修改原数组
        数字从小到大排序//从大到小
        arr.sort(function (x, y) {
            if (x < y) {
                return -1;//return 1
            }
            if (x > y) {
                return 1;//return -1
            }
            return 0;
        });
        //对字符串数组排序(按照ASCII的小到大)
        arr.sort(function (s1, s2) {
            x1 = s1.toUpperCase();
            x2 = s2.toUpperCase();
            if (x1 < x2) {
                return -1;
            }
            if (x1 > x2) {
                return 1;
            }
            return 0;
        });
    闭包
    箭头函数(相当于匿名函数)//还是用匿名函数吧

作用域
使用一个全局变量推荐 window.变量
自己写代码推荐使用一个名字空间(就是建立一个对象,自己的变量都当做对象属性操作)
申明一个块级变量用let
申请一个常量const PI = 3.14;//不可修改

生成器function* fib(参数) {}
    js引擎遇到yield就会停止并返回yield后值,并保持函数执行的所有状态,下次调用从上次yield的后面接着执行
调用生成器
    
    var f = fib(5);
    f.next(); 
    f.next(); 
    f.next(); 
    f.next(); 
    f.next(); 
    
    for (var x of fib(5)) {
        console.log(x); // 依次输出0, 1, 1, 2, 3
    }

js标准对象
typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'
总结一下有这么几条规则需要遵守

    不要使用new Number()new Boolean()new String()创建包装对象
    用parseInt()或parseFloat()来转换任意类型到number
    用String()来转换任意类型到string或者直接调用某个对象的toString()方法
    通常不必把任意类型转换为boolean再判断因为可以直接写if (myVar) {...}
    typeof操作符可以判断出numberbooleanstringfunction和undefined
    判断Array要使用Array.isArray(arr)
    判断null请使用myVar === null
    判断某个全局变量是否存在用typeof window.myVar === 'undefined'
    函数内部判断某个变量是否存在用typeof myVar === 'undefined'
    null和undefined没有toString()方法
    number使用toString()(123).toString();


JSON
var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
JSON.stringify(xiaoming); // '{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'
JSON.stringify(xiaoming, null, '  ');
{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}
JSON.stringify(xiaoming, ['name', 'skills'], '  ');
{
  "name": "小明",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}
JSON.stringify(xiaoming, convert, '  ');//每个键值都会被convert函数处理
function convert(key, value) {
    if (typeof value === 'string') {
        return value.toUpperCase();
    }
    return value;
}
在对象中重写toJSON
var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
    toJSON: function () {
        return { // 只输出name和age,并且改变了key:
            'Name': this.name,
            'Age': this.age
        };
    }
};

JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'

反序列化json
JSON.parse('json字符串')
JSON.parse('json字符串', function(key, value){
    //pass
});


js使用classs构建对象
class Student extends 父类{
    //构造函数
    constructor(name) {
        super(name); // 记得用super调用父类的构造方法!
        this.name = name;
    }

    hello() {
        alert('Hello, ' + this.name + '!');
    }
}

1.5 - 常用函数整理

/**
 * --------------------------------------------------------------------------
 * 小安整理的js函数
 * --------------------------------------------------------------------------
 * @package          JavaScript_function
 * @author           azhw
 * @since            Version 1.0
 */


/*-------------------------------------
  js获取当前url参数的两种方法 
 -------------------------------------*/
//方法一
function getQueryString(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return unescape(r[2]); return null;
}
//调用
// alert(GetQueryString("参数名1"));
// alert(GetQueryString("参数名2"));
// alert(GetQueryString("参数名3"));

//方法二
function GetRequest() {
   var url = location.search; //获取url中"?"符后的字串
   var theRequest = new Object();
   if (url.indexOf("?") != -1) {
      var str = url.substr(1);
      strs = str.split("&");
      for(var i = 0; i < strs.length; i ++) {
         theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);
      }
   }
   return theRequest;
}
//调用
// <Script language="javascript">
// var Request = new Object();
// Request = GetRequest();
// var 参数1,参数2,参数3,参数N;
// 参数1 = Request['参数1'];
// 参数2 = Request['参数2'];
// 参数3 = Request['参数3'];
// 参数N = Request['参数N'];
// </Script>
/*
---------------------------------------
*/



/*-------------------------------------
 js获取屏幕大小
 -------------------------------------*/
function a(){
document.write(
"屏幕分辨率为:"+screen.width+"*"+screen.height
+"<br />"+
"屏幕可用大小:"+screen.availWidth+"*"+screen.availHeight
+"<br />"+
"网页可见区域宽:"+document.body.clientWidth
+"<br />"+
"网页可见区域高:"+document.body.clientHeight
+"<br />"+
"网页可见区域宽(包括边线的宽):"+document.body.offsetWidth
+"<br />"+
"网页可见区域高(包括边线的宽):"+document.body.offsetHeight
+"<br />"+
"网页正文全文宽:"+document.body.scrollWidth
+"<br />"+
"网页正文全文高:"+document.body.scrollHeight
+"<br />"+
"网页被卷去的高:"+document.body.scrollTop
+"<br />"+
"网页被卷去的左:"+document.body.scrollLeft
+"<br />"+
"网页正文部分上:"+window.screenTop
+"<br />"+
"网页正文部分左:"+window.screenLeft
+"<br />"+
"屏幕分辨率的高:"+window.screen.height
+"<br />"+
"屏幕分辨率的宽:"+window.screen.width
+"<br />"+
"屏幕可用工作区高度:"+window.screen.availHeight
+"<br />"+
"屏幕可用工作区宽度:"+window.screen.availWidth
);
}
/*
------------------------------------------------
*/


/*-------------------------------------
 js模拟鼠标除法点击
 -------------------------------------*/
document.getElementById("target").onclick();  
document.getElementById("target").click();
//btnObj.click()是真正地用程序去点击按钮,触发了按钮的onclick()事件
//btnObj.onclick()只是简单地调用了btnObj的onclick所指向的方法,只是调用方法而已,并未触发事件



/*-------------------------------------
 js控制option
 -------------------------------------*/
//循环一个一个移除,可控
/*
<select name="mySelect" id="selectID">
    <option value=1>1</option>
    <option value=2>2</option>
</select>
*/
var theSelect=document.all.mySelect;
for(var i=theSelect.options.length-1;i>=0;i--)
theSelect.options.remove(i);

//删除内容
document.getElementById("selectID").innerHTML = "";

//令长度为0
document.getElementById("selectID").options.length=0; 

//删除制定位置的选项,在第一种里用过
document.getElementById("selectID").options.remove(index);

//添加内容
var selectObj=document.getElementById("selectID");
selectObj.options[selectObj.length] = new Option("mytest", "2");
//selectObj.options[index] = new Option("mytest", "2");
/*
---------------------------------------------------------
*/


/*-------------------------------------
 js日期格式转换成时间戳
 -------------------------------------*/
/**
 2  0  1  5  -  0  4  -  0  5  _  1  0  :  1  0  :  1  0
 0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18

 注: 下划线(_) 代表空格
*/
function transdate(endTime){
   var date=new Date();
   date.setFullYear(endTime.substring(0,4));
   date.setMonth(endTime.substring(5,7)-1);
   date.setDate(endTime.substring(8,10));
   date.setHours(endTime.substring(11,13));
   date.setMinutes(endTime.substring(14,16));
   date.setSeconds(endTime.substring(17,19));
   return Date.parse(date)/1000;
}
/*
------------------------------------------
*/

/*-------------------------------------
 JavaScript 获取当前时间戳:
 -------------------------------------*/

var timestamp = Date.parse(new Date());
//结果:1280977330000  获取的时间戳是把毫秒改成000显示,

var timestamp = (new Date()).valueOf();
var timestamp=new Date().getTime();
//获取了当前毫秒的时间戳

/*-------------------------------------
 js删除字符串最后一个字符
 -------------------------------------*/
//字符串:string s = "1,2,3,4,5,"
//目标:删除最后一个 "," ---> "1,2,3,4,5"
var s = "1,2,3,4,5,";
s=s.substring(0,s.length-1);
alert(s);



/*-------------------------------------
 js DOM树加载完成后加载或执行
 -------------------------------------*/
// 1 === 2
 $(function(){
  $("#a").click(function(){
    //adding your code here
  });
});
//2 === 1
$(document).ready(function(){
  $("#a").click(function(){
    //adding your code here  
  });
});
/*-------------------------------------
 js 页面加载完成后加载或执行
 整个页面的document全部加载完成以后执行,
 而且要求所有的外部图片和资源全部加载完成,
 如果外部资源,例如图片需要很长时间来加载,那么这个js效果就会让用户感觉失效了。
 js里的DOM加载完成后不知,待查
 -------------------------------------*/
//1.
window.onload = function(){
  $("#a").click(function(){
    //adding your code here
  });
} 

//2. 
function myfun(){
    alert("this window.onload");
}
window.onload=myfun;//不要括号


/*-------------------------------------
 js在页面输出日期和星期,时间
 -------------------------------------*/
var Today = new Date();
var DateName = new Array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");
var MonthName = new Array("1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月");
document.write("<span class=\"date\">" + Today.getFullYear() + "年" + MonthName[Today.getMonth()] +
Today.getDate() + "日" + "&nbsp; " + DateName[Today.getDay()] + "</span>");


/*-------------------------------------
 js控制input[type=text]获取失去焦点
 -------------------------------------*/
<input type="text" value="xiaoan" name="nick_name" onfocus="if(this.value == 'xiaoan') this.value = 'xiao'" onblur="if(this.value =='') this.value = 'xiaoa'">

<pre>
onfocus="if(this.value == 'xiaoan') this.value = 'xiao'"
</pre>
<p>当输入框获得焦点时onfocus 如果当前值为xiaoan,那么把输入框的值写成xiao</p>
<pre>
onblur="if(this.value =='') this.value = 'xiaoa'"
</pre>
<p>当输入框失去焦点时onblur 如果当前值为'',那么把输入框的值写成xiaoa</p>
<p>反正最后达到一个效果让输入框不为空</p>


/*-------------------------------------
 改变url参数并可以把不存在的参数添加进url最后
 -------------------------------------*/
function changeURLPar(destiny, par, par_value){
    var pattern = par+'=([^&]*)';
    var replaceText = par+'='+par_value;
    if (destiny.match(pattern)){
        var tmp = '/\\'+par+'=[^&]*/';
        tmp = destiny.replace(eval(tmp), replaceText);
        return (tmp);
    }
    else{
        if (destiny.match('[\?]')){
            return destiny+'&'+ replaceText;
        }
        else{
            return destiny+'?'+replaceText;
        }
    }
    return destiny+'\n'+par+'\n'+par_value;
} 

//destiny是目标字符串,比如是http://www.huistd.com/?id=3&ttt=3
//par是参数名,par_value是参数要更改的值,调用结果如下:
//changeURLPar(test, 'id', 99); // http://www.huistd.com/?id=99&ttt=3
//添加一个不存在的参数haha
//changeURLPar(test, 'haha', 33); // http://www.huistd.com/?id=99&ttt=3&haha=33 
/*
--------------------------------------------------------------------------
*/

/**
 * 生成一个自定义范围的随机数
 * 
 * @returns {int}
 */
function GetRandomNum(Min, Max){
    var Range = Max - Min;
    var Rand = Math.random();
    return(Min + Math.round(Rand * Range));
}



/*-------------------------------------
 js获取各种节点的方法
 -------------------------------------*/
1. 通过顶层document节点获取
  (1) document.getElementById(elementId)该方法通过节点的ID可以准确获得需要的元素是比较简单快捷的方法如果页面上含有多个相同id的节点那么只返回第一个节点
    如今已经出现了如prototypeMootools等多个JavaScript库它们提供了更简便的方法$(id)参数仍然是节点的id这个方法可以看作是document.getElementById()的另外一种写法不过$()的功能更为强大具体用法可以参考它们各自的API文档
  (2)document.getElementsByName(elementName)该方法是通过节点的name获取节点从名字可以看出这个方法返回的不是一个节点元素而是具有同样名称的节点数组然后我们可以通过要获取节点的某个属性来循环判断是否为需要的节点
    例如在HTML中checkbox和radio都是通过相同的name属性值来标识一个组内的元素如果我们现在要获取被选中的元素首先获取改组元素然后循环判断是节点的checked属性值是否为true即可
  (3)document.getElementsByTagName(tagName)该方法是通过节点的Tag获取节点同样该方法也是返回一个数组例如document.getElementsByTagName('A')将会返回页面上所有超链接节点在获取节点之前一般都是知道节点的类型的所以使用该方法比较简单但是缺点也是显而易见那就是返回的数组可能十分庞大这样就会浪费很多时间那么这个方法是不是就没有用处了呢当然不是这个方法和上面的两个不同它不是document节点的专有方法还可以应用其他的节点下面将会提到
2通过父节点获取
  (1)parentObj.firstChild如果节点为已知节点parentObj的第一个子节点就可以使用这个方法这个属性是可以递归使用的也就是支持parentObj.firstChild.firstChild.firstChild...的形式如此就可以获得更深层次的节点
  (2)parentObj.lastChild很显然这个属性是获取已知节点parentObj的最后一个子节点与firstChild一样它也可以递归使用
    在使用中如果我们把二者结合起来那么将会达到更加令人兴奋的效果parentObj.firstChild.lastChild.lastChild...
  (3)parentObj.childNodes获取已知节点的子节点数组然后可以通过循环或者索引找到需要的节点
    注意经测试发现在IE7上获取的是直接子节点的数组而在Firefox2.0.0.11上获取的是所有子节点即包括子节点的子节点
  (4)parentObj.children获取已知节点的直接子节点数组
    注意经测试在IE7上和childNodes效果一样而Firefox2.0.0.11不支持这也是为什么我要使用和其他方法不同样式的原因因此不建议使用
  (5)parentObj.getElementsByTagName(tagName)使用方法不再赘述它返回已知节点的所有子节点中类型为指定值的子节点数组例如parentObj.getElementsByTagName('A')返回已知的子节点中的所有超链接
3通过临近节点获取
  (1)neighbourNode.previousSibling获取已知节点neighbourNode的前一个节点这个属性和前面的firstChildlastChild一样都似乎可以递归使用的
  (2)neighbourNode.nextSibling获取已知节点neighbourNode的下一个节点同样支持递归
4通过子节点获取
  (1)childNode.parentNode获取已知节点的父节点


/*-------------------------------------
 js获取各种时间
 -------------------------------------*/
var now = new Date();
now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
now.getFullYear(); // 2015, 年份
now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
now.getDate(); // 24, 表示24号
now.getDay(); // 3, 表示星期三
now.getHours(); // 19, 24小时制
now.getMinutes(); // 49, 分钟
now.getSeconds(); // 22, 秒
now.getMilliseconds(); // 875, 毫秒数
now.getTime(); // 1435146562875, 以number形式表示的时间戳

要获取当前时间戳可以用

if (Date.now) {
    alert(Date.now()); // 老版本IE没有now()方法
} else {
    alert(new Date().getTime());
}



function setCookie(name, value, day, path) {
    var str = name + "=" + escape(value);
    if (day != 0) {
        var date = new Date();
        var ms = day * 3600 * 1000 * 24;
        date.setTime(date.getTime() + ms);
        str += ';expires=' + date.toGMTString();
    }//undefined
    if (typeof (path) != 'undefined') {
        str += ';path=' + path
    }
    document.cookie = str;
}
//获取cookie
function getCookie(c_name)
{
    if (document.cookie.length > 0)
    {
        c_start = document.cookie.indexOf(c_name + "=")
        if (c_start != -1)
        {
            c_start = c_start + c_name.length + 1
            c_end = document.cookie.indexOf(";", c_start)
            if (c_end == -1)
                c_end = document.cookie.length
            return unescape(document.cookie.substring(c_start, c_end))
        }
    }
    return ""
}




//这两个函数可以与asp(Server.UrlEncode)、php(urlencode())很好的解码
var test1="http://www.wljcz.com/My first/";  
var bb=encodeURIComponent(test1);  
var nnow=decodeURIComponent(bb);  
document.write(bb+ "<br />");  
document.write(nnow);  

1.6 - 分享到新浪等


<!doctype html>
<html lang="en">
<head>
     <meta charset="UTF-8">
     <title>Document</title>
</head>
<body>
     <!--分享到-->        
     <div class="arthdshare">
          <!-- Baidu Button BEGIN -->
          <div id="bdshare" class="bdshare_t bds_tools get-codes-bdshare">
               <span class="bds_more">分享到:</span>
               <a class="bds_qzone"></a>
               <a class="bds_tsina"></a>
               <a class="bds_tqq"></a>
               <a class="bds_renren"></a>
               <a class="bds_t163"></a>
               <a class="shareCount"></a>
          </div>
          <script type="text/javascript" id="bdshare_js" data="type=tools&amp;uid=6835930" ></script>
          <script type="text/javascript" id="bdshell_js"></script>
          <script type="text/javascript">
               document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
          </script>
          <!-- Baidu Button END -->      
     </div>
<!--分享到--> 
</body>
</html>     

1.7 - 改变url参数并可以把不存在的参数添加进url最后

function changeURLPar(destiny, par, par_value)
{
var pattern = par+'=([^&]*)';
var replaceText = par+'='+par_value;
if (destiny.match(pattern))
{
var tmp = '/\\'+par+'=[^&]*/';
tmp = destiny.replace(eval(tmp), replaceText);
return (tmp);
}
else
{
if (destiny.match('[\?]'))
{
return destiny+'&'+ replaceText;
}
else
{
return destiny+'?'+replaceText;
}
}
return destiny+'\n'+par+'\n'+par_value;
} 


destiny是目标字符串比如是http://www.huistd.com/?id=3&ttt=3
par是参数名par_value是参数要更改的值调用结果如下
changeURLPar(test, 'id', 99); // http://www.huistd.com/?id=99&ttt=3
添加一个不存在的参数haha
changeURLPar(test, 'haha', 33); // http://www.huistd.com/?id=99&ttt=3&haha=33 

1.8 - 判断浏览器及版本

<!DOCTYPE HTML>
<html>
  <head>
    <title>JavaScript获取浏览器类型与版本</title>
    <meta charset="utf-8"/>
    <script type="text/javascript">
        var Sys = {};
        var ua = navigator.userAgent.toLowerCase();
        var s;
        (s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
        (s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
        (s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
        (s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
        (s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;

        //以下进行测试
        if (Sys.ie) document.write('IE: ' + Sys.ie);
        if (Sys.firefox) document.write('Firefox: ' + Sys.firefox);
        if (Sys.chrome) document.write('Chrome: ' + Sys.chrome);
        if (Sys.opera) document.write('Opera: ' + Sys.opera);
        if (Sys.safari) document.write('Safari: ' + Sys.safari);
    </script>
    <script type="text/javascript">
        function getBrowserInfo(){
            var Sys = {};
            var ua = navigator.userAgent.toLowerCase();
            var re =/(msie|firefox|chrome|opera|version).*?([\d.]+)/;
            var m = ua.match(re);
            Sys.browser = m[1].replace(/version/, "'safari");
            Sys.ver = m[2];
            return Sys;
        }
        document.write('<hr/>');
       //获取当前的浏览器信息
       var sys = getBrowserInfo();
       //sys.browser得到浏览器的类型,sys.ver得到浏览器的版本
       document.write(sys.browser + "的版本是:" + sys.ver);
    </script>
  </head>
  
  <body>
   
  </body>
</html>

1.9 - 瀑布流

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        ul li {height: 50px; border: 1px solid red;}
    </style>
    <script type="text/javascript" src="jquery1.8.2.js"></script>
</head>
<body>
    <ul>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
        <li>1</li>
    </ul>
</body>
<script type="text/javascript">
$(window).load(function(){
    ;(function($){
        var is_do = true;
        var range = 50;             //距下边界长度/单位px
        var maxnum = parseInt(10);            //设置加载最多次数-页数
        var num = 1;                //当前页数
        var totalheight = 0;

        $(window).scroll(function(){
            var srollPos = $(window).scrollTop();    //滚动条距顶部距离(页面超出窗口的高度)
            var window_height = $(window).height();//浏览器窗体高度
            var document_height = $(document).height();//文档高度
            //浏览器窗体高度 + 滚动条距顶部距离 = 文档高度
            console.log("滚动条到顶部的垂直高度: "+$(document).scrollTop());  
            console.log("页面的文档高度 :"+$(document).height());  
            console.log('浏览器的高度:'+$(window).height());  

            totalheight = parseFloat(window_height) + parseFloat(srollPos);

            if ((document_height-range <= totalheight) && (num < maxnum) && is_do) {
                is_do = false;
                alert(1);
            }
        });
    })(jQuery);
});

</script>
</html>

1.10 - 手机屏幕触摸

<!-- HTML5 -->
<!DOCTYPE html>
<html>
    <head>
        <title>TouchEvent测试</title>
        <meta charset="gbk">
    </head>
    <body>
        <h2>TouchEvent测试</h2>
        <br />
        <div id="version" style="border:2px solid black;background-color:yellow"></div>
        <br />
        <br />
        <br />
        <br />
        <br />
        <br />
        <div id="result" style="border:2px solid red; color:red;">未触发事件!</div>
        <div id="test" style="border:2px solid red">
            <ul>
                <li id="li1">测试条目1</li>
                <li id="li2">测试条目2</li>
                <li id="li3">测试条目3</li>
                <li id="li4">测试条目4</li>
                <li id="li5">测试条目5</li>
                <li id="li6">测试条目6</li>
                <li id="li7">测试条目7</li>
                <li id="li8">测试条目8</li>
                <li id="li9">测试条目9</li>
                <li id="li10">测试条目10</li>
                <li id="li11">测试条目11</li>
                <li id="li12">测试条目12</li>
                <li id="li13">测试条目13</li>
                <li id="li14">测试条目14</li>
                <li id="li15">测试条目15</li>
                <li id="li16">测试条目16</li>
                <li id="li17">测试条目17</li>
                <li id="li18">测试条目18</li>
                <li id="li19">测试条目19</li>
                <li id="li20">测试条目20</li>
            </ul>
        </div>
        
        <script type="text/javascript">
            //全局变量,触摸开始位置
            var startX = 0, startY = 0;
            
            //touchstart事件
            function touchSatrtFunc(evt) {
                try
                {
                    //evt.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等

                    var touch = evt.touches[0]; //获取第一个触点
                    var x = Number(touch.pageX); //页面触点X坐标
                    var y = Number(touch.pageY); //页面触点Y坐标
                    //记录触点初始位置
                    startX = x;
                    startY = y;

                    var text = 'TouchStart事件触发:(' + x + ', ' + y + ')';
                    document.getElementById("result").innerHTML = text;
                }
                catch (e) {
                    alert('touchSatrtFunc:' + e.message);
                }
            }

            //touchmove事件,这个事件无法获取坐标
            function touchMoveFunc(evt) {
                try
                {
                    //evt.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等
                    var touch = evt.touches[0]; //获取第一个触点
                    var x = Number(touch.pageX); //页面触点X坐标
                    var y = Number(touch.pageY); //页面触点Y坐标

                    var text = 'TouchMove事件触发:(' + x + ', ' + y + ')';

                    //判断滑动方向
                    if (x - startX != 0) {
                        text += '<br/>左右滑动';
                    }
                    if (y - startY != 0) {
                        text += '<br/>上下滑动';
                    }

                    document.getElementById("result").innerHTML = text;
                }
                catch (e) {
                    alert('touchMoveFunc:' + e.message);
                }
            }

            //touchend事件
            function touchEndFunc(evt) {
                try {
                    //evt.preventDefault(); //阻止触摸时浏览器的缩放、滚动条滚动等

                    var text = 'TouchEnd事件触发';
                    document.getElementById("result").innerHTML = text;
                }
                catch (e) {
                    alert('touchEndFunc:' + e.message);
                }
            }

            //绑定事件
            function bindEvent() {
                document.addEventListener('touchstart', touchSatrtFunc, false);
                document.addEventListener('touchMoveFunc', touchMoveFunc, false);
                document.addEventListener('touchend', touchEndFunc, false);
            }

            //判断是否支持触摸事件
            function isTouchDevice() {
                document.getElementById("version").innerHTML = navigator.appVersion;

                try {
                    document.createEvent("TouchEvent");
                    alert("支持TouchEvent事件!");

                    bindEvent(); //绑定事件
                }
                catch (e) {
                    alert("不支持TouchEvent事件!" + e.message);
                }
            }

            window.onload = isTouchDevice;
    </script>
    </body>
</html>

1.11 - 一些案例

源码地址

  1. js验证身份证号有效性 预览:

  2. 单选按钮单击一下选中再次单击取消选中 预览:

  3. 模拟js弹出框 预览alert 预览confirm 预览prompt

  4. 使用js加载器动态加载外部Javascript文件 无预览

  5. html时钟 预览

  6. jquery-barcode条形码 预览

  7. jQuery1.11.0_20140330.chm 无预览

  8. ajax异步提交表单 无预览

  9. JQUERY字体超出省略号 预览

  10. jqzoom_ev-2.3 商城的商品图片墙 预览 预览 预览 预览 预览 预览

  11. 一个管理端模板

  12. 标签切换 预览

  13. 模拟文件上传 预览

  14. 日期插件 预览

  15. 图片滚动 预览

  16. 网站常用简洁的TAB选项卡 预览

  17. 页码样式 预览

2 - 键盘事件编码

event.keycode大全(javascript)


keycode 8 = BackSpace BackSpace 
keycode 9 = Tab Tab 
keycode 12 = Clear 
keycode 13 = Enter 
keycode 16 = Shift_L 
keycode 17 = Control_L 
keycode 18 = Alt_L 
keycode 19 = Pause 
keycode 20 = Caps_Lock 
keycode 27 = Escape Escape 
keycode 32 = space space 
keycode 33 = Prior 
keycode 34 = Next 
keycode 35 = End 
keycode 36 = Home 
keycode 37 = Left 
keycode 38 = Up 
keycode 39 = Right 
keycode 40 = Down 
keycode 41 = Select 
keycode 42 = Print 
keycode 43 = Execute 
keycode 45 = Insert 
keycode 46 = Delete 
keycode 47 = Help 
keycode 48 = 0 equal braceright 
keycode 49 = 1 exclam onesuperior 
keycode 50 = 2 quotedbl twosuperior 
keycode 51 = 3 section threesuperior 
keycode 52 = 4 dollar 
keycode 53 = 5 percent 
keycode 54 = 6 ampersand 
keycode 55 = 7 slash braceleft 
keycode 56 = 8 parenleft bracketleft 
keycode 57 = 9 parenright bracketright 
keycode 65 = a A 
keycode 66 = b B 
keycode 67 = c C 
keycode 68 = d D 
keycode 69 = e E EuroSign 
keycode 70 = f F 
keycode 71 = g G 
keycode 72 = h H 
keycode 73 = i I 
keycode 74 = j J 
keycode 75 = k K 
keycode 76 = l L 
keycode 77 = m M mu 
keycode 78 = n N 
keycode 79 = o O 
keycode 80 = p P 
keycode 81 = q Q at 
keycode 82 = r R 
keycode 83 = s S 
keycode 84 = t T 
keycode 85 = u U 
keycode 86 = v V 
keycode 87 = w W 
keycode 88 = x X 
keycode 89 = y Y 
keycode 90 = z Z 
keycode 96 = KP_0 KP_0 
keycode 97 = KP_1 KP_1 
keycode 98 = KP_2 KP_2 
keycode 99 = KP_3 KP_3 
keycode 100 = KP_4 KP_4 
keycode 101 = KP_5 KP_5 
keycode 102 = KP_6 KP_6 
keycode 103 = KP_7 KP_7 
keycode 104 = KP_8 KP_8 
keycode 105 = KP_9 KP_9 
keycode 106 = KP_Multiply KP_Multiply 
keycode 107 = KP_Add KP_Add

keycode 108 = KP_Separator KP_Separator 
keycode 109 = KP_Subtract KP_Subtract 
keycode 110 = KP_Decimal KP_Decimal 
keycode 111 = KP_Divide KP_Divide 
keycode 112 = F1 
keycode 113 = F2 
keycode 114 = F3 
keycode 115 = F4 
keycode 116 = F5 
keycode 117 = F6 
keycode 118 = F7 
keycode 119 = F8 
keycode 120 = F9 
keycode 121 = F10 
keycode 122 = F11 
keycode 123 = F12 
keycode 124 = F13 
keycode 125 = F14 
keycode 126 = F15 
keycode 127 = F16 
keycode 128 = F17 
keycode 129 = F18 
keycode 130 = F19 
keycode 131 = F20 
keycode 132 = F21 
keycode 133 = F22 
keycode 134 = F23 
keycode 135 = F24 
keycode 136 = Num_Lock 
keycode 137 = Scroll_Lock 
keycode 187 = acute grave 
keycode 188 = comma semicolon 
keycode 189 = minus underscore 
keycode 190 = period colon 
keycode 192 = numbersign apostrophe 
keycode 210 = plusminus hyphen macron 
keycode 211 = 
keycode 212 = copyright registered 
keycode 213 = guillemotleft guillemotright 
keycode 214 = masculine ordfeminine 
keycode 215 = ae AE 
keycode 216 = cent yen 
keycode 217 = questiondown exclamdown 
keycode 218 = onequarter onehalf threequarters 
keycode 220 = less greater bar 
keycode 221 = plus asterisk asciitilde 
keycode 227 = multiply division

keycode 228 = acircumflex Acircumflex 
keycode 229 = ecircumflex Ecircumflex 
keycode 230 = icircumflex Icircumflex 
keycode 231 = ocircumflex Ocircumflex 
keycode 232 = ucircumflex Ucircumflex 
keycode 233 = ntilde Ntilde 
keycode 234 = yacute Yacute 
keycode 235 = oslash Ooblique 
keycode 236 = aring Aring 
keycode 237 = ccedilla Ccedilla 
keycode 238 = thorn THORN 
keycode 239 = eth ETH 
keycode 240 = diaeresis cedilla currency 
keycode 241 = agrave Agrave atilde Atilde 
keycode 242 = egrave Egrave 
keycode 243 = igrave Igrave 
keycode 244 = ograve Ograve otilde Otilde 
keycode 245 = ugrave Ugrave 
keycode 246 = adiaeresis Adiaeresis 
keycode 247 = ediaeresis Ediaeresis 
keycode 248 = idiaeresis Idiaeresis 
keycode 249 = odiaeresis Odiaeresis 
keycode 250 = udiaeresis Udiaeresis 
keycode 251 = ssharp question backslash 
keycode 252 = asciicircum degree 
keycode 253 = 3 sterling 
keycode 254 = Mode_switch

使用event对象的keyCode属性判断输入的键值
eg:if(event.keyCode==13)alert(“enter!”);
键值对应表
A  0X65  U   0X85
B  0X66  V   0X86
C  0X67  W   0X87
D  0X68  X   0X88
E  0X69  Y   0X89
F  0X70  Z   0X90
G  0X71  0   0X48
H  0X72  1   0X49
I  0X73  2   0X50
J  0X74  3   0X51
K  0X75  4   0X52
L  0X76  5   0X53
M  0X77  6   0X54
N  0X78  7   0X55
O  0X79  8   0X56
P  0X80  9   0X57
Q  0X81 ESC  0X1B
R  0X82 CTRL  0X11
S  0X83 SHIFT 0X10
T  0X84 ENTER 0XD

如果要使用组合键,则可以利用event.ctrlKey,event.shiftKey,event .altKey判断是否按下了ctrl键、shift键以及alt键

3 - ES6语法

声明变量

ES6之前声明变量的方式:var 、 let 、 const

var

  1. 变量提升: 声明的变量会提升到函数作用域的顶部
{
    var  a = 1;
}
console.log(a);
  1. var 可以声明多次

var a = 1;
var a = 2;
console.log(a);

let

  1. 块作用域,具有严格的作用于域
{
    let a = 1;
    console.log(a);
}
console.log(a); // ReferenceError: a is not defined
  1. let 只能声明一次
let a = 1;
let a = 2;
console.log(a);  // SyntaxError: Identifier 'a' has already been declared

### const

1. const 声明的变量必须初始化并且不能被改变
```javascript
const a;
console.log(a); // SyntaxError: Missing initializer in const declaration

const a = 1;
a = 2;  // TypeError: Assignment to constant variable.
console.log(a);

解构表达式

  1. 数组解构
let arr = [1,2,3];

// 传统用法
// let a = arr[0];
// let b = arr[1];
// let c = arr[2];

// 解构用法
let [a,b,c] = arr;
  1. 对象解构
let obj = {
    name: 'zhangsan',
    age: 18
    sex: 'male'
}
// 传统用法
let name = obj.name;
let age = obj.age;
let sex = obj.sex;

// 解构用法
let {name,age,sex} = obj;
console.log(name,age,sex);

字符串扩展

let str = "hello.vue";
console.log(str.startsWith("hello"));//true
console.log(str.endsWith(".vue"));//true
console.log(str.includes("e"));//true
console.log(str.includes("hello"));//true


//多行字符串
let ss = `<div>
    <span>hello world<span>
</div>`;
console.log(ss);

// 2、字符串插入变量和表达式。变量名写在 ${} 中,${} 中可以放入 JavaScript 表达式。

function fun() {
    return "这是一个函数"
}

let info = `我是${abc},今年${age + 10}了, 我想说: ${fun()}`;
console.log(info);

函数参数优化

  1. 默认值
//在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法:
function add(a, b) {
    // 判断b是否为空,为空就给默认值1
    b = b || 1;
    return a + b;
}
// 传一个参数
console.log(add(10));


//现在可以这么写:直接给参数写上默认值,没传就会自动使用默认值
function add2(a, b = 1) {
    return a + b;
}
console.log(add2(20));
  1. 不定参数
function fun(...values) {
    console.log(values.length)
}
fun(1, 2)      //2
fun(1, 2, 3, 4)  //4
  1. 箭头函数
// case1
var print = function (obj) {
    console.log(obj);
}

var print = obj => console.log(obj);
print("hello");

// case2
var sum = function (a, b) {
    c = a + b;
    return a + c;
}
// case2 箭头函数1
var sum2 = (a, b) => a + b;
console.log(sum2(11, 12));
// case2 箭头函数2
var sum3 = (a, b) => {
    c = a + b;
    return a + c;
}
console.log(sum3(10, 20))

// case3 箭头函数+解构
const person = {
    name: "jack",
    age: 21,
    language: ['java', 'js', 'css']
}

// 传统用法
function hello(person) {
    console.log("hello," + person.name)
}

//箭头函数+解构
var hello2 = ({name}) => console.log("hello," +name);
hello2(person); // 直接把包含name属性的一个对象扔进来就行

对象优化

// case1
const person = {
    name: "jack",
    age: 21,
    language: ['java', 'js', 'css']
}

// [
//     "name",
//     "age",
//     "language"
// ]
console.log(Object.keys(person));

// [
//     "jack",
//     21,
//     [
//         "java",
//         "js",
//         "css"
//     ]
// ]
console.log(Object.values(person));

// [
//     [
//         "name",
//         "jack"
//     ],
//     [
//         "age",
//         21
//     ],
//     [
//         "language",
//         [
//             "java",
//             "js",
//             "css"
//         ]
//     ]
// ]
console.log(Object.entries(person));//[Array(2), Array(2), Array(2)]


// case2
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };

//{a:1,b:2,c:3}
Object.assign(target, source1, source2);

// {
//     "a": 1,
//     "b": 2,
//     "c": 3
// }
console.log(target);

// case3 声明对象简写
const age = 23
const name = "张三"
const person1 = { age: age, name: name }

const person2 = { age, name }
console.log(person2);

// case4 对象的函数属性简写
let person3 = {
    name: "jack",
    // 以前:
    eat: function (food) {
        console.log(this.name + "在吃" + food);
    },
    //箭头函数this不能使用,对象.属性
    eat2: food => console.log(person3.name + "在吃" + food),
    eat3(food) {
        console.log(this.name + "在吃" + food);
    }
}

person3.eat("香蕉");

person3.eat2("苹果")

person3.eat3("橘子");

// case5 对象拓展运算符

// 1、拷贝对象(深拷贝)
let p1 = { name: "Amy", age: 15 }
let someone = { ...p1 }
console.log(someone)  //{name: "Amy", age: 15}

// 2、合并对象
let age1 = { age: 15 }
let name1 = { name: "Amy" }
let p2 = {name:"zhangsan"}
p2 = { ...age1, ...name1 } 
console.log(p2)

map和reduce

数组中新增了map和reduce方法。

map():接收一个函数,将原数组中的所有元素用这个函数处理后放入新数组返回。

let arr = ['1', '20', '-5', '3'];
    
//  arr = arr.map((item)=>{
//     return item*2
//  });
arr = arr.map(item=> item*2);

console.log(arr);

reduce() 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,

[2, 40, -10, 6]

arr.reduce(callback,[initialValue])

/**
1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
2、currentValue (数组中当前被处理的元素)
3、index (当前元素在数组中的索引)
4、array (调用 reduce 的数组)
*/
let result = arr.reduce((a,b)=>{
    console.log("上一次处理后:"+a);
    console.log("当前正在处理:"+b);
    return a + b;
},100);
console.log(result)

promise

promise 是一个对象,用于表示一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。promise 对象的构造函数接受一个函数作为参数,该函数的两个参数分别是 resolve 和 reject。resolve 是一个函数,用于将 promise 状态从 pending 转换为 fulfilled,reject 是一个函数,用于将 promise 状态从 pending 转换为 rejected。promise 对象的 then 方法接受两个参数,第一个参数是 promise 成功的回调函数,第二个参数是 promise 失败的回调函数

设定一个功能

  1. 查出当前用户信息
  2. 按照当前用户的id查出他的课程
  3. 按照当前课程id查出分数

传统的写法

$.ajax({
    url: "mock/user.json",
    success(data) {
        console.log("查询用户:", data);
        $.ajax({
            url: `mock/user_corse_${data.id}.json`,
            success(data) {
                console.log("查询到课程:", data);
                $.ajax({
                    url: `mock/corse_score_${data.id}.json`,
                    success(data) {
                        console.log("查询到分数:", data);
                    },
                    error(error) {
                        console.log("出现异常了:" + error);
                    }
                });
            },
            error(error) {
                console.log("出现异常了:" + error);
            }
        });
    },
    error(error) {
        console.log("出现异常了:" + error);
    }
});

Promise可以封装异步操作 // mock shuju

// mock/user.json
{
    "id": 1,
    "name": "zhangsan",
    "password": "123456"
}
//mock/user_corse_${obj.id}.json
{
    "id": 10,
    "name": "chinese"
}
// mock/corse_score_${data.id}.json
{
    "id": 100,
    "score": 90
}

// 第一种
let p = new Promise((resolve, reject) => {
    //1、异步操作
    $.ajax({
        url: "mock/user.json",
        success: function (data) {
            console.log("查询用户成功:", data)
            resolve(data);
        },
        error: function (err) {
            reject(err);
        }
    });
});

p.then((obj) => {
    return new Promise((resolve, reject) => {
        $.ajax({
            url: `mock/user_corse_${obj.id}.json`,
            success: function (data) {
                console.log("查询用户课程成功:", data)
                resolve(data);
            },
            error: function (err) {
                reject(err)
            }
        });
    })
}).then((data) => {
    console.log("上一步的结果", data)
    $.ajax({
        url: `mock/corse_score_${data.id}.json`,
        success: function (data) {
            console.log("查询课程得分成功:", data)
        },
        error: function (err) {
        }
    });
})

// 方法二
function get(url, data) {
    return new Promise((resolve, reject) => {
        $.ajax({
            url: url,
            data: data,
            success: function (data) {
                resolve(data);
            },
            error: function (err) {
                reject(err)
            }
        })
    });
}

get("mock/user.json")
    .then((data) => {
        console.log("用户查询成功~~~:", data)
        return get(`mock/user_corse_${data.id}.json`);
    })
    .then((data) => {
        console.log("课程查询成功~~~:", data)
        return get(`mock/corse_score_${data.id}.json`);
    })
    .then((data)=>{
        console.log("课程成绩查询成功~~~:", data)
    })
    .catch((err)=>{
        console.log("出现异常",err)
    });

模块化

hello.js

// 默认导出
export default {
    sum(a, b) {
        return a + b;
    }
}

// 具名导出
// export const util = {
//     sum(a, b) {
//         return a + b;
//     }
// }

// export {util}

//`export`不仅可以导出对象,一切JS变量都可以导出。比如:基本类型变量、函数、数组、对象。

user.js

var name = "jack"
var age = 21
function add(a,b){
    return a + b;
}

export {name,age,add} // 导出了 变量和函数

main.js

import abc from "./hello.js"
import {name,add} from "./user.js"

abc.sum(1,2);
console.log(name);
add(1,3);

4 - mybatisSql语句拼装

mybatisSql语句拼装的html代码可以直接本地运行

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>Mybatis Log Helper</title>
  <meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
  <link rel="shortcut icon" href="" />
  <script src="https://unpkg.com/vue@2.6.11/dist/vue.js"></script>
  <!-- 引入样式 -->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  <!-- 引入组件库 -->
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <style>
    #app {
      margin-top: 70px;
      display: flex;
      justify-content: space-evenly;
      align-items: center;
      font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    }
  </style>
</head>
<body>
  <div id="app">
    <el-input type="textarea" v-model="pre" placeholder="请复制输入Mybatis打印的日志,须完整Prepareing语句和Parameter语句"
              :rows="28" style="width: 600px"></el-input>
    <el-button type="success" @click="convert" style="height: 60px; width: 80px;">转换</el-button>
    <el-input type="textarea" v-model="res" placeholder="输出结果"
              :rows="28" style="width: 600px"></el-input>
  </div>

  <script type="text/javascript">
    const app = new Vue({
      el: '#app',
      data() {
        return {
          // 原始str
          pre: '',
          // 输出结果
          res: ''
        }
      },
      methods: {
        convert() {
          const str = this.pre
          
          if (str.indexOf('Preparing') == -1 || str.indexOf('Parameters') == -1) {
            this.$message({
              message: '请将Preparing和Parameters语句复制进来',
              type: 'error',
              center: true
            })
          }
          // str为完整的三行或两行SQL    提取预编译语句
          // const prepare = str.substring(str.indexOf('Preparing') + 11, str.indexOf('\n'))
          var prepare=""
          var params=new Array()
          var arr = str.split("\n");
          for(const strItem of arr) {
            if (strItem.indexOf("Preparing") != -1) {
              prepare = strItem.substring(strItem.indexOf('Preparing') + 11)
              // console.log("prepare="+prepare)
            }
            
            if (strItem.indexOf("Parameters") != -1) {
              params.push(strItem.substring(strItem.indexOf('Parameters') + 12))
              // console.log("params["+i+"]="+params[i])
            }
          }


          if(params.length > 1) {
            var placeholder = prepare.substring(prepare.indexOf('( ?')-1)
            console.log(prepare)
            for(let i=0; i < params.length-1;i++) {
              prepare = prepare+','+placeholder
            }
            console.log(prepare)
          } 
          var paramStr = params.join(',')
          // 获取参数,去空格
          paramStr = paramStr.replace(/ /g, '')
          // 参数数组
          const array = paramStr.split(',')
          console.log(array)
          // 循环替换占位符,字符串方式替换每次替换第一个
          array.map(item => {
            youKuoHaoWeiZhi = item.indexOf('(')
            console.log(item+":右侧括号"+youKuoHaoWeiZhi)
            let newValue = ""
            if (youKuoHaoWeiZhi != -1) {
              newValue = item.substring(0, item.indexOf('('))
              console.log(item+":最新值"+newValue)
              // 获取参数类型
              const type = item.substring(item.indexOf('(') + 1, item.indexOf(')'))
              console.log(item+":参数"+type)
              if ('String' === type) {
                newValue = "'" + newValue + "'"
              }
            } else {
              newValue = item
            }
            
            
            
            prepare = prepare .replace('?', newValue)
          })
          
          
          this.res = prepare
        }
      }
    })

    // 返回字符串str中的第n字符串reg在str中的索引值index
    function index(str, reg, n) {
      if (!str || !reg || n <= 0) return -1
      // 先求出第一个,再递归n-1
      if (n === 1) {
        return str.indexOf(reg)
      }
      // 注意n-1的索引后一定要加1,负责会一直是第一个reg的索引
      return str.indexOf(reg, index(str, reg, n - 1) + 1)
    }
    // 测试index函数
    // const str = 'hello world ok'
    // const reg = 'o'
    // console.log(index(str, reg, 3))
  </script>
</body>
</html>

6 - cookie、localStorage和sessionStorage 三者之间的区别以及存储、获取、删除等使用方式

写在前面:

前端开发的时候,在网页刷新的时候,所有数据都会被清空,这时候就要用到本地存储的技术,前端本地存储的方式有三种,分别是cookie,localstorage和sessionStorage ,这是大家都知道的。本文的主要内容就是针对这三者的存放、获取,区别、应用场景。有需要的朋友可以做一下参考,希望可以帮到大家。

本文首发于blog:obkoro1.com 本文版权归作者所有,转载请注明出处。

使用方式:

很多文档都是说了一大堆,后面用法都没有说,先要学会怎么用,不然后面的都是扯淡,所以这里我先把使用方式弄出来。

保存cookie值:

    var dataCookie='110';
    document.cookie = 'token' + "=" +dataCookie; 复制代码

获取指定名称的cookie值

 function getCookie(name) { //获取指定名称的cookie值
// (^| )name=([^;]*)(;|$),match[0]为与整个正则表达式匹配的字符串,match[i]为正则表达式捕获数组相匹配的数组;
var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
if(arr != null) {
  console.log(arr);
  return unescape(arr[2]);
}
return null;
}
 var cookieData=getCookie('token'); //cookie赋值给变量。复制代码

先贴这两个最基础的方法,文末有个demo里面还有如何设置cookie过期时间,以及删除cookie的、

localStorage和sessionStorage:

localStorage和sessionStorage所使用的方法是一样的,下面以sessionStorage为栗子:

var name='sessionData';
var num=120;
sessionStorage.setItem(name,num);//存储数据
sessionStorage.setItem('value2',119);
let dataAll=sessionStorage.valueOf();//获取全部数据
console.log(dataAll,'获取全部数据');
var dataSession=sessionStorage.getItem(name);//获取指定键名数据
var dataSession2=sessionStorage.sessionData;//sessionStorage是js对象,也可以使用key的方式来获取值
 console.log(dataSession,dataSession2,'获取指定键名数据');
sessionStorage.removeItem(name); //删除指定键名数据
  console.log(dataAll,'获取全部数据1');
 sessionStorage.clear();//清空缓存数据:localStorage.clear();
  console.log(dataAll,'获取全部数据2');  复制代码

使用方式,基本上就上面这些,其实也是比较简单的。大家可以把这个copy到自己的编译器里面,或者文末有个demo,可以点开看看。

三者的异同:

上面的使用方式说好了,下面就唠唠三者之间的区别,这个问题其实很多大厂面试的时候也都会问到,所以可以注意一下这几个之间的区别。

生命周期:

cookie:可设置失效时间,没有设置的话,默认是关闭浏览器后失效

localStorage:除非被手动清除,否则将会永久保存。

sessionStorage: 仅在当前网页会话下有效,关闭页面或浏览器后就会被清除。

存放数据大小:

cookie:4KB左右

localStorage和sessionStorage:可以保存5MB的信息。

http请求:

cookie:每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题

localStorage和sessionStorage:仅在客户端(即浏览器)中保存,不参与和服务器的通信

易用性:

cookie:需要程序员自己封装,源生的Cookie接口不友好

localStorage和sessionStorage:源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

应用场景:

从安全性来说,因为每次http请求都会携带cookie信息,这样无形中浪费了带宽,所以cookie应该尽可能少的使用,另外cookie还需要指定作用域,不可以跨域调用,限制比较多。但是用来识别用户登录来说,cookie还是比stprage更好用的。其他情况下,可以使用storage,就用storage。

storage在存储数据的大小上面秒杀了cookie,现在基本上很少使用cookie了,因为更大总是更好的,哈哈哈你们懂得。

localStorage和sessionStorage唯一的差别一个是永久保存在浏览器里面,一个是关闭网页就清除了信息。localStorage可以用来夸页面传递参数,sessionStorage用来保存一些临时的数据,防止用户刷新页面之后丢失了一些参数。

浏览器支持情况:

localStorage和sessionStorage是html5才应用的新特性,可能有些浏览器并不支持,这里要注意。

cookie的浏览器支持没有找到,可以通过下面这段代码来判断所使用的浏览器是否支持cookie:

if(navigator.cookieEnabled) {
  alert("你的浏览器支持cookie功能");//提示浏览器支持cookie  
} else {
  alert("你的浏览器不支持cookie");//提示浏览器不支持cookie   }复制代码

数据存放处:

Cookie、localStorage、sessionStorage数据存放处

Cookie、localStorage、sessionStorage数据存放处

番外:各浏览器Cookie大小、个数限制。

cookie 使用起来还是需要小心一点,有兴趣的可以看一下这个链接

demo链接

把上面的demo代码,上传到github上面了,有需要的小伙伴们,可以看一下。传送门

后话

最后要说的是:不要把什么数据都放在 Cookie、localStorage 和 sessionStorage中,毕竟前端的安全性这么低。只要打开控制台就可以任意的修改 Cookie、localStorage 和 sessionStorage的数据了。涉及到金钱或者其他比较重要的信息,还是要存在后台比较好。

最后:如需转载,请放上原文链接并署名。码字不易,感谢支持!本人写文章本着交流记录的心态,写的不好之处,不撕逼,但是欢迎指点。然后就是希望看完的朋友点个喜欢,也可以关注一下我。
blog网站 and 掘金个人主页

<script>
  cookieFn();
  strogeFn();
function cookieFn() {
  var dataCookie='110';
  document.cookie = 'token' + "=" +dataCookie;//直接设置cookie
  function getCookie(name) { //获取指定名称的cookie值
    // (^| )name=([^;]*)(;|$),match[0]为与整个正则表达式匹配的字符串,match[i]为正则表达式捕获数组相匹配的数组;
    var arr = document.cookie.match(new RegExp("(^| )"+name+"=([^;]*)(;|$)"));
    if(arr != null) {
      console.log(arr,'正则表达式捕获数组相匹配的数组');
      return unescape(arr[2]);
    }
    return null;
  }
  var cookieData=getCookie('token');
  console.log(cookieData,'获取指定名称的cookie值');
  function setTime() {
    //存储cookie值并且设置cookie过期时间
    var date=new Date();
    var expiresDays=10;//设置十天过期
    date.setTime(date.getTime()+expiresDays*24*3600*1000);
    document.cookie="userId=828;  expires="+date.toGMTString();
    console.log(document.cookie,'存储cookie值并且设置cookie过期时间');
  }
  setTime();

  function delCookie(cookieName1) {
    //删除cookie
    var date2=new Date();
    date2.setTime(date2.getTime()-10001);//把时间设置为过去的时间,会自动删除
    document.cookie= cookieName1+"=v; expires="+date2.toGMTString();
    console.log(document.cookie,'删除cookie');
  }
  delCookie('userId');
}
function strogeFn() {
  var name='sessionData';
  var num=120;
  sessionStorage.setItem(name,num);//存储数据
  sessionStorage.setItem('value2',119);
  let dataAll=sessionStorage.valueOf();//获取全部数据
  console.log(dataAll,'获取全部数据');
  var dataSession=sessionStorage.getItem(name);//获取指定键名数据
  var dataSession2=sessionStorage.sessionData;//sessionStorage是js对象,也可以使用key的方式来获取值
  console.log(dataSession,dataSession2,'获取指定键名数据');
  sessionStorage.removeItem(name); //删除指定键名数据
  console.log(dataAll,'获取全部数据1');
  sessionStorage.clear();//清空缓存数据:localStorage.clear();
  console.log(dataAll,'获取全部数据2');
}


</script>