TeaCoder

生命不息,代码不止


  • 首页

  • 分类

  • 归档

  • 标签

  • 搜索
close

javascript中的call()和apply()方法

发表于 2016-06-15   |   分类于 前端

我们知道函数调用有四种方式:直接调用、作为对象的方法调用、构造函数调用、间接调用。
而call()和apply()就是间接调用函数的方法。这两个方法都允许显示的指示调用上下文(this)的值,也就是说,任何函数可以作为任何对象的方法来调用,哪怕这个函数不是那个对象的方法。

假定有个函数f(),要想以对象o的方法来调用,可以这样使用call()和apply()

1
2
f.call(o);
f.apply(o);

每行代码的功能类似于(假设对象o预先不存在名为m的属性)

1
2
3
o.m=f; //将f存储为临时方法
o.m(); //调用
delete o.m; //删除临时方法

call()

语法:call(thisObj, arg1, arg2 …argN)
定义:调用一个对象的一个方法,以另一个对象替换当前对象。
说明:
1、call 方法可以用来代替另一个对象调用一个方法。
2、call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
3、如果没有提供 thisObj 参数(或者传入null、undefined),那么 Global 对象被用作 thisObj;ES5严格模式则将默认为this的值。
4、arg1、arg2..是待传入调用函数的实参,以逗号分隔。

apply()

语法:apply(thisObj,argArray)
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明:
1、如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
2、如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
3、argArray是待传入调用函数的参数组成的数组

关于apply()的奇淫巧计

apply()用来求数组中最大元素

由于Math.max()只能传入逗号分隔的参数,而apply()的第二个参数恰好可以传入数组或类数组元素。

1
var bigest=Math.max.apply(Math, array_of_numbers)

Array.prototype.push 可以实现两个数组合并

push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来使用数组作为参数

1
2
3
arr1=[1,2,3];
arr2=[4,5,6];
Array.prototype.push.apply(arr1,arr2);

常用实例

将某个对象的方法临时借给另一个对象调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Animal(){
this.name = "Animal";
this.showName = function(){
alert(this.name);
}
}
function Cat(){
this.name = "Cat";
}
var animal = new Animal();
var cat = new Cat();
//通过call或apply方法,将原本属于Animal对象的showName()方法交给对象cat来使用了。
//输入结果为"Cat"
animal.showName.call(cat,",");
//animal.showName.apply(cat,[]);

实现继承

1
2
3
4
5
6
7
8
9
10
11
function Animal(name){
this.name = name;
this.showName = function(){
alert(this.name);
}
}
function Cat(name){
Animal.call(this, name); //将Anima函数临时作为this的方法进行调用,并且传入Cat方法的参数name
}
var cat = new Cat("Black Cat"); //使用new调用Cat函数之后,this指向实例出来的对象cat;如果不使用new调用,则this指向全局对象。
cat.showName(); //"Black Cat"

多重继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Class1()
{
this.showSub = function(a,b)
{
alert(a-b);
}
};
function Class2()
{
this.showAdd = function(a,b)
{
alert(a+b);
}
};
function Class3()
{
Class1.call(this);
Class2.call(this);
};
var obj=new Class3(); //此时obj就多了showSub和showAdd的方法

javascript字符串对象方法

发表于 2016-06-14   |   分类于 前端

字符方法

chatAt()和chatCodeAt

charAt()和charCodeAt()
这两个方法接收一个参数,即基于0的字符位置。
chatAt()以单字符字符串的形式返回给定位置的那个字符。
chatCodeAt()返回给定位置的那个字符的字符编码。

1
2
3
var stringValue="hellow";
stringValue.chatAt(1); //"e"
stringValue.chatCodeAt(1); //"101"

字符串操作方法

concat()

concat()用于将一个或多个字符串拼接起来,返回拼接得到的新创建的字符串。
但实践中大多数情况还是使用(+)加号操作符,比concat()简单易行。

slice()、substring()、substr()

三个基于子字符串创建新字符串的方法,创建并返回被操作字符串的子字符串。注意方法名称都是小写
共同点:
参数1:必选,指定子字符串开始位置。
参数2:可选,不指定时将字符串的长度作为结束位置。
差异:
1、当指定参数2时

方法 参数2含义
slice()、substring() 指定子字符串最后一个字符的位置
substr 返回或截取的字符个数
1
2
3
4
5
6
7
8
var stringValue="hello world";
stringValue.length; //11
stringValue.slice(3); //"lo world"
stringValue.substring(3); //"lo world"
stringValue.substr(3); //"lo world"
stringValue.slice(3,7); //"lo wo"
stringValue.substring(3,7); //"lo wo"
stringValue.substr(3,7); //"lo worl"

2、当传递这些方法的参数是负数时

方法 行为
slice() 所有传入的负值与字符串的长度相加
substring() 所有的负值参数都转化为0
substr() 将负的第一个参数加上字符串的长度,将负的第二个参数转换为0
1
2
3
4
5
6
7
8
var stringValue="hello world";
stringValue.length; //11
stringValue.slice(-3); //"rld"
stringValue.substring(-3); //"hello world"
stringValue.substr(-3); //"rld"
stringValue.slice(3,-4); //"lo wo"
stringValue.substring(3,-4); //"hel"
stringValue.substr(3,-4); //""

字符串位置方法

indexOf()和lastIndexOf

从字符串中查找子字符串的位置,如果找到返回子字符串的位置;找不到返回-1
参数1:指定检索的子字符串
参数2:可选,指定开始检索的位置
indexOf()从开头向末尾搜索
lastIndexOf()从末尾向开头搜索

1
2
3
stringValue="hello world";
stringValue.indexOf('o',6); //7
stringValue.lastIndexOf('o',6); //4,此时从指定位置向前检索

trim()方法

创建一个字符串的副本,删除前置及后缀的所有空格,然后返回结果。
注意:字符串中的空格不管

1
2
3
stringValue=" hellow world ";
stringValue.trim(); //"hellow world"
stringValue; //" hellow world ";

字符串大小写转换方法

toLowerCase()和toUpperCase()

字符串模式匹配方法

match()

