叁个多月没更新了-,以一九七零年一月1日子夜为

2019-11-08 02:59栏目:前端开发
TAG:

JS原生Date类型方法的一些冷知识

2015/09/07 · JavaScript · Date

原文出处: chitanda   

一个多月没更新了- -偷懒中。这个东西其实很早之前就在整理了,不过后来发现自己不少地方没弄明白,然后就一直卡那边了(其实就是不想写吧),想了下反正是给自己熟悉js的原生API而已,所以也没必要太钻牛角尖,也不一定要多完整,因此就当是Date()函数的一个冷门知识点小补充吧。这篇文章主要讲Date()的字符串与时间戳转换以及用户时间本地化,可能内容上比较乱(不然也不会卡我一个月时间了),见谅

ps:由于 Date() 是js原生函数,不同浏览器的解析器对其实现方式并不同,所以返回值也会有所区别。本文测试未特别申明浏览器的情况下,均是指 win7 x64+chrome 44.0.2403.155 (正式版本) m (32 位) 版本

  • 显示警告时,JavaScript脚本会被挂起。

       我平时的软件开发中,信息的搜索是经常碰到的,增加搜索关键字提示是提高用户体验的一种很好的办法。今天就介绍下在ASP.NET如何利用AJAX来实现搜索的信息提示!

Date()与new Date()的区别

Date() 直接返回当前时间字符串,不管参数是number还是任何string

JavaScript

Date(); Date('sssss'); Date(1000); //Fri Aug 21 2015 15:46:21 GMT+0800 (中国标准时间)

1
2
3
4
Date();
Date('sssss');
Date(1000);
//Fri Aug 21 2015 15:46:21 GMT+0800 (中国标准时间)

而 new Date() 则是会根据参数来返回对应的值,无参数的时候,返回当前时间的字符串形式;有参数的时候返回参数所对应时间的字符串。 new Date() 对参数不管是格式还是内容都要求,且只返回字符串,

JavaScript

new Date(); //Fri Aug 21 2015 15:51:55 GMT+0800 (中国标准时间) new Date(1293879600000); new Date('2011-01-01T11:00:00') new Date('2011/01/01 11:00:00') new Date(2011,0,1,11,0,0) new Date('jan 01 2011,11 11:00:00') new Date('Sat Jan 01 2011 11:00:00') //Sat Jan 01 2011 11:00:00 GMT+0800 (中国标准时间) new Date('sss'); new Date('2011/01/01T11:00:00'); new Date('2011-01-01-11:00:00') new Date('1293879600000'); //Invalid Date new Date('2011-01-01T11:00:00')-new Date('1992/02/11 12:00:12') //596069988000

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
new Date();
//Fri Aug 21 2015 15:51:55 GMT+0800 (中国标准时间)
 
new Date(1293879600000);
new Date('2011-01-01T11:00:00')
new Date('2011/01/01 11:00:00')
new Date(2011,0,1,11,0,0)
new Date('jan 01 2011,11 11:00:00')
new Date('Sat Jan 01 2011 11:00:00')
//Sat Jan 01 2011 11:00:00 GMT+0800 (中国标准时间)
 
new Date('sss');
new Date('2011/01/01T11:00:00');
new Date('2011-01-01-11:00:00')
new Date('1293879600000');
//Invalid Date
 
new Date('2011-01-01T11:00:00')-new Date('1992/02/11 12:00:12')
//596069988000

从上面几个测试结果可以很容易发现

  1. new Date() 在参数正常的情况只会返回当前时间的字符串(且是当前时区的时间)
  2. new Date() 在解析一个具体的时间的时候,对参数有较严格的格式要求,格式不正确的时候会直接返回Invalid Date,比如将 number 类的时间戳转换成 string 类的时候也会导致解析出错
  3. 虽然 new Date() 的返回值是字符串,然而两个 new Date() 的结果字符串是可以直接相减的,结果为相差的毫秒数。

那么, new Date() 能接受的参数格式到底是什么标准呢?(相对于严格要求的多参数传值方法。非严格的单参数(数字日期表示格式)更常用且更容易出错,所以下文只考虑单参数数字时间字符串转换的情况)

表示格式)更常用且更容易出错,所以下文只考虑单参数数字时间字符串转换的情况)


 

new Date()解析所支持的参数格式标准

  • 对象构造函数示例:

       1.需要了解的一些知识点

时间戳格式

这个是最简单的也是最不容易出错的。当然唯一的缺点大概就是对开发者不直观,无法一眼看出具体日期。
需要注意的以下两点:

  1. js内的时间戳指的是当前时间到1970年1月1日00:00:00 UTC对应的毫秒数,和unix时间戳不是一个概念,后者表示秒数,差了1000倍
  2. class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-r">new class="crayon-r">Date( class="crayon-v">timestamp class="crayon-sy">) 中的时间戳必须是number格式, class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-t">string 会返回Invalid Date。所以比如new Date('11111111')这种写法是错的

  

           (1)AJAX对象不同浏览器的创建

时间数字字符串格式

不大清楚这种该怎么描述,就是类似YYYY/MM/DD HH:mm:SS这种。下文以dateString代指。
new Date(dateString)所支持的字符串格式需要满足RFC2822标准或者ISO 8601标准
这两种标准对应的格式分别如下:

  1. RFC2822 标准日期字符串
JavaScript

