简单的js调试工具函数

Posted by 叶梓 on 八月 31st, 2010

最近做项目,有时候需要打印出程序运行到那里,于是就写了个debug的小工具,留以自用,也正在尝试着用这种方式写程序,觉得比起以前,我的js有了点进步。可喜可贺

/*
debug 调试js by jun @2010.8.26
使用,放到页面最下面
*/
var debug = (function(){
	var count=0,
		debugcont,
		clear,
		log=function(e){
			var buginfotag = document.createElement('p');
                        buginfotag.style.cssText = "margin:0;padding:0";
			var buginfo = document.createTextNode(e+'-----'+count);
			buginfotag.appendChild(buginfo);
			debugcont.appendChild(buginfotag);
			setTimeout(function() {
				debugcont.scrollTop = debugcont.scrollHeight;
			},
			200)
			count++;
		};
		init=(function(){
			var debug = document.createElement('div');
			debugcont = document.createElement('div');
			clear = document.createElement('button');
			var cltext = document.createTextNode('清空');
			debug.id = 'debuginfo';
			debug.style.cssText = "position:absolute;right:5px;top:5px;width:300px;height:500px;border:1px solid #000000;overflow-y:auto;word-wrap:break-word;font-size:14px;";
			document.body.appendChild(debug);
			clear.id = 'cleardebug';
			clear.appendChild(cltext)
			debug.appendChild(clear);
			debug.appendChild(debugcont);
			clear.onclick=function(){
				setTimeout(function(){
					debugcont.innerHTML=''
					count=0;
				},0)
			}
		})();
	return log;
})();

How to find cursor position in a contenteditable DIV

Posted by 叶梓 on 八月 6th, 2010

If all you want to do is insert some content at the cursor, there’s no need to find its position explicitly. The following function will insert a DOM node (element or text node) at the cursor position in all the mainstream desktop browsers:

function insertNodeAtCursor(node) {
    var range, html;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        range.insertNode(node);
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        html = (node.nodeType == 3) ? node.data : node.outerHTML;
        range.pasteHTML(html);
    }
}

If you would rather insert an HTML string:

function insertHtmlAtCursor(html) {
    var range, node;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        node = range.createContextualFragment(html);
        range.insertNode(node);
    } else if (document.selection && document.selection.createRange) {
        document.selection.createRange().pasteHTML(html);
    }
}

Following the OP’s comments, I suggest using IERange, which adds a wrapper to IE TextRange object that behaves like a DOM Range. A DOM Range consists of a start and end boundary, each of which is expressed in terms of a node and an offset within that node, and a bunch of methods for manipulating the Range. The MDC article should provide some introduction.

jQuery 简单拖拽插件

Posted by 叶梓 on 七月 8th, 2010

今天试着把原生的拖拽函数改成了jQuery插件,留个记号吧

