分类目录归档:JavaScript

同时大量ajax请求同一个url的处理

情景比如: 一个load数据的按钮,因为网络比较慢或其他原因,用户一直狂点这个按钮,就会发出N多ajax请求出去。因为网络延迟,多个ajax返回的回调处理函数可能会交叉影响,造成意料外的结果。

其中一种方式是,对按钮的点击做限制,某个时间段内不允许重复点击,但是治标不治本,网络差的时候,也会发生意外状况。

这里想到的是一个目前还相对简单的处理方式,使用jQuery的jQuery ajaxPrefilter方法做预处理。普通ajax请求同理也是可以处理的。代码如下:

/* ajax请求预前过滤器 */
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    var args = originalOptions;
    var _url = args.url || location.href;
    var data = args.data || {};
    //参数名+url做唯一判定
    var xhrId = [_url];
    for(var key in data) {
        xhrId.push(key);
    };
    xhrId = xhrId.join('');

    var cacheXhr = window[xhrId]; 
    if(cacheXhr && cacheXhr.readyState != 4) {
        cacheXhr.abort();
    };
    window[xhrId] = jqXHR;
})

 

Chrome下input输入框内容无法选中的解决方法

来源于: http://www.cnblogs.com/danye/archive/2012/08/07/2626572.html

首先,我把选中内容放在了onfocus事件中处理,然后FF成功失败交替出现,而chrome则总是失败。采用上述链接中的方法后,解决问题。

解决方法如下;

$("input").click(function(e){
  $(this).select();
});
//阻止chrome自己的mouseup事件即可。
$("input").mouseup(function(e){
    if(window.navigator.userAgent.indexOf("Chrome")!=-1){
        var event = e||window.event; 
        event.preventDefault(); 
    }
});

 

CORS跨域试用

CORS,全称Cross-Origin Resource Sharing,中文翻译为 跨源资源共享,目前支持情况: IE8+, FF3.5+, Safari 4+, Opera 12+(? opera不是很明确,但是至少我的opera V12是测试通过的)。

测试使用nginx配置两个虚拟主机(修改hosts,弄两个本地域名),node.js为后端服务器(nginx代理一个虚拟主机转发给nodejs)。

http://a.com/cors-test.html内容如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>测试CORS跨域</title>
</head>
<body>
    <h3>跨域显示</h3>
    <p id="text"></p>

    <script type="text/javascript">
        function sendCORSRequest(method, url) {
            var xhr = new XMLHttpRequest();
            if('withCredentials' in xhr) {
                xhr.open(method, url, true);
            } else if(typeof XDomainRequest != 'undefined') {
                xhr = new XDomainRequest();
                xhr.open(method, url);
            } else {
                xhr = null;
            };
            return xhr;
        };
        window.onload = function() {
            var request = sendCORSRequest('POST', 'http://cors.b.com/username/');
            var $show = document.getElementById('text');
            if(request) {
                request.onload = function(data) {
                    data = request.responseText;
                    $show.innerHTML = data;
                };
                request.onerror = function() {
                    console.info('cors is error.....')
                };
                request.send();
            } else {
                $show.innerHTML = '不支持CORS跨域....';
            };
        };
    </script>
</body>
</html>

nginx转发http://cors.b.com/username/请求给服务器端nodejs的写法也很简单:

var http = require('http');

http.createServer(function(request, response) {
    response.writeHead(200, {
        'Content-Type': 'text/plain',
        'Access-Control-Allow-Origin': 'http://cors.a.com'
    });

    response.write('myname is tofishes');

    response.end();
}).listen(8080);

以上测试通过。