YYYY/MM/DD HH:MM:SS ± timezon(时区用4位数字表示) // eg 1992/02/12
12:23:22+0800

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6c187675a314957670-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6c187675a314957670-2">
2
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6c187675a314957670-1" class="crayon-line">
YYYY/MM/DD HH:MM:SS ± timezon(时区用4位数字表示)
</div>
<div id="crayon-5b8f6c187675a314957670-2" class="crayon-line crayon-striped-line">
// eg 1992/02/12 12:23:22+0800
</div>
</div></td>
</tr>
</tbody>
</table>

>  RFC2822还有别的格式,不过上面这个是比较常用的(另外这标准太难啃了,实在没耐心啃完,所以也就没太深入)。RFC2822标准本身还有其他的非数字日期表达方式,不过不在这个话题讨论范围内了,略过
  1. ISO 8601标准日期字符串
JavaScript

YYYY-MM-DDThh:mm:ss ± timezone(时区用HH:MM表示) 1997-07-16T08:20:30Z
//
“Z”表示UTC标准时区,即"00:00",所以这里表示零时区的`1997年7月16日08时20分30秒`
//转换成位于东八区的北京时间则为`1997年7月17日16时20分30秒`
1997-07-16T19:20:30+01:00 //
表示东一区的1997年7月16日19时20秒30分,转换成UTC标准时间的话是1997-07-16T18:20:30Z

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6c187675d765819674-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6c187675d765819674-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6c187675d765819674-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6c187675d765819674-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6c187675d765819674-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6c187675d765819674-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f6c187675d765819674-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6c187675d765819674-8">
8
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6c187675d765819674-1" class="crayon-line">
 YYYY-MM-DDThh:mm:ss ± timezone(时区用HH:MM表示)
</div>
<div id="crayon-5b8f6c187675d765819674-2" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f6c187675d765819674-3" class="crayon-line">
 1997-07-16T08:20:30Z
</div>
<div id="crayon-5b8f6c187675d765819674-4" class="crayon-line crayon-striped-line">
 // “Z”表示UTC标准时区,即&quot;00:00&quot;,所以这里表示零时区的`1997年7月16日08时20分30秒`
</div>
<div id="crayon-5b8f6c187675d765819674-5" class="crayon-line">
 //转换成位于东八区的北京时间则为`1997年7月17日16时20分30秒`
</div>
<div id="crayon-5b8f6c187675d765819674-6" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f6c187675d765819674-7" class="crayon-line">
 1997-07-16T19:20:30+01:00
</div>
<div id="crayon-5b8f6c187675d765819674-8" class="crayon-line crayon-striped-line">
 // 表示东一区的1997年7月16日19时20秒30分,转换成UTC标准时间的话是1997-07-16T18:20:30Z
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 日期和时间中间的T不可以被省略,一省略就出错。
  2. 虽然在chrome浏览器上时区也可以用+0100这种RFC2822的形式来表示,然而IE上不支持这种混搭写法,所以用ISO8601标准形式表示的时候时区要用+HH:MM

单单从格式上来说,两者的区别主要在于分隔符的不同。不过需要注意的是,ISO 8601标准的兼容性比RFC2822差得多(比如IE8和iOS均不支持前者。我知道IE8很多人会无视,不过iOS也有这个坑的话,各位或多或少会谨慎点了吧?),所以一般情况下建议用RFC 2822格式的。
不过需要注意的是,在未指定时区的前提下,对于只精确到day的日期字符串,RFC 2822返回结果是以当前时区的零点为准,而ISO8601返回结果则会以UTC时间的零点为标准进行解析。
例如:

JavaScript

//RFC2822: new Date('1992/02/13') //Thu Feb 13 1992 00:00:00 GMT+0800 (中国标准时间) //ISO8601: new Date('1992-02-13') //Thu Feb 13 1992 08:00:00 GMT+0800 (中国标准时间)

1
2
3
4
//RFC2822:
new Date('1992/02/13') //Thu Feb 13 1992 00:00:00 GMT+0800 (中国标准时间)
//ISO8601:
new Date('1992-02-13') //Thu Feb 13 1992 08:00:00 GMT+0800 (中国标准时间)

 

然而上面这个只是ES5的标准而已,在ES6里这两种形式都会变成当前时区的零点为基准1
*不管你们崩溃没,反正我是已经想死了*
关于跨浏览器的dataString解析情况,还可以参考这个页面:
JavaScript and Dates, What a Mess!

所以对于时间字符串对象,个人意见是要么用RFC2822形式,要么自己写个解析函数然后随便你传啥格式进来。


 1 function Card (name, address, work, home){
 2 
 3   this.name = name;
 4 
 5   this.address = address;
 6   
 7   this.work = work;
 8   
 9   this.home = home;
10 
11 }

                   不同的浏览器对AJAX(XMLHttpRequest)对象的实现是不一样的,例如IE浏览器是通过ActiveX控件来实现AJAX对象。而其他一些浏览器比如火狐,它将AJAX对象实现成了一个浏览器内部的对象叫XMLHttpRequest,所以不同的浏览器创建AJAX对象的方式也就不同,那么我们来看看不同浏览器之间创建AJAX对象的方式:

时间格式化函数的效率

这里的时间格式化值得是将时间字符串转换成毫秒数的过程。js原生的时间格式化函数有Date.parseDate.prototype.valueOfDate.prototype.getTimeNumber(Date)+Date(还有个Date.UTC方法,然而对参数要求严格,不能直接解析日期字符串,所以略过)
这5个函数从功能上来说一模一样,但是具体的效率如何呢?我写了个检测页面,诸位也可以自己测试下。
点击预览

 

                   在IE浏览器下面的创建:

核心测试函数:

JavaScript