jQuery.fn.extend({
    drag:function(h,x,y,c){
	var mover = $(this);
	$.each(h,function(i){
	    if(!c){
		$(h[i]).css('cursor','move');
	    }else{
		$(h[i]).css('cursor',c);
	    }
	    $(h[i]).mousedown(function(e){
		if(!e) e = event;
		move(mover,e,x,y);
	    });
	})
	function move(ele,event,x,y){
	    var offset = ele.offset();
	    var startX = event.clientX,startY = event.clientY;
	    var origX = offset.left,origY = offset.top;
	    var deltaX = startX - origX,deltaY = startY - origY;
	    if(document.addEventListener){
		    document.addEventListener("mousemove",moveHandler,true);
		    document.addEventListener("mouseup",upHandler,true);
	    }else if(document.attachEvent){
		    ele[0].setCapture();
		    ele[0].attachEvent("onmousemove",moveHandler);
		    ele[0].attachEvent("onmouseup",upHandler);
		    ele[0].attachEvent("onlosecapture",upHandler);
	    }else{
		    var oldmovehandler = document.onmousemove;
		    var olduphandler = document.onmouseup;
		    document.onmousemove = moveHandler;
		    document.onmouseup = upHandler;
	    }
	    if(event.stopPropagation) event.stopPropagation();
	    else event.returnValue = false;
	    function moveHandler(e){
		    if(!e) e = window.event;
		    if(!y&&x){
			ele.css('left',x[0]);
			var posx = e.clientX - deltaX;
			if(x[0]){
			    var mxleft = x[0];
			}else{
			    var mxleft = ele.css('left');
			}
			var mxright = x[1]-ele.outerWidth(true);
			posx = Math.max(Math.min(posx, mxright), mxleft);
			ele.css('left',posx);
		    }else if(!x&&y){
			var posy = e.clientY - deltaY;
			var mxtop = y[0];
			var mxbottom = y[1]-ele.outerHeight(true);
			posy = Math.max(Math.min(posy, mxbottom), mxtop);
			ele.css('top',posy);
		    }else{
			var posx = e.clientX - deltaX;
			var posy = e.clientY - deltaY;
			if(x){
			    var mxleft = x[0];
			    var mxright = x[1]-ele.outerWidth(true);
			}else{
			    var mxleft = 0;
			    var mxright = $(window).width()-ele.outerWidth(true);
			}
			if(y){
			    var mxtop = y[0];
			    var mxbottom = y[1]-ele.outerHeight(true);
			}else{
			    var mxtop = 0;
			    var mxbottom = $(window).height()-ele.outerHeight(true);
			}
			posx = Math.max(Math.min(posx, mxright), mxleft);
			posy = Math.max(Math.min(posy, mxbottom), mxtop);
			ele.css('left',posx);
			ele.css('top',posy);
		    }
		    if(e.stopPropagation) e.stopPropagation();
		    else e.cancelBubble = true;
		    window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
	    }
	    function upHandler(e){
		    if(!e) e = window.event;
		    if(document.removeEventListener){
			    document.removeEventListener("mouseup",upHandler,true);
			    document.removeEventListener("mousemove",moveHandler,true);
		    }else if(document.detachEvent){
			    ele[0].detachEvent("onlosecapture",upHandler);
			    ele[0].detachEvent("onmouseup",upHandler);
			    ele[0].detachEvent("onmousemove",moveHandler);
			    ele[0].releaseCapture();
		    }else{
			    document.onmouseup = olduphandler;
			    document.onmousemove = oldmovehandler;
		    }
		    if(e.stopPropagation) e.stopPropagation();
		    else e.cancelBubble = true;
	    }
	}
    }
})

使用

<style>#drag{position:absolute;}</style>

<div id="drag"></div>

<script type="text/javascript">
$(document).ready(function(){
    $('#a').drag(['#hhh','.hhh2','#hhh3'],[56,98],[89,96],'move');
});
</script>

数字转换为国际格式-分割字符串

Posted by 叶梓 on 七月 1st, 2010

今天看到一则腾讯的招聘试题,一时兴趣,写了个

把数字格式123456789转换成123,456,789

function cn(number){
	var n = number + "";
	var arr = n.split("");
	var arr2 = new Array();
	for(var i = 0 ,len = arr.length; i<len/3; i++){
		var j = i*3;
		arr2.push(arr.slice(j,j+3).join(""));
	}
	alert(arr2.join(","));
}

用Js通过className插入圆角

Posted by 叶梓 on 四月 2nd, 2010

最近在给公司网站重构,页面有很多圆角,之前是将圆角结构直接写在页面中,使得页面很多无意义的代码,于是就想到通过一个className来插入圆角结构,从而精简代码。
html结构,css代码,和js函数如下
Html

<div class="contain ccb">
        <dl>
        	<dt>标题</dt>
            <dd>这里是内容啊,定义列表是用来解释标题的。</dd>
        </dl>
</div>

CSS