补充(http://www.weste.net/2011/4-27/75028.html):

Firefox, Safari, 和Chrome的XMLHttpRequest对象与IE的XDomainRequest对象有着相似的充分的接口,这些模式运行的很好。常见的接口属性/方法:

  • abort()——用来终止已在进程中请求。
  • Onerror()——替代onreadystatechange方法来探测错误。
  • Onload()——替代onreadystatechange方法来探测成功。
  • responseText——用来取得响应地文本。
  • send()——用来发送请求。

Preflighted请求

除了GET或POST,通过一种称之为preflighted请求的服务器透明验证机制,CORS允许使用自定义的头部和方法,以及不同主体内容类型。当你尝试使用高级选项中的一个来试着建立一个请求时,这时就建立了一个preflighted请求。该请求使用可选的方法,并发送如下头部:

  • Origin——与简单请求相同。
  • Access-Control-Request-Method——请求将要使用的方法。
  • Access-Control-Request-Headers——(可选)一个逗号分开的正被使用的自定义头部列表。

例子假定一个头部自定义为NCZ的POST请求:

Origin: http://www.nczonline.net

Access-Control-Request-Method: POST

Access-Control-Request-Headers: NCZ

在请求期间,服务器能决定是否允许这类请求。服务器通过在响应中发送以下头部来与浏览器通信。

  • Access-Control-Allow-Origin——与简单请求相同。
  • Access-Control-Allow-Methods——用逗号分开的可接受的方法列表。
  • Access-Control-Allow-Headers——用逗号分开的服务器可接受的头部列表。
  • Access-Control-Max-Age——preflighted 请求应该被缓存的时间。

如:

Access-Control-Allow-Origin: http://www.nczonline.net

Access-Control-Allow-Methods: POST, GET

Access-Control-Allow-Headers: NCZ

Access-Control-Max-Age: 1728000

preflighted 请求一旦作出,结果将按响应中规定的时间缓存下来;第一次做出这样的请求,你将引发一次额外的HTTP请求。

Firefox 3.5+, Safari 4+和Chrome都支持preflighted 请求,IE8则不支持。

Credentialed请求

默认状态下,跨域请求不提供证书(cookie、HTTP身份验证、客户端SSL证书)。你可以规定一个请求应该通过设置withCredentials属性为true来发送证书。如果服务器允许credentialed请求,那么它将用下面的头部作出响应:

如果一个credentialed请求被发送,这个头部不会作为响应地一部分被发送。浏览器不会将响应传递给JavaScript(responseText是一个空字符串,状态为 0,onerror()被调用)。注意,服务器也能发送这个HTTP头部作为preflight响应的一部分,以此来表明该源允许发送 credentialed请求。

Access-Control-Allow-Credentials: true

IE8不支持withCredentials属性,Firefox 3.5+, Safari 4+和Chrome都支持它。

 

官方博客说明: ie8/9的跨域限制

javascript跨域之同源策略

来源于:http://www.woiweb.net/same-origin-policy.html

所谓同源是指域名,协议,端口均相同。

同源的几种情况:
1.不同域名属于跨域,如:www.a.com和www.b.com,另外www.a.com 和www.a.com.cn 也属于不同域名。
2.主域名和子域名(二级域名、三级域名等)跨域,如:www.a.com 和 sub.a.com
属于跨域,sub.a.com 和 sub1.a.com 之间也是跨域。
3.不同协议属于跨域,如:http://www.a.com 和 https://www.a.com。
4.不同端口,如: www.a.com:80和 www.a.com:81 。
5.IP和域名属于跨域,如:123.125.106.16 和 www.weibo.com。

精确获取页面元素的位置

来源于: http://www.cnblogs.com/rubylouvre/archive/2009/09/08/1562444.html

基本方法是用目前浏览器都支持的getBoundingClientRect方法(IE率先提供的方法),然后对html或body的可能误差做修正,从jQuery中提取的函数:

var getCoords = function(el){
  var box = el.getBoundingClientRect(),
  doc = el.ownerDocument,
  body = doc.body,
  html = doc.documentElement,
  clientTop = html.clientTop || body.clientTop || 0,
  clientLeft = html.clientLeft || body.clientLeft || 0,
  top  = box.top  + (self.pageYOffset || html.scrollTop  ||  body.scrollTop ) - clientTop,
  left = box.left + (self.pageXOffset || html.scrollLeft ||  body.scrollLeft) - clientLeft
  return { 'top': top, 'left': left };
};

javascript动画剖析

最近要多接触点原生js的东东,不能老是jQuery了。jQuery有个很棒的地方,就是animate方法,实现动画。故从http://stylechen.com/javascript-animate.html拷贝来一篇介绍,学习学习。

最近将去年写过的easyAnim进行了重构和优化以整合到我的javascript框架中,回过头来发现以前写的代码确实还有很多可以改进的地方,这也证明自己还是有点进步的。趁有点时间,将javascript动画运行的机制和实现的思路整理了一下,算是做个小总结,也希望对有兴趣的人有点帮助。篇幅稍长,看之前请自备瓜子啤酒。

当然这里说的javascript动画是指利用javascript来计算DOM元素的CSS属性值来实现的动画,HTML5和CSS3的发展让WEB中的动画有了更多的可能,但这些看起来比较高级的东西还需要浏览器给力点才行。

Continue reading javascript动画剖析

JavaScript attribute和property的区别

前几天还在想了解JavaScript attribute和property的区别,今天就碰到了一篇不错的内容。
补充个特别例子,就是 input的value,用attribute和property设置和获取的完全是不一样的值。

以下内容源自:http://stylechen.com/attribute-property.html

DOM元素的attribute和property很容易混倄在一起,分不清楚,两者是不同的东西,但是两者又联系紧密。很多新手朋友,也包括以前的我,经常会搞不清楚。

Continue reading JavaScript attribute和property的区别

更精准快速的javascript图片预加载技术

可能有部分人跟偶一样,只知道用Image.onload来预加载图片,但是多了解之后,才知道这个方法有很多缺点。那么怎么更好的预加载图片呢,请看转自:http://www.planeart.cn/?p=1121&cpage=1的内容。

这是大部分人使用预加载获取图片大小的例子:

var imgLoad = function (url, callback) {
	var img = new Image();

	img.src = url;
	if (img.complete) {
		callback(img.width, img.height);
	} else {
		img.onload = function () {
			callback(img.width, img.height);
			img.onload = null;
		};
	};

};

Continue reading 更精准快速的javascript图片预加载技术

getElementsByTagName的返回值

getElementsByTagName返回值标准定义应该是NodeList对象,不是Array。拥有length属性。

在IE一些版本,不可以对返回值做 for in循环,length属性会被循环出来,所以必须 for i++经典遍历。

更多情况,进入传送门:

http://topic.csdn.net/u/20100706/14/a81cdeed-7112-4c3e-8408-540c4951879c.html