function test(dateString,times,func){ var startTime=window.performance.now(); // console.log('start='+startTime.getTime()); for (var i = 0; i < times; i++) { func(dateString);//这里填写具体的解析函数 }; var endTime=window.performance.now(); // console.log('endTime='+endTime.getTime()); var gapTime=endTime-startTime; console.log('一共耗时:'+gapTime+'ms'); // console.log('时间字符串'+dateString); return gapTime; }

1
2
3
4
5
6
7
8
9
10
11
12
13
    function test(dateString,times,func){
    var startTime=window.performance.now();
    // console.log('start='+startTime.getTime());
    for (var i = 0; i < times; i++) {
        func(dateString);//这里填写具体的解析函数
    };
    var endTime=window.performance.now();
    // console.log('endTime='+endTime.getTime());
    var gapTime=endTime-startTime;
      console.log('一共耗时:'+gapTime+'ms');
    // console.log('时间字符串'+dateString);
    return gapTime;
}

 

之所以这里用window.performance.now()而不用new Date(),是因为前者精确度远比后者高。后者只能精确到ms。会对结果造成较大影响

  • 使用Prototype扩展内置对象,示例:

        //IE浏览器
        try {
            //IE5.0

            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                //IE5.5 以上版本

                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) { }

测试结果:

单次执行50W次时间格式化函数,并重复测试100次,最后的结果如下:
(表格中的数字为单次执行50W次函数的平均结果。单位为毫秒)

函数 chrome IE Firefox
Date.parse() 151.2087 55.5811 315.0446
Date.prototype.getTime() 19.5452 21.3423 14.0169
Date.prototype.valueOf() 20.1696 21.7192 13.8096
+Date() 20.0044 31.3511 22.7861
Number(Date) 23.0900 24.8838 23.3775

从这个表格可以很容易得出以下结论:

  1. 从计算效率上来说,Date.prototype.getTime()Date.prototype.valueOf()>+DateNumber(Date)>>Date.parse()
  2. 从代码书写效率上来说,对于少量的时间格式化计算,用+Date()或者Number(Date)即可。而若页面内有大量该处理,则建议用Date原生的函数Date.prototype.getTime()或者Date.prototype.valueOf().只有Date.parse,找不到任何使用的理由。
  3. 这个结果和计算机的计算性能以及浏览器有关,所以具体数字可能会有较大偏差,很正常。然而几个函数结果的时间差大小顺序并不会变。
  4. codepen的在线demo限制比较大,对于这个测验个人建议最好将源代码复制到本地文件然后进行测试

``

   

UTC,GMT时间的区别

这个不是啥重要东西,单纯当课外知识吧。

 1 function addhead(level){
 2 
 3  html = "H" +level;
 4 
 5  text = this.toString();
 6 
 7  start = "<" + html +">";
 8 
 9  end = "</" + html +">";
10 
11 return start + text + end;
12 
13 }
14 
15 String.prototype.heading = "head";
16 
17 document.write ("This is a heading 1".heading(1));
18 
19 //output: "<H1>This is a heading 1<H2>"

                   在火狐浏览器下面的创建:

格林威治标准时间GMT

GMT即「格林威治标准时间」(Greenwich Mean Time,简称G.M.T.),指位于英国伦敦郊区的皇家格林威治天文台的标准时间,因为本初子午线被定义为通过那里的经线。然而由于地球的不规则自转,导致GMT时间有误差,因此目前已不被当作标准时间使用。

``

        //火狐, Safari 等浏览器
        httpRequest = new XMLHttpRequest();

世界协调时间UTC

UTC是最主要的世界时间标准,是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间。UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。不过日常使用中,GMT与UTC的功能与精确度是没有差别的。
协调世界时区会使用“Z”来表示。而在航空上,所有使用的时间划一规定是协调世界时。而且Z在无线电中应读作“Zulu”(可参见北约音标字母),协调世界时也会被称为“Zulu time”。

 

                   多浏览器AJAX对象创建函数: 

浏览器获取用户当前时间以及喜好语言

首先需要注意一点,浏览器获取当前用户所在的时区等信息只和系统的日期和时间设置里的时区以及时间有关。区域和语言设置影响的是浏览器默认时间函数(Date.prototype.toLocaleString等)显示的格式,不会对时区等有影响。以window为例,控制面板时钟、语言和区域中的两个子设置项目的区别如下:

日期和时间:设置当前用户所处的时间和时区,浏览器获取到的结果以此为准,哪怕用户的设置时间和时区是完全错误的。比如若东八区的用户将自己的时区设置为东9区,浏览器就会将视为东9区;时间数据上同理。这里的设置会影响Date.prototype.getTimezoneOffsetnew Date()的值

区域和语言:主要是设置系统默认的时间显示方式。其子设置的格式会影响Date.prototype.toLocaleString方法返回的字符串结果

  • if( next > " ") statement ; 

function** createAjaxObj() {
    var httpRequest = false;

浏览器判断用户本地字符串格式

Date有个 Date.prototype.toLocaleString() 方法可以将时间字符串返回用户本地字符串格式,这个方法还有两个子方法 Date.prototype.toLocaleDateString 和 Date.prototype.toLocaleTimeString ,这两个方法返回值分别表示日期时间,加一起就是 Date.prototype.toLocaleString 的结果。
这个方法的默认参数会对时间字符串做一次转换,将其转换成用户当前所在时区的时间,并按照对应的系统设置时间格式返回字符串结果。然而不同浏览器对用户本地所使用的语言格式的判断依据是不同的。
IE:获取系统当前的区域和语言格式中设置的格式,依照其对应的格式来显示当前时间结果;IE浏览器实时查询该系统设置(即你在浏览器窗口打开后去更改系统设置也会引起返回格式变化)
FF:获取方式和结果与IE浏览器相同,区别在于FF只会在浏览器进程第一次启动的时候获取一次系统设置,中间不管怎么系统设置怎么变化,FF都无法获取到当前系统设置。除非重启FF浏览器。
Chrome:获取方式和以上两个都不同。chrome无视系统的区域和语言格式格式,只依照自己浏览器的界面设置的菜单语言来处理。(比如英文界面则按系统’en-US’格式返回字符串,中文界面则按系统’zh-CN’格式返回结果)
综上可得:

chrome下浏览器语言设置优先系统语言设置。而IE和FF则是系统语言设置优先浏览器语言设置,不管浏览器界面语言是什么,他们只依照系统设置来返回格式。(没有MAC,所以不知道safari是啥情况,等以后看情况补充吧)
另外,不同浏览器对toLocaleString返回的结果也是不同的,IE浏览器严格遵守系统设置,而chrome和FF会有自己内置的格式来替换。

注:将 next 与空格的进行大小比较,这里比较的是两者的 ASCII 码值大小,当大于空格时,可以粗略的认为是有有效输入(视应用场景)

    //判断是否包含XMLHttpRequest对象 PS:将来IE高也有可能继承次对象     if (window.XMLHttpRequest) {
        //火狐 , Safari 等浏览器         httpRequest = new XMLHttpRequest();
        if (httpRequest.overrideMimeType)
            httpRequest.overrideMimeType('text/xml'**);
    }//判断是否支持Active控件对象
    else if (window.ActiveXObject) {
        //IE浏览器

        try {
            //IE5.0

            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                //IE5.5以上

                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (e) { }
        }
    }
    //返回创建好的AJAX对象

    return** httpRequest;
}**