.rec-t,.rec-b{
	background:url(http://www.heavenfoliage.com/wp-content/uploads/2010/04/rec.png) no-repeat left top;
	height:8px;
	overflow:hidden;
}
.rec-t span,.rec-b span{
	background:url(http://www.heavenfoliage.com/wp-content/uploads/2010/04/rec.png) no-repeat right top;
	float:right;
	width:8px; height:8px;
}
.rec-b{background-position:left -8px;}
.rec-b span{background-position:right -8px;}
.rec-c{
	background-color:#fff88e;
	border:3px solid #000;
	border-bottom:none; border-top:none;
}

JavaScript

function pushRet(classElement){//这是主函数
	var allTag=document.getElementsByTagName("div"); //获得页面所有的div标签
	for(var i=0;i<allTag.length;i++){//我是用循环的方法遍历所有的div标签
		var tagClass=allTag[i].className;//获得每个div标签上的className
		if(tagClass.indexOf(classElement)!=-1){//判断是否有目标className

			/*这里主要是创建圆角的节点*/
			var rec_T=document.createElement("div"); //创建一个div 标签,命名为rec_T
			var rec_B=rec_T.cloneNode(true); //复制rec_T命名为rec_B
			var rec_SpanT=document.createElement("span"); //创建一个span标签,命名为rec_SpanT
			var rec_SpanB=rec_SpanT.cloneNode(true);//复制rec_SpanT命名为rec_SpanB
			addClass(rec_T,"rec-t");addClass(rec_B,"rec-b"); //分别给 rec_T,rec_B添加className
			rec_T.appendChild(rec_SpanT);rec_B.appendChild(rec_SpanB);//将rec_SpanT,rec_SpanB添加到rec_T,rec_B中

			/*这里是将上面创建的节点插入到含有目标class的div里*/
			var cont=allTag[i].innerHTML;
			allTag[i].innerHTML="<div class='rec-c'>"+cont+"</div>";//把内容插入到中间标签
			allTag[i].firstChild.parentNode.insertBefore(rec_T,allTag[i].firstChild);//把上圆角插入到第一个节点前面
			allTag[i].appendChild(rec_B); //把下圆角插入到最后
		}
	}
}
function addClass(element,value){//这是一个补充函数,用来给创建的标签添加className的
	if(!element.className){
		element.className=value;
	}else{
		newClassName=element.className;
		newClassName+=" ";
		newClassName+=value;
		element.className=newClassName;
	}
}

说说盒子模型box model

Posted by 叶梓 on 三月 25th, 2010

页面上的每个元素都能看作一个矩形框,这个框是由元素的内容,填充,边框和外边距组成。

盒模型的示意图

盒模型的示意图

 在CSS中,width和height指的是内容区域的宽度和高度,增加填充,边框和外边距是不会影响内容区域的尺寸的,但是会增加元素框的总尺寸;

假设上面的盒模型示意图,外边距(m)每个边上有15px,边框(b)每个边上有10px,填充(p)每个边上有15px,内容(c)有70px,那么这个元素的

总宽度等于 m*2+b*2+p*2+c=15*2+10*2+15*2+70=150px.

但是,IE5.x使用的是自己的非标准盒模型,IE6在怪异模式中也是使用自己的非标准盒模型,IE6的怪异模式指的是没有申明DTD的情况(上次在携程面试的时候,面试官跟我解释,IE6如果没有申明正确的DTD的话,浏览器会将IE解释为IE5.x),这些浏览器的width属性指的不是内容的宽度,而是内容,填充和边框的总和。

那么非标准的盒模型中,上例的总宽度等于 m*2+70=100px.

这是因为IE5.x认为每个边上的15px的填充和每个边上的10px的边框是70px的宽度的一部分,而不是宽度之外附加的。

要解决这个问题,最好是检查是否正在使用适合自己的标记语言的DOCTYPE,即申明正确的DTD,从而让页面以标准模型显示。

Lazy Load 延迟加载图片的 jQuery 插件

Posted by 叶梓 on 二月 22nd, 2010

本文翻译自 Lazy Load Plugin for js, 介绍一个 js 插件, 它提供懒汉式加载页面图片的功能.
怎样使用?
Lazy Load 依赖于 js. 请将下列代码加入页面 head 区域:

<script src="js.js" type="text/javascript"></script>
<script src="js.lazyload.js" type="text/javascript"></script>

并且在你的执行代码中加入下面语句:

$("http://www.appelsiini.net/projects/lazyload/img").lazyload();

这将使 id=”http://www.appelsiini.net/projects/lazyload/img” 区域下的图片将被延迟加载.
设置敏感度
插件提供了 threshold 选项, 可以通过设置临界值 (触发加载处到图片的距离) 来控制图片的加载. 默认值为 0 (到达图片边界的时候加载).

$("http://www.appelsiini.net/projects/lazyload/img").lazyload({ threshold : 200 });

将临界值定为 200, 当可视区域离图片还有 200 个象素的时候开始加载图片. (这一句原文的字面意思和本人理解不一致, 原文: Setting threshold to 200 causes image to load 200 pixels before it is visible.)
占位图片
你还可以设定一个占位图片并定义事件来触发加载动作. 这时需要为占位图片设定一个 URL 地址. 透明, 灰色和白色的 1×1 象素的图片已经包含在插件里面.

$("img").lazyload({ placeholder : "img/grey.gif" });

事件触发加载
事件可以是任何 js 时间, 如: click 和 mouseover. 你还可以使用自定义的事件, 如: sporty 和 foobar. 默认情况下处于等待状态, 直到用户滚动到窗口上图片所在位置. 在灰色占位图片被点击之前阻止加载图片, 你可以这样做:

$("img").lazyload({
placeholder : "img/grey.gif",
event : "click"
});

使用特效
当图片完全加载的时候, 插件默认地使用 show() 方法来将图显示出来. 其实你可以使用任何你想用的特效来处理. 下面的代码使用 FadeIn 效果. 这是演示页面.

$("img").lazyload({
placeholder : "img/grey.gif",
effect : "fadeIn"
});

图片在容器里面
你可以将插件用在可滚动容器的图片上, 例如带滚动条的 DIV 元素. 你要做的只是将容器定义为 js 对象并作为参数传到初始化方法里面. 这是水平滚动演示页面和垂直滚动的演示页面.
CSS 代码:

#container {
height: 600px;
overflow: scroll;
}

JavaScript 代码:

$("img").lazyload({
placeholder : "img/grey.gif",
container: $("#container")
});

当图片不顺序排列
滚动页面的时候, Lazy Load 会循环为加载的图片. 在循环中检测图片是否在可视区域内. 默认情况下在找到第一张不在可见区域的图片时停止循环. 图片被认为是流式分布的, 图片在页面中的次序和 HTML 代码中次序相同. 但是在一些布局中, 这样的假设是不成立的. 不过你可以通过 failurelimit 选项来控制加载行为.

$("img").lazyload({
failurelimit : 10
});

将 failurelimit 设为 10 令插件找到 10 个不在可见区域的图片是才停止搜索. 如果你有一个猥琐的布局, 请把这个参数设高一点.
延迟加载图片
Lazy Load 插件的一个不完整的功能, 但是这也能用来实现图片的延迟加载. 下面的代码实现了页面加载完成后再加载. 页面加载完成 5 秒后, 指定区域内的图片会自动进行加载. 这是延迟加载演示页面.

$(function() {
$("img:below-the-fold").lazyload({
placeholder : "img/grey.gif",
event : "sporty"
});
});
$(window).bind("load", function() {
var timeout = setTimeout(function() {$("img").trigger("sporty")}, 5000);
});

下载插件
最新版本: 源代码, 压缩的代码, 打包的代码
已知问题
由于 webkit 的 bug #6656, Lazy Load 在 Safari 和 Chrome 中无法使用. 它会立即为你加载所有你愿意和不愿意被载入的图片.
貌似 js 1.3.x 令插件在 IE 中失效了. 所有图片将在后台被加载即使它们不应该被加载. 作者正在为解决这个问题而努力, 在此期间只能停留在 js 1.2.6 中使用该插件.
还有, 如果你使用 Mint, 请将 mint 标签加在页面头部, 如果把 mint 标签加到页面结尾会干扰到 Lazy Load 插件. 这是一个相当罕见的问题, 如果有人找到解决办法请联系作者.

white-space 属性

Posted by 叶梓 on 一月 7th, 2010

white-space 属性

CSS 中的 white-space 属性用于设置文本空白符的处理规则,这其中包括:是否合并空白符、是否保留换行符、是否允许自动换行。各属性值的不同行为如下表所示:

white-space 属性值一览表

属性值 空白符 换行符 自动换行 最早出现于
normal 合并 忽略 允许 CSS 1
nowrap 合并 忽略 不允许 CSS 1
pre 保留 保留 不允许 CSS 1
pre-wrap 保留 保留 允许 CSS 2.1
pre-line 合并 保留 允许 CSS 2.1

:在 CSS1/2 下,white-space 属性只可应用于块级元素;在 CSS 2.1 下,可应用于所有元素。) Read the rest of this entry »

