标签:javascript

浏览模式: 标准 | 列表 | 图文
Javascript堵塞问题的解决[转]

Javascript堵塞问题的解决[转]

本文来自:Thinking in LAMP - 老王的技术手册,网址是在baidu上面的,文章URL是:http://hi.baidu.com/thinkinginlamp/blog/item/1ebc2e730600891b8601b049.html

原文内容如下:(为了方便,我将图片COPY过来了,而并非是引用,不好意思老王)

所谓“Javascript堵塞问题”,指的是浏览器在下载javascript文件的时候,会堵塞其他下载进程,并且多个javascript文件之 间,只能一个一个下载,不能并行下载。浏览器之所以要这么干,一来是因为javascript里可能会有一些涉及页面渲染的操作,比如 document.write,所以要先把他们加载完,以免影响用户体验,二来是如果并发下载javascript文件,代码执行的先后顺序会错乱,从而 引起逻辑错误。为了规避上述弊端,YSlow建议如果有多个javascript文件,并且这些文件里没有类似document.write等页面渲染的 操作,那么应该尽可能把他们合并成一个文件,并放到页面的尾部。不过很多时候,合并javascript文件是个浩大的工程,不仅破坏了模块化结构,而且 还可能会给代码维护带来不必要的麻烦,今天说说另一个方法,以期避免对现有代码的大规模修改。

先做两个javascript文件,他们是a.php,b.php,之所以用php文件是因为我只会这个,内容如下:

<?php sleep(1); ?>

可以看到a.php和b.php的内容是一样的,其中之所以sleep一秒钟,是为了让演示的效果更明显。

现在让我们来做一个页面(x.htm),看看javascript堵塞问题是如何产生的:

<html>
<head>
<title>DEMO</title>
<script type="text/javascript" src="a.php"></script>
<script type="text/javascript" src="b.php"></script>
</head>
<body>
<img src="http://www.google.com/intl/en_ALL/images/logo.gif">
</body>
</html>

浏览这个页面的时候,通过Pagetest软件,我们可以看到类似下面的结果:

db055da4f27f68d6a5a5e0071e838a65

我们可以看到,logo.gif图片的下载进程被堵塞了,并且a.php和b.php是分别下载的。

下面让我们再来做一个页面(y.htm),看看是怎么解决这个问题的:
<html>
<head>
<title>DEMO</title>
<script>
var load = function(file) {
var scriptElement = document.createElement("script");
scriptElement.src = file;
document.getElementsByTagName("head")[0].appendChild(scriptElement);
}
load('a.php');
load('b.php');
</script>
</head>
<body>
<img src="http://www.google.com/intl/en_ALL/images/logo.gif">
</body>
</html>
浏览这个页面的时候,通过Pagetest软件,我们可以看到类似下面的结果:
5ae2ea7c9e695712a50cf94866a057b0
结论显而易见,logo.gif图片的下载进程并没有被堵塞,并且a.php和b.php是并行下载的。

参考资料:http://stevesouders.com/docs/web20expo-20080425.ppt


膘叔:虽然从我个人而言,我会考虑将js换到其他的域名下面,以防止堵塞(所谓的YAHOO设计网页14条军规中的),然后通过一个程序minify来进行引用。关于minify我会单独介绍。(其实也是COPY别人的文章而来,最近是很懒了。一是要考试,二是单位太忙,只能做到天天更新,但无法原创了)
利用PHP裁剪图片

利用PHP裁剪图片

其实,用PHP裁剪图片的原理是很简单的,无非就是用javascript画出一个方块,计算一下四个角的顶点,然后从原图中按照这四个点的坐标把当中的图切出来。

网上有现成的例子:http://www.coderhome.net/zifa/?p=351,不过里面的JS库用的是mootools的,如果要看,请直接到该网上去看,以后,等有空了,用jQuery的模拟一下,呵呵。
jQuery的插件还是很好开发的

JavaScript---Web流程定义工具

JavaScript---Web流程定义工具