浏览器界面语言设置和语言设置的区别

这小节貌似有点跑题,然而不说明下的很容易和上面提到的浏览器设置的语言混淆,所以也拿出来说一下。
需要注意浏览器的语言设置和界面语言设置不是一回事
浏览器的语言设置设置的是浏览器发送给服务器的Request Header里的Accept-Language的值,这个值可以告诉服务器用户的喜好语言,对于某些跨国网站,服务器可以以此为依旧来返回对应语言的页面(不过实际应用上这个限制比较大,大部分网站还是根据IP来判断用户来源的,或者直接让用户自己选择)
对于各大浏览器而言,这个设置的更改也是比较显性,容易找到的。
IE: Internet选项语言
FF: 选项内容语言
chrome:设置显示高级设置语言语言和输入设置...
上面这里的设置不会影响到浏览器的界面语言设置,以国内大部分用户而言,即不管你怎么设置这里的语言选项,浏览器菜单等默认都会是以中文显示的.
浏览器的界面语言设置一般来说则藏的深得多,没那么容易找到。
IE:
卸载前面安装过的浏览器语言包,去微软官网下载对应的IE浏览器语言包安装。(和安装的语言包有关。系统界面语言和该语言包相同的情况下,变为该语言。否则以安装的语言包为准。)
FF:地址栏输入about:config,然后找到general.useragent.locale字段,修改对应字段即可。
chrome:设置显示高级设置语言语言和输入设置...

  • 在JavaScript中,显示的字段用  '   ' 符号包围;

 

利用js获取用户浏览器语言喜好

对于获取这两种设置,js原生方法支持度都比较一般:
IE下的 navigator 方法有四种和language有关的方法,区别如下:
假设系统语言为  ja-JP ,系统unicode语言为 zh-CN 日期格式为nl-NL,浏览器语言设置(accept-language)为 de ,浏览器界面语言为 en-US (其他条件不变,浏览器界面语言改为 zh-CN 的时候结果也是一样),

JavaScript

window.navigator.language //"nl-NL" window.navigator.systemLanguage //"zh-CN"(设置中的非unicode程序所使用语言选项) window.navigator.userLanguage //"nl-NL" window.navigator.browserLanguage //"ja-JP"(系统菜单界面语言) window.navigator.languages //undefined

1
2
3
4
5
6
7
8
9
10
window.navigator.language
//"nl-NL"
window.navigator.systemLanguage
//"zh-CN"(设置中的非unicode程序所使用语言选项)
window.navigator.userLanguage
//"nl-NL"
window.navigator.browserLanguage
//"ja-JP"(系统菜单界面语言)
window.navigator.languages
//undefined

chrome下,当浏览器界面语言为 zh-CN, accept-language首位为 en-US 的时候:

JavaScript

window.navigator.language //'zh-CN' window.navigator.languages //["en-US", "en", "zh-CN", "zh", "ja", "zh-TW", "de-LI", "de", "pl"] //当界面语言改为"en-US"时 window.navigator.language //'en-US'(浏览器界面语言)

1
2
3
4
5
6
7
window.navigator.language
//'zh-CN'
window.navigator.languages
//["en-US", "en", "zh-CN", "zh", "ja", "zh-TW", "de-LI", "de", "pl"]
//当界面语言改为"en-US"时
window.navigator.language
//'en-US'(浏览器界面语言)

FF下,当浏览器界面语言为 zh-CN ,accept-language首位为 en-US 的时候:

JavaScript

window.navigator.language //'en-US' window.navigator.languages //["en-US", "zh-CN", "de", "zh", "en"] //当界面语言改为"en-US",`accept-language`首位为`zh-CN`的时候 window.navigator.language //'zh-CN'(`accept-language`首选值) window.navigator.languages //["zh-CN", "de", "zh", "en-US", "en"]