flash as3加载外部图片等比缩放类

Posted by 叶梓 on 十二月 30th, 2009

这是转来的 从蓝色

给自己留个档,以后方便查看 嘿嘿

<!–以下为转载啊–>

/*
等比缩放
as1984 - qq:38657783
20091221
请注意包路径,我的as包都放在tools目录下。所以包的路径是 tools
如果你的路径不一样,请注意修改
*/
package tools
{
public class imgzoom {

// 变量声明
private var isZoom:Boolean;//是否缩放
private var srcWidth:Number;//原始宽
private var srcHeight:Number;//原始高
private var maxWidth:Number;//限制宽
private var maxHeight:Number;//限制高
private var newWidth:Number;//新宽
private var newHeight:Number;//新高

public function imgzoom(srcWidth:Number,srcHeight:Number,maxWidth:Number,maxHeight:Number):
void
{
this.srcWidth=srcWidth;//获得原始宽度
this.srcHeight=srcHeight;//获得原始高度
this.maxWidth=maxWidth;//获得限定宽度
this.maxHeight=maxHeight;//获得限定高度
if(this.srcWidth>0 && this.srcWidth>0){//检查图片高度是否正常
this.isZoom=true;//高宽正常,执行缩放处理
}else{
this.isZoom=false;//不正常,返回0
}
conductimg();//执行缩放算法
}
public function width():Number{//返回处理后的宽度,精确到2个小数点
return Number(this.newWidth.toFixed(2));
}
public function height():Number{//返回处理后的高度,精确到2个小数点
return Number(this.newHeight.toFixed(2));
}
private function conductimg():void{
if(this.isZoom){//如果高宽正常,开始计算
if(this.srcWidth/this.srcHeight>=this.maxWidth/this.maxHeight){
//比较高宽比例,确定以宽或者是高为基准进行计算。
if(this.srcWidth>this.maxWidth){//以宽为基准开始计算,
//当宽度大于限定宽度,开始缩放
this.newWidth=this.maxWidth;
this.newHeight=(this.srcHeight*this.maxWidth)/this.srcWidth
}else{
//当宽度小于限定宽度,直接返回原始数值。
this.newWidth=this.srcWidth;
this.newHeight=this.srcHeight;
}
}else{
if(this.srcHeight>this.maxHeight){//以高为基准,进行计算
//当高度大于限定高度,开始缩放。
this.newHeight=this.maxHeight;
this.newWidth=(this.srcWidth*this.maxHeight)/this.srcHeight
}else{
//当高度小于限定高度,直接返回原始数值。
this.newWidth=this.srcWidth;
this.newHeight=this.srcHeight;
}
}
}else{//不正常,返回0
this.newWidth=0;
this.newHeight=0;
}
}
}
}