在字符串调用这个方法,本质上与调用RegExp对象的exec()方法相同。
参数:match()接收一个参数,要么是正则表达式,要么是正则对象。
返回值:matches返回一个数组,数组的第一项是与整个模式匹配的字符串,之后的每一项(如果有)保存着与正则表达式中捕获组匹配的字符串。

1
2
3
4
5
6
var text="cat,bat,hat";
var pattern=/.at/;
var matches=text.match(pattern);
matches.index //0
matches[0] //"cat"
pattern.lastIndex //0

search()

参数:search()接收一个参数,要么是正则表达式,要么是正则对象。
返回值:返回字符串中第一个匹配项的索引,如果没有找到匹配项,则返回-1.
注意:search()方法始终从字符串开头向后查找模式
例子:

1
2
var text="cat,bat,hat";
var pos=text.search(/cat/); //0

replace()

诞生原因:为了简化替换子字符串的操作,ECMAScript提供了replace()方法
参数:第一个参数正则对象或者字符串,第二个参数是一个字符串或者函数。
返回值:生成的替换后的字符串
注意

1
2
3
text="cat,bat,hat";
result=text.replace("at","ond") //"cond,bat,hat"
result=text.replace(/at/g,"ond") //"cond,cont,hont"

更精细的替换操作,使用函数作为replace()的第二个参数
在只有一个匹配项的情况下,会向这个函数传递3个参数:模式的匹配项、模式的匹配项在字符串中的位置、原始字符串。
在正则表达式中定义了多个捕获组的情况下,这个函数的参数依次是:模式的匹配项、第一个捕获组的匹配项、第二个捕获组的匹配项…,最后两个参数是模式的匹配项在字符串中的位置、原始字符串。
这个函数应该返回一个字符串,表示准备替换的预备项。
例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function htmlEscape(text){
return text.replace(/[<>"&]/g,function(match,pos,originText){
switch(case){
case "<":
return &lt;
case ">":
return &gt;
case "\"":
return &quot;
case "&":
return &amp;
}
})
}
htmlEscape("<p class=\"desc\">hellow</p>")
//输出 &lt;p class=&quot;desc;&quot;&gt;hellow&lt;/p&gt;

split()

基于指定的分割符将字符串分割成多个子字符串,并将结果存放在一个数组中。
参数:第一个参数是字符串或者正则表达式,匹配的项将作为分隔符
第二个参数可选,用于指定数组的大小

1
2
3
4
5
color="red,blue,pink";
colors1=color.split(","); //["red","blue","pink"]
colors2=color.split(",",2); //["red","blue"]
colors3=color.split(/[^,]+/);
//["",",",",",""] 由于/^,/匹配的是除逗号以外的一个或多个字符,而"red"和"pink"刚好在开头和结尾,因此数组第一个元素和最后一个为空字符

Javascript数组方法

发表于 2016-06-14   |   分类于 前端

ECMAScript3定义的数组方法

  • 转换:join()
  • 排序: reverse()、sort()
  • 连接:concat()
  • 裁剪: slice()
  • 插入、删除:splice()、push()、pop()、unshift()、shift()
  • 对象方法:toString()、toLocaleString()

join()

将数组中所有元素转化为字符串并连接在一起,返回最后生成的字符串。可以指定一个可选的字符串在生成的字符串中来分隔数组中的各个元素。如果不指定分隔符,默认使用逗号。

reverse()

将数组中的元素顺序颠倒,返回逆序的数组。它不通过创建新的数组重新排列,而是在原先的数组中排列它们。

sort()

将数组中的元素排序并返回排序后的数组。当不带参数调用sort()时,数组元素以字母表顺序排序。
如果包含undefined的元素,它们会被排到数组的尾部。
如果要按照其他方式排序,必须给sort()方法传递一个比较函数,该函数的返回值决定了该函数所传入参数a,b在排序好的数组中的先后顺序。假设第一个参数在前,则应该返回一个小于0的数;相反,则返回一个大于0的数。

1
2
3
4
5
6
7
8
9
10
11
12
//按数值升序
a.sort(function(a,b){
return a-b;
})
//按数组降序
a.sort(function(a,b){
return b-a;
})
//随机排序
a.sort(function(){
return 0.5-Math.random();
})

concat()

Array.concat()方法创建并返回一个新的数组,元素包括调用concat()的原始数组的元素和concat()的每个参数。如果这些参数中的任何一个自身是数组,则连接的是数组的元素;但是,concat
()不会扁平化数组的数组,可以理解为只能解剖一层。

1
2
3
4
5
var a=[1,2,3];
a.concat(4,5); //返回[1,2,3,4,5]
a.concat([4,5]); //返回[1,2,3,4,5]
a.concat([4,5],[6,7]) //返回[1,2,3,4,5,6,7]
a.concat(4,[5,[6,7]]) //返回[1,2,3,4,5,[6,7]]

由于返回的是新数组,该方法可用于实现数组复制

1
2
var b=a.concat();
console.log(b) //返回[1,2,3]

slice()

Array.slice()方法创建并返回指定数组的子数组。
slice(start,end) 参数start为必须,end为可选,分别指定截取的数组的起、止位置;如果出现负数,它表示相对于数组最后一个元素的位置。
slice(start) 截取start开始到数组结束的所有元素
slice(start,end) 截取[start,end)闭开区间的数组元素

1
2
3
4
5
var a=[1,2,3,4,5];
a.slice(0,3); //返回[1,2,3]
a.slice(3); //返回[4,5]
a.slice(1,-1); //返回[2,3,4]
a.slice(-3,-2); //返回[3]

slice()方法可用于实现数组复制

1
a.slice(0); //返回[1,2,3,4,5]

splice()

Array.splice()是数组中插入或删除元素的通用方法。不同于concat()和slice(),splice()会修改调用的数组
splice(index,howmany,item1,item2…)
第一个参数指定了插入或删除的起始位置
第二个参数指定了应该从数组中删除的元素的个数,如果省略,从起始点开始到数组结尾的所有元素都将被删除
返回值:splice()返回一个由删除元素组成的数组,或者没有删除元素,就返回空数组。
删除:

1
2
3
var a=[1,2,3,4,5];
a.splice(3); //返回[4,5],a是[1,2,3]
a.splice(1,2); //返回[2,3],a是[1]

插入:注意区别于concat(),splice()会插入数组本身而非数组的元素

1
2
3
var a=[1,2,3,4,5];
a.splice(2,0,'a','b') //返回[],a是[1,2,'a','b',3,4,5]
a.splice(2,2,[1,2],3) //返回[3,4],a是[1,2,[1,2],3,4,5]

push()、pop()、unshift()、shift()

在数组的尾部插入元素、删除元素:
push()、pop()
在数组的头部插入元素、删除元素:
unshift()、shift()
这些方法都可以被splice()替代;

toString()和toLocaleString()

toString()方法将数组的每个元素转化为字符串,返回用逗号分隔的字符串列表。注意,输出不包括方括号或其他任何形式包裹数组数值的分隔符。

1
2
3
[1,2,3].toString(); //返回'1,2,3'
["a","b","c"].toString(); //返回'a,b,c'
[1,[2,'c']].toString(); //返回'1,2,c'

这里与不使用任何参数调用join()方法返回的字符串是一样的。

toLocaleString()是数组对象的本地字符串表示,返回结果随机器不同而不同,最好不要在脚本中用来基本运算。

ECMAScript5中的数组方法

ECMAScript5中数组方法概述:
大多数方法第一个参数接收一个函数,并且对数组中的每个元素调用一次该函数。对不存在的元素不调用该函数。
大多数情况下,调用提供的函数使用三个参数:数组元素、元素的索引和数组本身,通常只需要使用第一个参数,忽略后面两个参数。
大多数ECMASscript数组方法第一个参数是一个函数,第二个参数可选。如果有第二个参数,则调用的函数被看成第二个参数的方法,即第二个参数可以在调用函数时将作为它的this关键字的值来使用,起到修改指针的作用。

forEach()

array1.forEach(callbackfn[, thisArg])

参数 定义
array1 必需。 一个数组对象。
callbackfn 必需。 一个接受最多三个参数的函数。 对于数组中的每个元素,forEach 都会调用 callbackfn 函数一次。
thisArg可选 可在 callbackfn 函数中为其引用 this 关键字的对象。 如果省略 thisArg,则 undefined 将用作 this 值。

如果 callbackfn 参数不是函数对象,则将引发 TypeError 异常。

对于数组中的每个元素,forEach 方法都会调用 callbackfn 函数一次(采用升序索引顺序)。 不为数组中缺少的元素调用该回调函数。

除了数组对象之外,forEach 方法可由具有 length 属性且具有已按数字编制索引的属性名的任何对象使用。

map()

map()方法将调用数组的每个元素传递给指定的函数,并返回一个数组,它包含该函数的返回值。
map()方法返回的是新数组,它不修改调用的数组;如果是稀疏数组,返回的也是相同方式的稀疏数组。它具有相同的长度,相同的缺失元素。

1
2
3
4
a=[1,2,3];
b=a.map(function(x){
return x*x; //b是[1,4,9]
})

filter()

filter()方法创建并返回调用数组的一个子集。传递的函数用来进行逻辑判定的,该函数返回true或false。
返回true的元素将被添加成为这个子集的成员。

1
2
3
4
5
6
7
a=[1,2,3,4,5];
b=a.filter(function(x){
return x>3
}) //b是[4,5]
c=a.filter(function(x,i){
return i%2==0;
}) //c是[1,3,5]

every()和some()方法

所有:every()每个数组元素回调函数都返回true的时候才会返回true,当遇到false的时候终止执行,返回false;

1
2
3
4
5
6
7
a=[1,2,3,4];
a.every(function(x){
return x < 10; //返回true
});
a.every(function(x){
return x % 2 == 0; //返回false,并非所有元素都能被2整除
})

存在:some()
存在有一个数组元素的回调函数返回true的时候终止执行并返回true,否则返回false。

1
2
3
4
5
a=[1,2,3,4];
a.some(function(x){
return x % 2 == 0; //返回true
});
a.some(isNaN); //false

reduce()和reduceRight()方法

遍历数组,调用回调函数,将数组元素组合成一个值
参数1:回调函数:把两个值合为一个
参数2:value,一个初始值,可选
reduce从索引最小值开始
reduceRight反向,方法有两个参数

1
2
3
4
5
6
7
var a=new Array(1,2,3,4,5,6);
console.log(a.reduce(function(v1,v2){
return v1+v2;
})); // 21
console.log(a.reduceRight(function(v1,v2){
return v1-v2;
},100)); // 79

indexOf()lastIndexOf()方法

用于查找数组内指定元素位置,查找到第一个后返回其索引,没有查找到返回-1,indexOf从头至尾搜索,lastIndexOf反向搜索。

1
2
3
4
var a=new Array(1,2,3,3,2,1);
console.log(a.indexOf(2)); //1
console.log(a.lastIndexOf(2)); //4
console.log(a.IndexOf(4)); //-1,找不到

使用jQuery封装插件

发表于 2016-06-12   |   分类于 前端

jQuery封装插件的方法有三种:封装对象方法的插件、封装全局函数的插件、选择器插件

对象方法的插件

这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进行操作,是最常见的一种插件。此类插件可以发挥出jQuery选择器的强大优势,有相当一部分的jQuery的方法,都是在jQuery脚本库内部通过这种形式“插”在内核上的,例如parent()方法,appendTo()方法等。

添加一个对象扩展方法

1
2
3
4
5
6
$.fn.changeColor= function() {
this.css( "color", "red" );
};
$.fn.changeFont= function() {
this.css( "font-size", "24px" );
};

添加多个对象扩展方法

1
2
3
4
5
6
7
8
(function($){
$.fn.changeColor= function() {
this.css( "color", "red" );
};
$.fn.changeFont=function() {
this.css( "font-size", "24px" );
};
})(jQuery);

使用$.fn.extend(obj)方法

插件中不需要默认参数

1
2
3
4
5
6
7
8
9
10
(function($){
$.fn.extend({
"pluginName":function(){
this.each(function() {
//这里放置插件代码
});
return this;
}
});
})(jQuery);