1
2
3
4
5
6
7
8
9
window.navigator.language
//'en-US'
window.navigator.languages
//["en-US", "zh-CN", "de", "zh", "en"]
//当界面语言改为"en-US",`accept-language`首位为`zh-CN`的时候
window.navigator.language
//'zh-CN'(`accept-language`首选值)
window.navigator.languages
//["zh-CN", "de", "zh", "en-US", "en"]
  1. 从上面的测试结果可以很明显的发现IE浏览器的这几个函数都是获取系统信息的,无法获取到前面提到的两个浏览器层面上的设置。(这几个函数具体含义还有疑问的可以参考MSDN官方文档)
  2. class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-v">window class="crayon-sy">. class="crayon-v">navigator class="crayon-sy">. class="crayon-v">language 这个函数虽然三个浏览器都可以兼容,然而代表的意义完全不同。IE下该函数返回系统设置的时间显示格式所遵守的标准的地区代码;chrome下返回浏览器界面语言;FF下返回accept-language的首选语言值

由此:

  1. 浏览器设置的语言accept-language值,IE浏览器无法利用JS获取。chrome和FF浏览器都可以利用
     class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco"
    
    style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-v">window class="crayon-sy">. class="crayon-v">navigator class="crayon-sy">. class="crayon-v">languages 来获取,而FF还可以直接用 
     class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco"
    
    style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-v">window class="crayon-sy">. class="crayon-v">navigator class="crayon-sy">. class="crayon-v">language 直接获取accept-language的首选语言值。所以对于accept-language,兼容性最好的获取方法应该是利用后端,发起一个ajax请求,分析header。而不是直接js来处理。
  2. 浏览器界面语言,IE和FF都无法利用js来获取,chrome可以用 id="crayon-5b8f6c18767b3253782986" class="crayon-syntax crayon-syntax-inline crayon-theme-github crayon-theme-github-inline crayon-font-monaco" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important;"> class="crayon-pre crayon-code" style="font-size: 13px !important; line-height: 15px !important;font-size: 13px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;"> class="crayon-v">window class="crayon-sy">. class="crayon-v">navigator class="crayon-sy">. class="crayon-v">language 来获取
  3. 系统级别的语言设置(系统菜单界面语言,系统设置的时间显示格式),chrome和FF都无法用JS获取到

 

          (2)文本框内容改变的事件在不同浏览器下的使用

总结

这篇文章断断续续地写了一个多月,不过由于对 Date() 函数的掌握不足因此个人感觉其实还是思路有点乱,所以文章看起来可能稍微有点跳跃性。不过用户本地化那块内容确实用了不少心思去写,希望对看到这篇文章的人有点帮助。

  • 使用循环navigator遍历对象属性:

                  文本框内容改变的事件目前来说还没有一个标准的版本。我们目前只关心IE与火狐好了,那么在IE和火狐下这两个时间分别怎么表示呢?

参考文献

  1. Date and Time Formats
  2. Date and Time Specification(RFC2822)
  3. Date.parse()-Differences in assumed time zone
  4. JavaScript and Dates, What a Mess!
  5. navigator object(IE浏览器私有language函数的解析)

    1 赞 收藏 评论

图片 1

``

                  IE: onpropertychange

1 for(i in navigator){
2     document.write("property:" + i);
3 
4     document.write(" value:" + navigator[i] + "<br>");
5 
6 }

           FireFox: oninput

``

                 那么如何在页面加载时,根据浏览器给文本框附加对应的change事件呢?

 

                 1.JS如何判断浏览器版本                   

window.navigator 对象包含有关访问者浏览器的信息;navigator 数据可被浏览器使用者更改;

Q: 当循环体结束时,i指向对象的下一个属性?

//IE浏览器
if (navigator.userAgent.indexOf("MSIE") > 0)
{ }

 

//火狐浏览器
if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0)
{}

  • with 关键字:

 