Read the rest of this entry »

前端性能优化

Posted by 叶梓 on 十一月 16th, 2009

前端性能优化了解yahoo性能优化N条的同学应该不会陌生,安装一个YSlow评分并对照着优化就可以了,但是有没有想过为什么要这么做就可以提升速度,这些与Web标准有没有某种关联或者因果呢。

第一类,服务器端优化

服务器端就是对你的网站的动态语言的执行(asp,php),数据库查询,存储等速度,总的来说就是输入/输出的运算。这些跟前端没关系,但是影响着前 端。YSlow里面没有,鬼知道你网站的服务器性能如何,看不出来,就自行优化服务器性能,数据库性能,多买点服务器扩容。
yslow有一条尽早刷新 Buffer (Flush the Buffer Early),貌似是不等html完成生成就传输。
提高域名的DNS解析速度。减少DNS的解析个数。这个不好归类,暂时放到这里吧。

第二类,传输优化

这类是大头,很烦,首先是字节,字节越小越好,怎么能小下来,最有效的方式就是google的方案,把首页做的极其精简,图片,html,静态文件都很小,再就是缓存,把文件放到本地缓存区读取。还有http请求数,减少文件传输中的排队等待。

字节优化

  1. 减少冗余html,结构化,语义化的html来实现,行为,表现,结构分离,独立的html文件将变得很小。
  2. 压缩文本文件,css,html,js去掉注释、空格、换行等。
  3. 降低图片字节,选择合适的图片类型,png-8是一个好东西,再用工具将图片进行压缩去掉,比如png-8的压缩工具。用合适的图片尺寸,不要把大图控制一下宽高就用上了。
  4. gzip压缩一下,减小服务器端传输到客户端时候的字节。
  5. flash文件和flash+xml的动态flash也减小字节