插件中需要设置一些默认参数,可以使用\$.extend()进行扩展。在后面将对\$.fn.extend()和$.extend()进行详解

1
2
3
4
5
6
7
8
9
10
11
12
13
(function($){
$.fn.extend({
"pluginName":function(options){
options=$.extend({
//放置默认参数
},options);
this.each(function() {
//这里放置插件代码
});
return this;
}
});
})(jQuery);

全局函数的插件

可以将独立的函数加到jQuery命名空间下。如常用的jQuery.ajax()方去首尾空格的jQuery.trim()方法,都是jQuery内部作为全局函数的插件附加到内核上去的。

添加单个全局函数

1
2
3
$.ltrim = function( str ) {
return str.replace( /^\s+/, "" );
};

添加多个全局函数

1
2
3
4
5
6
7
$.ltrim = function( str ) {
return str.replace( /^\s+/, "" );
};
$.rtrim = function( str ) {
return str.replace( /\s+$/, "" );
};

使用$.extend()进行扩展(适合全局函数比较多的情况)

1
2
3
4
5
6
7
8
$.extend({
ltrim:function( str ) {
return str.replace( /^\s+/, "" );
},
rtrim:function( str ) {
return str.replace( /\s+$/, "" );
}
});

独立的命名空间

1
2
3
4
5
6
7
8
$.myPlugin={
ltrim:function( str ) {
return str.replace( /^\s+/, "" );
},
rtrim:function( str ) {
return str.replace( /\s+$/, "" );
}
};

选择器插件

虽然jQuery的选择器十分强大,但在少数情况下,还是会需要用到选择器插件来扩充一些自己喜欢的选择器。

编写jQuery选择器需要知道jQuery选择器的参数。

jQuery选择器函数一共接收3个参数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
function(a,i,m){
//第一个参数为a,指向当前遍历的DOM元素
//第二个参数为i,指的是当前遍历DOM元素的索引,从0开始
//第三个参数m比较特别,它是有jQuery正则引擎进一步解析后的产物(用match匹配出来的),结果是一个数组
//m[0],以例子$("div:gt(1)")来讲,是:gt(1)这部分
//m[1],选择器的引导符,匹配例子中的:号
//m[2],例子中的gt,确定是调用哪个选择器函数
//m[3],括号里的数字1,是编写选择器函数最重要的参数
//m[4],例子没有体现,略
}
}

构建选择器函数

例如编写$(“div:between(2,5)”)能实现获取索引值为3,4元素的功能
构建:

1
2
3
4
function(a,i,m){
var tmp=m[3].split(","); //将传进来的m[3]以逗号分隔开,转成一个数组
return tmp[0]-0<i&&i<tmp[1]-0;
}

扩展成jQuery选择器

1
2
3
4
5
6
7
8
(function(){
$.extend($.expr[":"],{
between:function(){
var tmp=m[3].split(",");
return tmp[0]-0<i&&i<tmp[1]-0;
}
})
})(jQuery)

插件的基本要点

  • Query插件的文件名推荐命名为jquery.[插件名].js,以免和其他JS库插件混淆。
  • 所有的对象方法都应当附加到jQuery.fn对象上,而所有的全局函数都应当附加到jQuery对象本身。
  • 在插件的范围里, this关键字代表了这个插件将要执行的jQuery对象;而在其他包含callback的jQuery函数中,this关键字代表了原生的DOM元素。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (function($){
    $.fn.m​​yPlugin =function(){
    //此处没有必要将this包在$号中如$(this),因为this已经是一个jQuery对象。
    //$(this)等同于 $($('#element'));
    this.fadeIn('normal',function(){
    //此处callback函数中this关键字代表一个DOM元素
    });
    };
    })(jQuery);
    $('#element').myPlugin();
  • 可以通过this.each方法来遍历所有元素。

  • 在插件头部加上一个分号,以免他人的不规范代码给插件带来影响。
  • 所有的方法或函数插件,都应当以分号结尾,以免压缩时出现问题
  • 除非插件需要返回的是一些需要获取的变量,插件应该返回一个jQuery对象,以保证插件的可链式操作。
  • 利于jQuery.extend()方法设置插件方法的默认参数,增加插件的可用性。

jQuery.fn.extend()与jQuery.extend()的对比

  • jQuery.fn.extend()是对于jQuery对象(原型)扩展的方法,因为jQuery.fn=jQuery.prototype
  • jQuery.extend()除了用于扩展jQuery全局函数和选择器函数之外,还有一个重要的功能,就是扩展已有的Objext对象
    语法:jQuery.extend(target,obj1,…[objN])

1、例如合并setting对象和options对象,修改并返回settings对象

1
2
3
4
5
var setting={validate:false,limit:5,name:"foo"}
var options={validate:true,name:"bar"}
var newOptions=jQuery.extend(setting,options)
//结果
newOptions={validate:true,limit:5,name:"bar"}

由此可见,内部机制是有扩展对象将覆盖与原对象相同的属性的值;若原对象不存在某属性,则进行扩展
2、jQuery.extend()常被用于设置插件方法的一系列默认参数,如下:

1
2
3
4
5
6
7
function foo(options){
options=jQuery.extend({
name:"bar",
length:5,
dataType:"xml" /*默认参数*/
},options) /*options为传递的参数*/
}

省、市、区三级联动菜单Demo

发表于 2016-06-08   |   分类于 前端
  • 前端模拟数据,省略请求数据
  • 封装成jQuery插件形式
  • 省、市、区选择弹出浮层信息