引用《理解javascript中的with关键字》(

with语句的作用是将代码的作用域设置到一个特定的作用域中,基本语法如下:

with (expression) statement;

这几行代码都是访问location对象中的属性,如果使用with关键字的话,可以简化代码如下:

 

``

1 with (location){
2 
3 var qs = search.substring(1);
4 
5 var hostName = hostname;
6 
7 var url = href;
8 
9 }

``

 

                 2.根据浏览器版本给文本框附加对应事件

 

function getOs() {
    //判断浏览器类型 
       if (navigator.userAgent.indexOf("MSIE") > 0) {
        //此时假设文本框id为'txtSearch'
        //为文本框附加IE所支持的事件
        document.getElementById('txtSearch').attachEvent("onpropertychange", search);
        OsTyep = "MSIE";
    } else if (navigator.userAgent.indexOf("Firefox") > 0) {
        //此时假设文本框id为'txtSearch'
        //为文本框附加火狐所支持的事件
        document.getElementById('txtSearch').addEventListener("input", search, false);
        OsTyep = "Firefox";
    }
}

在这段代码中,使用了with语句关联了location对象,这就以为着在with代码块内部,每个变量首先被认为是一个局部变量,如果局部变量与location对象的某个属性同名,则这个局部变量会指向location对象属性。

在《JavaScript入门经典》中,提及的with作用为:

“with 关键字指定一个对象,后面跟着括在大括号中的一大块语句。对于块语句中的每一条语句,没有指定对象的属性都被假定为该对象的属性。举例来说,假定有一个名为lastname的字符串,可以用 with 来执行字符串操作,而不必每次都指定该字符串的名称:

``

1 with (lastname){
2 
3  window.alert("length of last name: " + length);
4 
5  capname = toUpperCase();
6 
7 }

``

 

在本例中,虽然只用 with 关键字指定了一次,但 length 属性和 toUpperCase 方法都会引用lastname字符串”

                3.根据浏览器版本给文本框清除对应事件

 

function ClearOS() {
    if (navigator.userAgent.indexOf("MSIE") > 0) {

  • 一个事件调用多个函数的方法:

        //此时假设文本框id为'txtSearch'
        //为文本框清除IE所支持的事件
        document.getElementById('txtSearch').detachEvent("onpropertychange", search);
        OsTyep = "MSIE";
    } else if (navigator.userAgent.indexOf("Firefox") > 0) {

  1. 定义一个函数来调用多个函数,事件触发时调用“调用多个函数的函数”;
  2. 在IE6、7中用"attachEvent()"方法;在高级版本中用"addEventListener()"方法

        //此时假设文本框id为'txtSearch'
        //为文本框清除火狐所支持的事件
        document.getElementById('txtSearch').removeEventListener("input", search, false);
        OsTyep = "Firefox";
    }
}

 

 

 

       2.客户端的设计

  • Date() 方法相关:

           (1)实现流程的分析

JavaScript 中 Date 对象的四种创建格式示例:

birthday = new Day(); //不指定,其值为 new 对象时的时间

birthday = new Day("October 9,2016 23:03:00"); //通过字符串参数指定年月日时分秒

birthday = new Day(10, 9, 2016, 23, 3, 0);//通过数字参数指定年月日时分秒

birthday = new Day(10, 9, 2016);//通过数字参数指定年月日

getYear() 返回值为两位数的年份(如“16”),getFullYear() 返回值为四位数的年份(如“2016”),使用getFullYear() 可避免"2000年"问题。

                   了解完以上知识点之后,我们来看一下实现搜索提示的一个整体流程:

 

                   (1) 首先客户端通过文本框输入事件捕获输入的关键字

  • <img>标签也有 onLoad 事件

                   (2)  在通过我们之前创建好的AJAX对象提交给服务器

 

                   (3) 服务器接受提交的关键字,进行查询将结果集返回给客户端进行显示

  • event.which存储的是按键的ASCII码值;event.keyCode存储的是字符代码

                    流程如下:图片 2

 

           (2)样式的编写

  • 在form标签中,用onSubmit = "return validate()" 以达到条件前调用validate()方法进行验证的效果。当validate()返回值为true时,提交表单;当validate()返回值为false时,不提交表单。

                   那么接下来我们来看一下样式,其中包括当文本框鼠标移动上去给边框加颜色与搜索结果行选中的样式等,这里就不细说了,列举出来供参考:

 

 <style type="text/css" media="screen">
    body
    {
        font:11px arial;
    }
    /*设置提示提示列表上的样式表*/
    .search_link
    {         
         background-color:#FFFFFF;
         cursor: pointer;
         line-height:24px;
         text-indent:6px;
    }
    /*设置当鼠标移动到提示列表上的样式表*/
    .search_link_over
    {     
         background-color:#E8F2FE;
         cursor: pointer;
         line-height:24px;
         text-indent:6px;

  • 典型的AJAX运行机制:

    }
    
    /*设置显示搜索提示div的样式表*/
    #search_div
    {
        position:absolute;
        background-color:#FFFFFF;
        text-align:left;
        border:1px solid #000000;
        border-top:0px;
        display:none;
        min-width:553px;
        width:553px;
    }
    
    /*文本框样式*/
    .mainInput  {
    line-height: 26px;
    height: 28px;
    width: 550px;
    font-size: 16px;
    font-family: "微软雅黑", "宋体", Candara;
    font-weight: normal;
    color: #666;
    margin: auto;
    border: none;
    text-indent: 8px;
}
    
    /*鼠标放上文本框样式*/
    .mainInputOver  {
    width:552px;
    height:30px;
    border-top-width: 1px;
    border-right-width: 1px;
    border-bottom-width: 1px;
    border-left-width: 1px;
    border-top-style: solid;
    border-right-style: solid;
    border-bottom-style: solid;
    border-left-style: solid;
    border-top-color: #b7b7b7;
    border-right-color: #d0d0d0;
    border-bottom-color: #d0d0d0;
    border-left-color: #d0d0d0;
}
/*鼠标离开文本框样式*/
.mainInputFocus  {
    width:552px;
    height:30px;
    border: 1px solid #41b5f2;
}

  1. 脚本会首先创建一个XMLHttpRequest对象,然后将它发送给Web服务器。同时,脚本可以继续发送请求。
  2. 服务器会发送包含内容的文件(或服务端应用程序的输出)作为响应。
  3. 当接到来自服务器端的响应后,相应的JavaScript 函数将被触发,以处理相关数据。
  4. 由于引入AJAX的主要目的是为了获取更好的用户交互性,所以脚本通常会使用DOM显示来自服务器的数据,从而无需再次刷新页面。

/*点击文本框样式*/
.myBorder
{
    width:552px;
    height:30px;
    border-top: 1px solid #CCCCCC;
    border-bottom: 1px solid #DDDDDD;
    border-left: 1px solid #DDDDDD;
    border-right: 1px solid #DDDDDD;    
}
    </style>

实际上,这一过程执行的非常快。即使服务器的处理速度很慢也可正常地执行。此外,由于请求是异步的,所以可以同时处理多个请求

 

 

           (3)aspx页面与ajax_search.js文件的编写

 

                   接下来就是一个比较重要的环节了,aspx页面与ajax_search.js文件中包含了整体包括显示与请求的方法例如:

 

                    1.页面的实现


<body onload="getOs()" onkeydown="if(event.keyCode==13)return false;">
    <form id="form1" runat="server">
    <div>
    <div class="myBorder" onmouseover="this.className='mainInputOver'" onmouseout="this.className='myBorder'"  onclick="this.className='mainInputFocus'">
    <input type="text" id="txtSearch"  name="txtSearch" onblur="HiddenDiv()" alt="SearchCriteria" autocomplete="off" class="mainInput"  />
    </div>
    <!--该DIV作为现实搜索提示的结果-->
    <div id="search_div" style="margin-top:0px" ></div>
    </div>
    </form>
</body>

规范:

                    2.根据浏览器创建AJAX对象

  • 内容是网页访问者在页面上阅读到的语句。通常以文本形式出现,并于HTML相结合,用于定义内容的类型——如标题、段落和链接等。
  • 展现是指页面中的外观和版面设计,这部分用 CSS来定义。
  • 行为是指与网页交互时发生的动作,由JavaScript来实现。

var searchReq = createAjaxObj();
var OsTyep = '';

 

function getOs() {
    //判断浏览器类型 
    if (navigator.userAgent.indexOf("MSIE") > 0) {
        document.getElementById('txtSearch').attachEvent("onpropertychange", search);
        OsTyep = "MSIE";
    } else if (navigator.userAgent.indexOf("Firefox") > 0) {
        document.getElementById('txtSearch').addEventListener("input", search, false);
        OsTyep = "Firefox";
    }
}

渐进式提高:

function ClearOS() {
    if (navigator.userAgent.indexOf("MSIE") > 0) {
        document.getElementById('txtSearch').detachEvent("onpropertychange", search);
        OsTyep = "MSIE";
    } else if (navigator.userAgent.indexOf("Firefox") > 0) {
        document.getElementById('txtSearch').removeEventListener("input", search, false);
        OsTyep = "Firefox";
    }
}

  • 应该在独立的CSS文件中添加规则,增强展现的形式。避免在代码中直接使用HTML形式的展现标记符,例如用<b>来表示黑体。
  • 通过外部的JavaScript文件添加脚本来增强行为。
  • 用功能检测技术确保只有支持相应功能的浏览器才会执行对应的JavaScript代码。功能检测如下: //检测getElementById函数的存在

    if (document.getElementById){

    //dostuff

    }

    也可以在函数开头处使用:

    function changeText(){

    if(!document.getElementById)return;

    //the rest of the function executes if the feature is supported

    }

     

function createAjaxObj() {
    var httpRequest = false;

 

    //判断是否包含XMLHttpRequest对象 PS:将来IE高也有可能继承次对象
    if (window.XMLHttpRequest) {
        //火狐 , Safari 等浏览器
        httpRequest = new XMLHttpRequest();
        if (httpRequest.overrideMimeType)
            httpRequest.overrideMimeType('text/xml');


        //ie: onpropertychange
        //ff: oninput
    } //判断是否支持Active控件对象
    else if (window.ActiveXObject) {
        //IE浏览器
        try {
            //IE5.0
            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                //IE5.5以上
                httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) { }
        }
    }
    //返回创建好的AJAX对象
    return httpRequest;
}