缓存
服务器端配置一下,提高缓存的命中率和把不经常修改的文件缓存了。
Add Expires headers、Etags、ajax使用get方式便于缓存。
把能分离出来的css,js分离成外部文件便于缓存。
使flash和xml文件可缓存。
打通不同运营商的限制
CDN提高不同类型运营商的网络传输速度,电信,网通,铁通,教育网统统搞定。

请求数
减少文件请求数,能合并到一起的合并一下,css,js,图片等,减小排队等待和服务器端开销。
分域提高同时加载数,优化排队等待。
避免404无效请求数。
避免重定向。

延迟加载和预载
把暂时不用的文件等主体页面加载完了再加载,把用户稍后要看浏览的内容预先加载进来,相册浏览就是很好的例子,先用小图片放大再把大图展示出来,看本张图片时把下一张预载进来等等。

第三类:客户端优化

  1. 讨厌的IE的滤镜和CSS expressions少用,小心把浏览器搞挂,CUP 100%死机。
  2. CSS放到前面,js能放到后面的放在代码后面。将页面尽早展示给用户。
  3. 减少iframe的使用,避免CPU扛不住。
  4. 减少DOM个数,减低浏览器解析压力。
  5. 使用 <link> 而不是@importChoose <link> over @import,在 IE 中 @import 指令等同于把 link 标记写在 HTML 的底部。而这与第一条相违背。
  6. 提高js的执行效率,话题太大不提了
  7. 缩小 Cookie,针对 Web 组件使用域名无关性的 Cookie (Use Cookie-free Domains for Components)
  8. 还有小图片的repeat背景会提高浏览器的CPU占用。
  9. 合理的DOM排序,把重要的内容代码前置,优先加载。

再就是些没对号入座的雅虎性能优化的条目。至此可以检验到页面工程师不是盖的,需要对代码、文件,http协议,缓存,服务器等精准的学习和控制,达到提供用户最最基本的体验——访问速度的体验。

Web标准的分离思想和结构化语义化html促成了以上很多条的实施,这是美工时代所不能比拟的。

来自经典论坛