核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//初始化省
function province(){
$.each(areaJson, function(index, val) {
temp_option+="<option value="+val.p+">"+val.p+"</option>";
oProvince.html(temp_option);
});
}
//根据省赋值市
function city(){
temp_option=""+chooseC;
var proIndex=oProvince.get(0).selectedIndex-1;
if(proIndex>=0){
$.each(areaJson[proIndex].c, function(index, val) {
temp_option+="<option value="+val.ct+">"+val.ct+"</option>";
oCity.html(temp_option);
oDis.html(chooseD);
});
}else{
oCity.html(chooseC);
oDis.html(chooseD);
}
}
//赋值区|县
function district(){
temp_option=""+chooseD;
var proIndex=oProvince.get(0).selectedIndex-1;
var cityIndex=oCity.get(0).selectedIndex-1;
if( proIndex>=0 && cityIndex>=0){
if(typeof(areaJson[proIndex].c[cityIndex].d)!=="undefined"){
$.each(areaJson[proIndex].c[cityIndex].d, function(index, val) {
temp_option+="<option value="+val.dt+">"+val.dt+"</option>";
oDis.html(temp_option);
});
}else{
showInfo();
}
}else{
oDis.html(chooseD);
}
}
function showInfo(){
var proIndex=oProvince.get(0).selectedIndex;
var cityIndex=oCity.get(0).selectedIndex;
var disIndex=oDis.get(0).selectedIndex;
var p=oProvince.get(0).options[proIndex].value;
var c=oCity.get(0).options[cityIndex].value;
var d=disIndex>0?oDis.get(0).options[disIndex].value:"";
oShow.css("display","block").find("p").html(p+c+d);
}
function closeInfo(){
var btnClose=oShow.find(".btn-close");
var btnOk=oShow.find("button").eq(0);
var btnReset=oShow.find("button").eq(1);
var btnArr=[btnClose,btnOk,btnReset];
$.each(btnArr, function() {
$(this).click(function() {
oShow.css("display","none");
});
});
}
//调用初始化省
province();
//省发生变化改变市
oProvince.change(function() {
city();
});
//市发生变化改变区|县
oCity.change(function() {
district();
});
//区|县选择完后弹出浮层信息框
oDis.change(function() {
showInfo();
});

css模块化

发表于 2016-06-06

模块化定义

  • 一系列相关联的结构组成的整体
  • 带有一定语义,而非表现

怎么做

  1. 为模块分类命名(如m-,md-)
  2. 以一个主选择器开头(模块根节点)
  3. 使用以主选择器开头的后代选择器(模块子节点)

实例

Html代码

1
2
3
4
5
6
7
8
<!--Nav Module-->
<div class="m-nav">
<ul>
<li class="z-crt"><a href="#">index</a><li>
<li><a href="#">link1</a></li>...
</ul>
</div>
<!--End Nav Module-->

Css代码:

1
2
3
4
5
.m-nav{} /*模块容器*/
.m-nav li,.m-nav a{}
.m-nav li{}
.m-nav a{}
.m-nav .z-crt a{}

模块扩展

原模块:Html

1
2
3
4
5
6
7
8
<!--Nav Module-->
<div class="m-nav">
<ul>
<li class="z-crt"><a href="#">index</a><li>
<li><a href="#">link1</a></li>...
</ul>
</div>
<!--End Nav Module-->

基于原模块的扩展模块Html:新增一个class类,名为m-nav-n,n为正整数依次递增

1
2
3
4
5
6
7
8
9
<!--Nav-1 Module-->
<div class="m-nav m-nav-1">
<ul>
<li class="z-crt"><a href="#">index</a><li>
<li><a href="#">link1</a></li>...
</ul>
<a class="btn">Login</a>
</div>
<!--End Nav-1 Module-->

对模块和拓展模块设置css