其它:

                    3.创建请求与返回数据的显示

Math对象不能new,因为它是静态对象。

//异步请求服务器获取搜索结果
function search() {
    if (searchReq.readyState == 4 || searchReq.readyState == 0) {
        //获得文本框中的值
        var valStr = escape(document.getElementById("txtSearch").value);
        //建立连接
        searchReq.open("GET", encodeURI('Search.ashx?search=' + valStr+'&fresh=' + Math.random()), true);
        //当请求状态改变时调用 handleSearch方法
        searchReq.onreadystatechange = handleSearch;
        searchReq.send(null);
    }
}

历元:以1970年1月1日子夜为起点计时的时间毫秒格式。

//返回结果处理方法
function handleSearch() {
    if (searchReq.readyState == 4) {
        //获得搜索提示结果的元素DIV
        var searchDIV = document.getElementById("search_div");
        searchDIV.innerHTML = "";

 

        //用^将返回的文本数据分割成数组
        var resultStrArr = searchReq.responseText.split("^");

  • 循环变量i的来源:

        //循环构建HTML代码
        for (var i = 0; i < resultStrArr.length - 1; i++) {
            var htmlStr = '<div onmouseover="selectOverDiv(this,'+i+');" ';
            htmlStr += 'onmouseout="selectOutDiv(this,'+i+');" ';
            htmlStr += 'onclick="setSearch(this.innerHTML);" ';
            htmlStr += '   >' + resultStrArr[i] + '</div>';

SO的答案:

style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; widows: 1">It comes ultimately from mathematics: the summation notation traditionally uses style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">  style="margin: 0px; padding: 0px; border: 0px currentColor; color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">i style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">  style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">for the first index, style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">  style="margin: 0px; padding: 0px; border: 0px currentColor; color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">j style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">for the second, and so on. Example (from style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">  style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; font-style: italic; widows: 1">):

It's also used that way for collections of things, like if you have a bunch of variables x1, x2, ... xn, then an arbitrary one will be known as xi.

  • style="color: #242729; line-height: 19.5px; font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; font-size: 15px; widows: 1">As for why it's that way, I imagine SLaks is correct and it's because I is the first letter in Index.”*

            searchDIV.innerHTML += htmlStr;
        }
        ShowDiv();
        x = -1;
    }
}

 

                    4.将数据选中数据显示文本框中

 

                       上边代码中在循环构建HTML代码时,我们给构建的DIV加入了三个事件分别是:

                        1 onmouseover="selectOverDiv(this,'+i+');" 

                           当鼠标放上去时调用selectOverDiv函数传递自己进去

                        2 onmouseout="selectOutDiv(this,'+i+');" 

                           当鼠标放上去时调用selectOutDiv函数传递自己进去

                        3 onclick="setSearch(this.innerHTML);" 

                           当鼠标点击DIV时调用setSearch函数传入本身DIV中内容

                     那么还是来看下这几个方法的实现吧:

function** selectOverDiv(div_value, i) {   
    div_value.className = "search_link_over";
    var my_div = document.getElementById("search_div").getElementsByTagName("div")
    var the_num = my_div.length;
    for (var k = 0; k < the_num; k++) {
        selectOut(my_div[k]);
        if (k == i) {
            selectOver(my_div[k])
        }
    }
    isCheckDiv = true;
    x =** i;
}

function selectOutDiv(div_value,i) {
    isCheckDiv = false;
    div_value.className = "search_link
";
    x **= i;
}

function setSearch(value) {
    //清空文本框的内容改变事件是因为我们给选中值复制时 该事件会触发      //所以先清空次事件     ClearOS();
    document.getElementById("txtSearch").value = value;
    //设置该属性为false 在调用HiddenDiv函数会隐藏提示结果DIV     isCheckDiv = false; 
    HiddenDiv();
    //在赋值完成后再次附加修改时间     getOs();
}

function ShowDiv() {
    var content = document.getElementById("txtSearch").value;
    var divConten = document.getElementById("search_div").innerHTML;
    if (content != '' && divConten != '') {
        document.getElementById("search_div").style.display = "block"     } else {
    isCheckDiv = false;
    HiddenDiv();
    }
    
}
function HiddenDiv() {
    if (isCheckDiv == false) {
        document.getElementById("search_div").style.display = "none";
        document.getElementById("search_div").innerHTML = ''**;
    }
}

                    5.增加键盘上下键选中提示数据与回车键选中数据到文本框

var index = -1; //表示当前选中的行索引
function keyDown() {
    var value = event.keyCode
    //向上38,向下40,回车13
    var the_key = event.keyCode 
    //判断提示DIV是否是现实状态
    if (document.getElementById("search_div").style.display != "none") {
        //获取里面所用行
        var my_div = document.getElementById("search_div").getElementsByTagName("div")
        var the_num = my_div.length;
        switch (the_key) {
            case 40: //向下
                //判断index是否已经到最下面
                if (index == the_num - 1) {
                    index = 0;
                } else {
                    index++;
                }
                //清楚所有选中
                for (var i = 0; i < the_num; i++) {
                    selectOut(my_div[i]);
                }
                //根据index选中对应索引行
                for (i = 0; i < the_num; i++) {
                    if (i == index) {
                        selectOver(my_div[i])
                    }
                }
                break;
            case 38: //向上
                //判断index是否已经到最上面
                if (index == 0) {
                    index = the_num-1;
                } else { index--; }
                //清楚所有选中
                for (var i = 0; i < the_num; i++) {
                    selectOut(my_div[i]);
                }
                //根据index选中对应索引行
                for (i = 0; i < the_num; i++) {
                    if (i == index) {
                        selectOver(my_div[i])
                    }
                }
                break;
            case 13: //回车
                //将选中的内容放入文本框中
                if (my_div[index].innerHTML != null) {
                    setSearch(my_div[index].innerHTML);
                }
                break;
        }

    }

}
document.onkeydown = keyDown;

 

       3.服务器端的设计

           (1)实现一个虚拟的数据源

                 前台传来关键字,后台必须要有数据匹配,为了简单我就不建立数据库了 我就模拟一个数据源好啦!

              步骤:右键项目 --> 添加新项--> 选择一般处理程序命名为:Search.ashx 编写代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.CodeDom;
using System.Globalization;
using System.ComponentModel;
using System.Collections;

public class Search : IHttpHandler {

    //定义一个数据源
    public List<string> DataSource
    {
        get
        {
            List<string> list = new List<string>()
            {
                "我爱C#",
                "我爱.NET",
                "我爱微软技术"
            };
            return list;
        }
    }
    
    public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";
    }
 
    public bool IsReusable {
        get {
            return false;
        }
    }

}

 

           (2)搜索数据源返回固定格式数据以字符串形式

             紧接着我们要在ProcessReques方法中加入我们搜索数据源构建返回相应数据集,拼接结果字符串返回给客户端。代码如下:

  public void ProcessRequest (HttpContext context) {
        context.Response.ContentType = "text/plain";

        //接受客户端关键字并且解码
      string searchStr = HttpUtility.UrlDecode(context.Request.QueryString["search"].ToString(), System.Text.Encoding.UTF8);

        //搜索数据源集合中匹配的关键字
        var result = (from string n in DataSource
                          where n.Contains(searchStr)
                          select n).ToList<string>();
        
        StringBuilder sb = new StringBuilder(100);
        //将匹配关键字用符号^ 分割拼接成字符串
        foreach (string str in result as List<string>)
        {
            sb.AppendFormat("{0}^", str);
        }
        //返回客户端
        context.Response.Write(sb.ToString());
    }

    &


版权声明:本文由大奖888-www.88pt88.com-大奖888官网登录发布于前端开发,转载请注明出处:叁个多月没更新了-,以一九七零年一月1日子夜为