用javascript+vml来做工作流,确实是第一次看到,所以我在看到有这个新闻的时候,就觉得特别的吃惊。当年的TRS就是因为有一个activex版的工作流控件的CMS,导致他的价格非常的高,今天能够看到有javascript版的,惊讶是难免的。。。

只是并非所有的机器都支持VML,所以它的适用范围还是有限的,不过,话又说回来,activex也只支持IE,但仍然有那么多人在用。看来,只要是好东西,即使你不跨平台,照样有人用的起劲。

闲话不说了,附上原文网址和他的说明,原文:http://www.cssrain.cn/article.asp?id=1192

开发语言;javascript,html,vml,json,css
功能:
1.环节可用鼠标拖拽
鼠标选中环节后不释放,拖拽鼠标,环节将随鼠标移动,释放鼠标后,环节不再移动。
2.路径的两个端点可以通过鼠标拖拽,改变路径指向的环节
鼠标选中路径的端点后不释放,拖拽鼠标,路径被选中的端点将鼠标移动,在选中的环节释放鼠标后,路径被选中的端点将指向该选中的环节。
3.ctrl+a,全选。
4.按住ctrl,鼠标选中对象,可以多选。
5.delete,删除选中对象。
6.使用鼠标多选
鼠标点击空白处不释放,拖拽鼠标,会出现一个长方形虚框,虚框的范围随着鼠标移动而变化,虚框范围内的对象将被选中。
7.动态添加环节和路径的属性

55aaefff5b3293ce4a92b425e8c1fcc6

由于对这个东西很吃惊,所以,把图片和附件保存到了本地。需要的朋友可以点上面那个网址或者点本文的附件进行下载

(不好意思,刚发现附件有密码,我也不知道是什么密码,有破解软件的朋友只能辛苦一下了,或者去上面的cssrain.cn问站长去吧,我这里仅仅是作个备份)

深入理解Javascript闭包(closure)

深入理解Javascript闭包(closure)

經過指點,獲悉原文為:http://www.felixwoo.com/archives/247

我轉貼的文章來源:http://www.knowsky.com/442121.html

PS:虽然我是从上面拷来的,但我并不建议打开这个网页看,因为,上面全是广告。个人猜测,代码也是他拷来的,但没有亲自验证,我也没法打包票。不过东西有点用,所以我也就COPY过来了。

内容如下:

最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业。对于初学者来说别说理解闭包了,就连文字叙述都很难看懂。撰写此文的目的就是用最通俗的文字揭开Javascript闭包的真实面目。

一、什么是闭包?
“官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码:

function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();

这段代码有两个特点:
1、函数b嵌套在函数a内部;
2、函数a返回函数b。
这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:

当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

我猜想你一定还是不理解闭包,因为你不知道闭包有什么作用,下面让我们继续探索。

二、闭包有什么作用?
简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。这是对闭包作用的非常直白的描述,不专业也不严谨,但大概意思就是这样,理解闭包需要循序渐进的过程。
在上面的例子中,由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。

那 么我们来想象另一种情况,如果a返回的不是函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引 用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。(关于Javascript的垃圾回收机制将在后面详细介绍)