1
2
3
4
5
6
7
8
9
10
/*导航模块*/
.m-nav{} /*模块容器*/
.m-nav li,.m-nav a{}
.m-nav li{}
.m-nav a{}
.m-nav .z-crt a{} /*交互状态变化*/
/*导航模块扩展*/
.m-nav-1{}
.m-nav-1 a{border-radius:5px; //设置扩展模块导航按钮有5px圆角}
.m-nav-1 btn{}

为什么要模块化

  • 利于多人协同开发
  • 便于扩展和重用
  • 可读性、可维护性好

如:

1
2
3
4
5
6
7
8
9
<div class="m-slides">
<ol>
<li class="slide z-crt"><img src="" alt=""></li>
<li class="slide"><img src="" alt=""></li>
<li class="slide"><img src="" alt=""></li>
<li class="slide"><img src="" alt=""></li>
<span class="ctrl"><i class="z-crt"></i><i></i><i></i><i></i></span>
</ol>
</div>

使用了外层div类名为m-slides时css结构清晰

1
2
3
4
5
6
7
8
/*模块化样式*/
.m-slides{}
.m-slides slide{}
.m-slides slide img{}
.m-slides li.z-crt{}
.m-slides .ctrl{}
.m-slides .ctrl i{}
.m-slides .ctrl i.z-crt{}

去掉外层div时css

1
2
3
4
5
6
7
8
/*未模块化样式*/
.slides{}
.slide{}
.slide img{}
li.z-crt{}
.ctrl{}
.ctrl i{}
i.z-crt{}

css命名规范总结(分类命名)

发表于 2016-06-06   |   分类于 前端

使用类选择器,放弃ID选择器

ID在一个页面中的唯一性导致了如果以ID为选择器来写CSS,就无法重用。

在样式命名中使用符号“-”

“-”在规范中并不表示连字符,而有两个含义:分类前缀分隔符、扩展分隔符

分类的命名方法:使用单个字母+”-“为前缀

布局(grid)(.g-);模块(module)(.m-);元件(unit)(.u-);功能(function)(.f-);皮肤(skin)(.s-);状态(.z-)。

  • 布局(grid)(.g-):将页面分割为几个大块,通常有头部、主体、主栏、侧栏、尾部等。
  • 模块(module)(.m-):通常是一个语义化的可以重复使用的较大的整体。比如导航、登录、注册、各种列表、评论、搜索等。
  • 元件(unit)(.u-):通常是一个不可再分的较为小巧的个体,通常被重复用于各种模块中。比如按钮、输入框、loading、图标等。
  • 功能(function)(.f-):为方便一些常用样式的使用,我们将这些使用率较高的样式剥离出来,按需使用,通常这些选择器具有固定样式表现,比如清除浮动等。
  • 皮肤(skin)(.s-):如果你需要把皮肤型的样式抽离出来,通常为文字色、背景色(图)、边框色等,非换肤型网站通常只提取文字色!(非换肤型网站不可滥用此类)
  • 状态(.z-):为状态类样式加入前缀,统一标识,方便识别,她只能组合使用或作为后代出现

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="g-header">...</div>
<div class="g-section">
<div class="m-article">
<div class="header">...</div>
</div>
</div>
<div class="g-footer">...</div>
/*布局样式*/
.g-header{color:black}
/*文章样式*/
.m-article{color:blue}
.m-article .header{font-size:12px;}

注:

  • 在样式中的选择器总是要以上面前五类开头,然后在里面使用后代选择器。
  • 如果这五类不能满足需求,可以另外定义一个或多个大类,但必须符合单个字母+”-“为前缀的命名规则,即 .x- 的格式。
  • 特殊:.j-将被专用于JS获取节点,请勿使用.j-定义样式。

后代选择器命名

  • 约定不以单个字母+ “-“ 为前缀且长度大于等于2的类选择器为后代选择器,如:.item为m-list模块里的每一个项,.text为m-list模块里的文本部分:.m-list .item{}.m-list .text{}。
  • 一个语义化的标签也可以是后代选择器,比如:.m-list li{}。
  • 不允许单个字母的类选择器出现,原因详见下面的“模块和元件的后代选择器的扩展类”。
  • 通过使用后代选择器的方法,你不需要考虑他的命名是否已被使用,因为他只在当前模块或元件中生效,同样的样式名可以在不同的模块或元件中重复使用,互不干扰;在多人协作或者分模块协作的时候效果尤为明显!

后代选择器不需要完整表现结构树层级,尽量能短则短。

注:后代选择器不要在页面布局中使用,因为污染的可能性较大;

1
2
3
4
5
6
7
8
/* 这里的.itm和.cnt只在.m-list中有效 */
.m-list{margin:0;padding:0;}
.m-list .itm{margin:1px;padding:1px;}
.m-list .cnt{margin-left:100px;}
/* 这里的.cnt和.num只在.m-page中有效 */
.m-page{height:20px;}
.m-page .cnt{text-align:center;}
.m-page .num{border:1px solid #ddd;}

命名应简约而不失语义

1
2
3
4
5
6
/* 反对:表现化的或没有语义的命名 */
.m-abc .green2{}
.g-left2{}
/* 推荐:使用有语义的简短的命名 */
.m-list .wrap2{}
.g-side2{}

相同语义的不同类命名

直接加数字或字母区分即可
如:.m-list、.m-list2、.m-list3等,都是列表模块,但是是完全不一样的模块。

其他举例:.f-fw0、.f-fw1、.s-fc0、.s-fc1、.m-logo2、.m-logo3、u-btn、u-btn2等等。

模块和元件的扩展类的命名方法

当A、B、C、…它们类型相同且外形相似区别不大,那么就以它们中出现率最高的做成基类,其他做成基类的扩展。

方法:+ “-” +数字或字母(如:.m-list的扩展类为.m-list-1、.m-list-2等)。

补充:基类自身可以独立使用(如:class=”m-list”即可),扩展类必须基于基类使用(如:class=”m-list m-list-2”)。

如果你的扩展类是表示不同状态,那么你可以这样命名:u-btn-dis,u-btn-hov,m-box-sel,m-box-hov等等,然后像这样使用:class=”u-btn u-btn-dis”。

如果你的网站可以不兼容IE6等浏览器,那么你标识状态的方法也可以采取独立状态分类(.z-)方法:.u-btn.z-dis,.m-box.z-sel,然后像这样使用:class=”u-btn z-dis”。

模块和元件的后代选择器的扩展类

有时候模块内会有些类似的东西,如果你没有把它们做成元件和扩展,那么也可以使用后代选择器和扩展。

后代选择器:.m-login .btn{}。

后代选择器扩展:.m-login .btn-1{},.m-login .btn-dis{} 。

同样也可以采取独立状态分类(.z-)方法:.m-login .btn.z-dis{},然后像这样使用:class=”btn z-dis”。

注:

  • 此方法用于类选择器,直接使用标签做为选择器的则不需要使用此命名方法。
  • 为防止后代选择器的扩展类和大类命名规范冲突,后代选择器不允许使用单个字母。

比如: .m-list .a{}是不允许的,因为当这个.a需要扩展的时候就会变成.a-bb,这样就和大类的命名规范冲突 。

分组选择器有时可以代替扩展方法

有时候虽然两个同类型的模块很相似,但是 你希望他们之间不要有依赖关系 ,也就是说你不希望使用扩展的方法,那么你可以 通过合并选择器来设置共性的样式 。

使用本方法的前提是:相同类型、功能和外观都相似,写在同一片代码区域方便维护。

1
2
3
4
5
6
7
8
9
10
/* 两个元件共性的样式 */
.u-tip1,.u-tip2{}
.u-tip1 .itm,.u-tip2 .itm{}
/* 在分别是两个元件各自的样式 */
/* tip1 */
.u-tip1{}
.u-tip1 .itm{}
/* tip2 */
.u-tip2{}
.u-tip2 .itm{}

防止污染和被污染

当模块或元件之间互相嵌套,且使用了相同的标签选择器或其他后代选择器,那么里面的选择器就会被外面相同的选择器所影响。

所以, 如果你的模块或元件可能嵌套或被嵌套于其他模块或元件,那么要慎用标签选择器 ,必要时采用类选择器,并注意命名方式,可以采用 .m-layer .layerxxx 、 .m-list2 .list2xxx 的形式来降低后代选择器的污染性。

正则表达式常用属性及方法

发表于 2016-06-02   |   分类于 前端

正则实例对象的5个属性

  • global:是否全局搜索,默认是false
  • ignoreCase:是否大小写敏感,默认是false
  • multiline:多行搜索,默认值是false
  • lastIndex:是当前表达式模式首次匹配内容中最后一个字符的下一个位置,每次正则表达式成功匹配时,lastIndex属性值都会随之改变。
  • source:正则表达式的文本字符串

正则表达式相关方法

正则表达式对象

regObj.test(strObj)

方法用于测试字符串参数中是否存正则表达式模式,如果存在则返回true,否则返回false

regObj.exec(strObj)

方法用于正则表达式模式在字符串中运行查找,如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。

调用非全局的 RegExp对象的 exec() 时,返回数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExp对象的第 2 个子表达式相匹配的文本(如果有的话),以此类推。

调用全局的RegExp对象的 exec() 时,它会在 RegExp实例的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExp实例的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。

字符串对象

strObj.search(RegObj)

search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。search() 方法不执行全局匹配,它将忽略标志 g。它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,这意味着它总是返回 stringObject 的第一个匹配的位置。

strObj.match(RegObj)

match() 方法将检索字符串 stringObject,以找到一个或多个与 regexp 匹配的文本。但regexp是否具有标志 g对结果影响很大。

如果 regexp 没有标志 g,那么 match() 方法就只能在 strObj 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。

strObj.replace(regObj,replaceStr)

关于strng对象的replace方法,我们最常用的时传入两个字符串的做法,但这种做法有个缺陷,只能replace一次

1
'abcabcabc'.replace('bc','X'); //aXabcabc

replace方法的第一个参数还可以传入RegExp对象,传入正则表达式可以时replace方法更加强大灵活

1
2
'abcabcabc'.replace(/bc/g,'X'); //aXaXaX
'abcaBcabC'.replace(/bc/gi,'X'); //aXaXaX

strObj.replace(regObj,function(){})

可以通过修改replace方法的第二个参数,使replace更加强大,在前面的介绍中,只能把所有匹配替换为固定内容,但如果我希望把一个字符串中所有数字,都用小括号包起来该怎么弄

1
2
3
'2398rufdjg9w45hgiuerhg83ghvif'.replace(/\d+/g,function(r){
return '('+r+')';
}); //"(2398)rufdjg(9)w(45)hgiuerhg(83)ghvif"

把replace方法的第二个参数传入一个function,这个function会在每次匹配替换的时候调用,算是个每次替换的回调函数,我们使用了回调函数的第一个参数,也就是匹配内容,其实回调函数一共有四个参数

  • 第一个参数很简单,是匹配字符串
  • 第二个参数是正则表达式分组内容,没有分组则没有该参数
  • 第三个参数是匹配项在字符串中的index
  • 第四个参数则是原字符串
1
2
3
4
5
6
7
8
9
'2398rufdjg9w45hgiuerhg83ghvif'.replace(/\d+/g,function(a,b,c){
console.log(a+'\t'+b+'\t'+c);
return '('+a+')';
});
2398 0 2398rufdjg9w45hgiuerhg83ghvif
9 10 2398rufdjg9w45hgiuerhg83ghvif
45 12 2398rufdjg9w45hgiuerhg83ghvif
83 22 2398rufdjg9w45hgiuerhg83ghvif

这是没有分组的情况,打印出来的分别是 匹配内容、匹配项index和原字符串,看个有分组的例子,如果我们希望把一个字符串的<%%>外壳去掉,<%1%><%2%><%3%> 变成123

1
2
3
4
5
6
7
8
'<%1%><%2%><%3%>'.replace(/<%([^%>]+)%>/g,function(a,b,c,d){
console.log(a+'\t'+b+'\t'+c+'\t'+d);
return b;
}) //123
<%1%> 1 0 <%1%><%2%><%3%>
<%2%> 2 5 <%1%><%2%><%3%>
<%3%> 3 10 <%1%><%2%><%3%>

根据这种参数replace可以实现很多强大的功能,尤其是在复杂的字符串替换语句中经常使用。

strObj.split(regObj)

我们经常使用split方法把字符串分割为字符数组

1
'a,b,c,d'.split(','); //["a", "b", "c", "d"]

和replace方法类似,在一些复杂的分割情况下我们可以使用正则表达式解决

1
'a1b2c3d'.split(/\d/); //["a", "b", "c", "d"]

这样就可以按照数字分割字符串了。

正则表达式语法详解

发表于 2016-06-02   |   分类于 前端

正则表达式的定义

可以使用Regexp()构造函数来创建Regexp对象,不过更多的是通过一种特殊的直接量语法来创建。直接量定义为包含在一对斜杠(/)之间的字符。例如:

1
var pattern=/s$/

ES3规范规定,一个正则表达式直接量在执行它时转换为一个Regexp对象,同一段代码表示的正则每次运算都指向同一个对象;ES5规范做了相反规定,每次运算都返回新的对象。

直接量字符

直接量字符包含所有的字母和数字,以及转义字符。
直接量字符列表:

字符 匹配
字母和数字组合 自身
\o NUL字符(\u0000)
\t 制表符(\u0009)
\n 换行符()
\v 垂直制表符
\f 换页符
\r 回车符
\xnn 由16进制数nn指定的拉丁字符
\uxxxx 由16进制数xxxx指定的Unicode字符
\cX 控制字符^X,例如\cJ等价于换行符\n

在正则表达式中,许多标点符号具有特殊的含义,他们是:
^ $ . * + ? = ! : | \ / ( ) [ ] { }
如果想匹配这些字符,同样需要\进行转义。其他标点符号(比如:@ ~ 引号 逗号 分号 横杆)没有特殊含义,将按照字面含义进行匹配

正则中需要转义的特殊字符

特别字符 说明
$ 匹配输入字符串的结尾位置。如果设置了RegExp对象的Multiline属性,则 $ 也匹配\n或\r。要匹配 $字符本身,请使用\
() 标记一个子表达式的开始和结束位置,子表达式可以获取供以后使用。要匹配这些字符,请使用 \ ( 和 \ )
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用\
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \
. 匹配除换行符 \n之外的任何单字符。要匹配 “.”,请使用 \
[] 标记一个中括号表达式的开始。要匹配 [,请使用 \ [
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\ \’ 匹配 “\”,而 ‘\ (‘ 则匹配 “(”。
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
{} 标记限定符表达式的开始。要匹配 {,请使用 \ {。
竖杠 指明两项之间的一个选择。要匹配竖杠,请使用 \竖杠。

字符类

将字面量字符单独放进放括号内就组成了字符类。
“^”符号可以否定字符类
“-”可以用来表示字符的范围

字符 匹配
[…] 方括号内的任意字符
[^…] 不在方括号内的任意字符
. 除换行符和其他unicode行终止符之外的任意字符)
\w 任何ASCII字符组成的单词,等价于[a-zA-Z0-9_]
\W 任何不是ASCII字符组成的单词,等价于[^a-zA-Z0-9_]
\s 任何unicode空白字符
\S 任何非unicode空白符的字符,注意\w和\S不同
\d 任何ASCII数字,等价于[0-9]
\D 除了ASCII数字之外的任何字符,等价于[^0-9]
[\b] 退格直接量(特例)

\w 表示匹配大小写英文字母、数字以及下划线,等价于[a-zA-Z0-9_]。
\S 表示匹配非空白字符,范围广,只要不是空格、换行符、制表符、换页符即可

重复

正则模式之后跟随用以指定字符重复的标记。由于某些重复种类非常常用,因此就有一些专门用于表示这种情况的特殊字符。
正则表达式的重复字符语法:

字符 含义
{n,m} 匹配前一项至少n次,但不能超过m次
{n,} 匹配前一项n次或者更多次
{n} 匹配前一项n次
? 匹配前一项0次或者1次,也就是说前一项可选,等价于{0,1}
+ 匹配前一项1次或者多次,等价于{1,}
* 匹配前一项0次或者多次,等价于{0,}

例子:

1
2
3
4
/\d{2,4}/ //匹配2~4个数字
/\w{3}\d?/ //匹配3个单词和一个可选的数字
/\s+java\s+/ //匹配前后带有一个或多个空格的字符串“java”
/[^(]*/ //匹配0个或者多个非左括号的字符

在使用星号和问号时要注意,由于这些字符可能匹配0个字符,因此他们允许什么都不匹配。例如正则/ a*/实际上与字符串“bbbb”匹配,因为这个字符串含有0个a。

贪婪匹配和非贪婪匹配
以上的重复匹配属于贪婪的匹配,即尽可能多的匹配;若要尽可能地少匹配,只需在重复字符后面跟随一个“?”即可。
比如正则表达式/a+/可以匹配一个或多个连续的字母a。当使用“aaa”作为匹配字符串时,正则表达式会匹配它的三个字符。但是/a+?/也可以匹配一个或多个连续字母a,同样以“aaa”作为匹配字符串,此时只匹配第一个a。

但是,非贪婪匹配可能和所匹配的预期不一致。这里提一下正则的机制,它总是会寻找字符串中第一个可能匹配的位置。比如/a+?b/,当用它来匹配“aaab”时,它实际上匹配了整个字符串,而非匹配一个a和最后一个b。

选择、分组和引用

选择字符:|
说明:选择字符匹配尝试从左到右,直到发现匹配项。如果左边的选择项匹配,就忽略右边匹配项。

组合字符:(…) 和(? : …)

引用字符:\n,n为大于等于1的正整数,表示引用与第n个分组相匹配的文本的引用,而非子表达式模式的引用。例如:

1
/['"][^'"]*['"]/

匹配的是位于单引号或双引号之内的0个或多个字符,但是,它并不要求左侧和右侧的引号相同。

1
/(['"])[^'"]*\1/

匹配位于单引号或双引号之内的0个或多个字符,并且左右两侧引号必须相同,这就是文本引用产生的结果。

正则表达式的选择、分组、和引用字符

字符 含义
竖杠 选择,匹配的是该符号左边的子表达式或右边的子表达式
(…) 将几个项组合为一个单元,这个单元可以通过“*”,“+”,“?”等符号加以修饰,而且可以记住和这个组合相匹配的字符串以供此后的引用使用。
(?:…) 只组合,把项组合成一个单元,但不记忆与改组相匹配的字符
\n 引用第n个分组第一次匹配的字符,组是圆括号中的子表达式(也有可能是嵌套的),组索引是从左到右的左括号数,“?:”形式的分组不编码

ajax请求数据

发表于 2016-05-25   |   分类于 前端

表单数据提交

核心方法:serialize():可以将表单中的数据序列化成key=value&key=value…的形式
核心代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$("#test").submit(function() {
$.ajax({
type: "POST",
url:"form.php",
data:$('#test').serialize(),// 你的formid
success: function(data) {
$("#res").html(data);
},
error: function(request) {
alert("Connection error");
}
});
return false; // 阻止表单默认提交事件,防止页面跳转
});

PHP获取数据的方式

ajax中data可以提交的数据方式:
普通键值对的方式:PHP后台可以通过_POST[‘键名’]或 _GET[‘键名’]获取数据

1
2
3
4
5
6
7
8
9
10
11
$.ajax({
url: 'test2.php',
type: 'POST',
data: {"姓名": '张三',"年龄":14}, //等价于"姓名=张三&年龄=14",属于传入基本键值对
success: function(data){
$("#content").html(data);
},
error:function() {
alert("connection fail");
}
});

json字符串的方式(需要制定contentType):后台通过file_get_contents(‘php://input’)获取数据

1
2
3
4
5
6
7
8
9
10
11
12
$.ajax({
type: "POST",
url:"test1.php",
**contentType:"application/json;charset=utf-8"**,
data: JSON.stringify(json),
error: function(request) {
alert("Connection error");
},
success: function(data) {
$("#container").html(data);
}
});

PHP输出json字符串数据

在PHP中比较常用的是数组,而PHP中json不是标准数据格式,所以PHP提供了对json数据进行编码和解码的函数。

  • json_encode($arr):将数组转化为json数据格式(json字符串)
  • json_decode(json):将json解析成PHP对象,通常会添加第二个参数true,此时会解析成PHP数组
1
2
3
4
5
6
7
<?php
header("Content-type:text/html;charset=utf-8");
$arr = array('姓名' => '张三', '年龄' => '14', '性别' => '男');
$res =json_encode($arr) ;
//当使用php自带的json_encode对数据进行编码时,中文都会变成unicode,导致不可读。如:对字符串”厦门“进行json_encode后,输出的是"\u53a6\u95e8"。经测试前端通过JSON.parse()解析出json对象后乱码消失
echo($res);
?>
1234
TeaCoder

TeaCoder

写精致代码,过简单生活

36 日志
6 分类
35 标签
RSS
掘金 GitHub 知乎
© 2015 - 2021 TeaCoder