三、闭包内的微观世界
如 果要更加深入的了解闭包以及函数a和嵌套函数b的关系,我们需要引入另外几个概念:函数的执行环境(excution context)、活动对象(call object)、作用域(scope)、作用域链(scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。

1、当定义函数a的时候,js解释器会将函数a的作用域链(scope chain)设置为定义a时a所在的“环境”,如果a是一个全局函数,则scope chain中只有window对象。
2、当函数a执行的时候,a会进入相应的执行环境(excution context)。
3、在创建执行环境的过程中,首先会为a添加一个scope属性,即a的作用域,其值就为第1步中的scope chain。即a.scope=a的作用域链。
4、 然后执行环境会创建一个活动对象(call object)。活动对象也是一个拥有属性的对象,但它不具有原型而且不能通过JavaScript代码直接访问。创建完活动对象后,把活动对象添加到a 的作用域链的最顶端。此时a的作用域链包含了两个对象:a的活动对象和window对象。
5、下一步是在活动对象上添加一个arguments属性,它保存着调用函数a时所传递的参数。
6、最后把所有函数a的形参和内部的函数b的引用也添加到a的活动对象上。在这一步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为b所被定义的环境,即a的作用域。

到此,整个函数a从定义到执行的步骤就完成了。此时a返回函数b的引用给c,又函数b的作用域链包含了对函数a的活动对象的引用,也就是说b可以访问到a中定义的所有变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被GC回收。

当函数b执行的时候亦会像以上步骤一样。因此,执行时b的作用域链包含了3个对象:b的活动对象、a的活动对象和window对象,如下图所示:(这里看了一下,确实没有图,看来果然是拷贝过来的,稍稍验证了我的说法,呵呵。。。。唉。可惜我确实不知道原文在哪里,不过,我是从他的网站拷来的,还是给他一个链接,毕竟我的资料来源是该网站)

df7707316cbb8ad23bba49a527e949e7

(附上原文圖片)

如图所示,当在函数b中访问一个变量的时候,搜索顺序是先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依 次查找,直到找到为止。如果整个作用域链上都无法找到,则返回undefined。如果函数b存在prototype原型对象,则在查找完自身的活动对象 后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。

四、闭包的应用场景
1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
以上两点是闭包最基本的应用场景,很多经典案例都源于此。

五、Javascript的垃圾回收机制
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。

jQuery Plugins -- JQzoom

jQuery Plugins -- JQzoom

demo地址:http://www.51toria.cn/demo/JQplus/jqzoom/

使用的JS:

//**************************************************************
// jQZoom allows you to realize a small magnifier window,close
// to the image or images on your web page easily.
//
// jqZoom version 1.0
// Author Doc. Ing. Renzi Marco(www.mind-projects.it)
// Released on Dec 05 2007
// i'm searching for a job,pick me up!!!
// mail: renzi.mrc@gmail.com
//**************************************************************

(function($){

$.fn.jqueryzoom = function(options){

var settings = {
xzoom: 200, //zoomed width default width
yzoom: 200, //zoomed div default width
offset: 10, //zoomed div default offset
position: "right" //zoomed div default position,offset position is to the right of the image
};

if(options) {
$.extend(settings, options);
}

$(this).hover(function(){


var imageLeft = $(this).get(0).offsetLeft;
var imageRight = $(this).get(0).offsetRight;
var imageTop = $(this).get(0).offsetTop;
var imageWidth = $(this).get(0).offsetWidth;
var imageHeight = $(this).get(0).offsetHeight;

var bigimage = $(this).attr("alt");

if($("div.zoomdiv").get().length == 0){

$(this).after("<div class='zoomdiv'><img class='bigimg' src='"+bigimage+"'/></div>");

}

if(settings.position == "right"){

leftpos = imageLeft + imageWidth + settings.offset;

}else{

leftpos = imageLeft - settings.xzoom - settings.offset;

}

$("div.zoomdiv").css({ top: imageTop,left: leftpos });

$("div.zoomdiv").width(settings.xzoom);

$("div.zoomdiv").height(settings.yzoom);

$("div.zoomdiv").show();


$(document.body).mousemove(function(e){

var bigwidth = $(".bigimg").get(0).offsetWidth;

var bigheight = $(".bigimg").get(0).offsetHeight;

var scaley ='x';

var scalex= 'y';


if(isNaN(scalex)|isNaN(scaley)){

var scalex = Math.round(bigwidth/imageWidth) ;

var scaley = Math.round(bigheight/imageHeight);

}

mouse = new MouseEvent(e);



scrolly = mouse.y - imageTop - ($("div.zoomdiv").height()*1/scaley)/2 ;

$("div.zoomdiv").get(0).scrollTop = scrolly * scaley ;

scrollx = mouse.x - imageLeft - ($("div.zoomdiv").width()*1/scalex)/2 ;

$("div.zoomdiv").get(0).scrollLeft = (scrollx) * scalex ;


});
},function(){
$("div.zoomdiv").hide();
$(document.body).unbind("mousemove");
$(".lenszoom").remove();
$("div.zoomdiv").remove();
});

}

})(jQuery);

function MouseEvent(e) {
this.x = e.pageX
this.y = e.pageY
}

页面调用方法:

jQuery.noConflict();
jQuery(document).ready(function(){
$("img.jqzoom").jqueryzoom();
});
祝贺:微软也开源 将采用jQuery JavaScript库

祝贺:微软也开源 将采用jQuery JavaScript库

微软和诺基亚正式宣布支持开源的 jQuery JavaScript库,另外,微软还称他们将把jQuery作为Visual Studio工具集的一部分。他将提供包括jQuery的智能提示,代码片段,示例,文档编制等内容在内的功能。微软和诺基亚将长期成为jQuery的用户成员,其他成员还有Google, Intel, IBM, Intuit, 路透社等。

测试JS的速度

在mootools的官方网站有一个网页专门用来测试几个框架的速度,大概是:mootools,jquery,prototype,dojo,yui,测试下来jquery的平均速度应该算是最快的。

那个评测下来IE下JS运行速度慢果然是很明显的。同样的测试在IE下面比FF下面,速度慢了一倍左右啊。

不多了。自己测试一下看结果吧。。
http://mootools.net/slickspeed/

YUI 3.0 Preview Release 1

YUI 3.0 Preview Release 1

几天不见,YUI居然release了,虽然是preview版本。
官方这么说:


The YUI development team has issued YUI 3.0 Preview Release 1, an early look at the next generation of the Yahoo! User Interface Library (YUI). This developer preview shows you where the library is headed as we pursue goals of size, performance, consistency, power, security, and openness.

You can read the introduction to the new release on YUIBlog and get a sense of the new syntactical style in this blog post, which reviews Dav Glass's Draggable Portable example — one of more than 60 examples that accompany the preview's extensive documentation.

YUI 3.0 PR 1 is an early preview — not suitable for production deployment. The development team is looking forward to your feedback in the YUI 3.x community forum as we refine the API toward a 2009 release.

Work continues on YUI's main 2.x codeline, too, and YUI 2.x is still the foundation for current projects. Check out the library's Roadmap for a up-to-date picture of what we're planning for upcoming releases.


有点期待。

javascript---浅析注册事件

javascript---浅析注册事件

在这个浮躁的世界里,说实话,很难看到一两篇好的文章,我写的一般都比较垃圾,但我会尽量发现精品。在闲逛的时候发现这篇文章确实不错,虽然讲的比较简单一点。

文章是从cssrain.cn上COPY而来,原文网址为:http://item.feedsky.com/~feedsky/cssrain/~6110346/103912558/4218245/1/item.html

内容如下:

首先是最常规的方法:

<p id="para" title="cssrain demo!" onclick="test()" >test</p>
<script>
function test(){
alert("test");
}
</script>

当某一天,我们知道JavaScript要跟HTML结构实现分离后,就会改了一种写法:

<p id="para" title="cssrain demo!">test</p>
<script>
function test(){
alert("test");
}
window.onload = function(){
document.getElementById("para").onclick = test;
}
</script>

当我们工作越来越久后,有时候我们需要对某个元素绑定多个相同的事件类型:

<p id="para" title="cssrain demo!">test</p>
<script>
function test(){
alert("test");
}

function pig(){
alert("pig");
}

window.onload = function(){
document.getElementById("para").attachEvent("onclick",test);
document.getElementById("para").attachEvent("onclick",pig);
}
</script>

在一段时间内,你并没发现这段代码有任何错误。
某一天,一个名叫firefox的浏览器 闯入你的视野,当我们把这段代码放到firefox中执行后,
发现并不能正常运行。 问题就这样,越来越多,然而作为一名JS程序员,这些都是必须面对的。

为了解决这段代码的平台兼容性问题,我翻翻手册,知道了firefox跟ie的区别:
firefox中注册事件使用:addEventListener方法,同时为了兼容ie,我们必须用到if ... else...

<p id="para" title="cssrain demo!">test</p>
<script>
function test(){
alert("test");
}

function pig(){
alert("pig");
}

window.onload = function(){
var element = document.getElementById("para");
if(element.addEventListener){ // firefox , w3c
element.addEventListener("click",test,false);
element.addEventListener("click",pig,false);
} else { // ie
element.attachEvent("onclick",test);
element.attachEvent("onclick",pig);
}
}
</script>

此时,代码就可以在多个平台上工作了。

但随着水平的进步,你不满足每次都去判断,你想把这个判断封装起来,以后可以直接调用:

<p id="para" title="cssrain demo!">test</p>
<script>
function test(){
alert("test");
}

function pig(){
alert("pig");
}

function addListener(element,e,fn){
if(element.addEventListener){
element.addEventListener(e,fn,false);
} else {
element.attachEvent("on" + e,fn);
}
}

window.onload = function(){
var element = document.getElementById("para");
addListener(element,"click",test);
addListener(element,"click",pig);
}
</script>
<p id="para" title="cssrain demo!">test</p>
<script>
function test(){
alert("test");
}

function pig(){
alert("pig");
}

function addListener(element,e,fn){
if(element.addEventListener){
element.addEventListener(e,fn,false);
} else {
element.attachEvent("on" + e,fn);
}
}

window.onload = function(){
var element = document.getElementById("para");
addListener(element,"click",test);
addListener(element,"click",pig);
}
</script>

至此,作为一个程序员的工作就完了。
中间我们从一个最传统,最基本的写法 , 然后实现Js和HTML的分离,然后又实现对同一个元素注册多个事件,期间,我们发现注册事件的兼容性问题。最后我们对注册事件的方法进行封装,方便以后使用。

———END——

浏览器这东西还是非常害人的。啥时候才能有统一的标准 ???

用 PHP 生成 JavaScript 字符串

用 PHP 生成 JavaScript 字符串

闲来无事,到coolcode.cn上去闲逛。发现了一些比较旧的文章,以前也都看过,但,那时候没有开博,所以也就没有记录。如今博客也开了,coolcode.cn估计要成为我搜刮的对象了。

coolcode.cn的作者是andot,PHPRPC的作者,我06年年中(应该没记错)就使用了这个软件,同年放弃使用xajax,当然,现在我更多的使用jquery来操作ajax,但PHPRPC的功能不完全局限于ajax,我这里就不详谈了。先谈这篇文章。。。

无耻的分隔线:


原来,在从 PHP 中直接传递字符串给 JavaScript 时,直接用了 addcslashes,如果传递的是带有 utf-8 编码汉字的,就用 "\0..\037\042\134",如果纯 ascii 范围内的字符串,就用 "\0..\037\042\134\177..\377"。但是今天在写加密程序时发现,发现程序有时行,有时不行。后来发现原来是 \v \a 搞的。addcslashes 会把 \007..\015(八进制) 转义成 \a\b\t\n\v\f\r,而其中 \a 这个 IE 和 Firefox 都不认识,\v 这个 Firefox 认识,IE 不认识。所以我写了下面这个函数,用它可以就可以转化成 JavaScript/JScript 所认识的字符串了(其中 $flag 表示是否转义 ascii 码大于 127 的字符)。感谢五帝同学的帮助!

/* @author andot & wudi */
function addjsslashes($str, $flag = true)
{
if ($flag) {
$str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134\177..\377");
}
else {
$str = addcslashes($str, "\0..\006\010..\012\014..\037\042\047\134");
}
return str_replace(
array(chr(7), chr(11)),
array('\007', '\013'),
$str
);
}