【前端】近期前端开发小结

近期一直在做前端开发。。。感觉自己的知识点被不断刷新。。秉持着好记性不如烂笔头的念头,就此记录下吧,以供参考~

1、js的闭包

当把js函数写在$(document).ready(function(){...}里面,就相当于闭包的效果。被包围起来的js函数内部可以互相调用,但是外部无法直接调用,闭包可以避免前端内存泄漏(?)如:

 

$(document).ready(function(){
	function getOperatorHtml(msg) {
		//...
		e += '<div class="content-top-list" name="on" data-name="'+msg.userName+'" id="'+msg.userName+'_div" onclick="switchShow(\''+msg.userName+'\')">';
		//...
		return e;
	}
	
	function switchShow(userName) {
		//...
	}
}

 点击class为content-top-list的div这个会报错:找不到switchShow方法,而通过调试查看改元素发现Event Listeners也并没有这个switchShow。

 

原因是onclick属性是跟dom节点相关的,相对于闭包里的js函数属于“外部”操作,是无法调用闭包内部的js方法的。

 

2、jquery的delegate绑定事件

delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数。

使用 delegate() 方法的事件处理程序适用于当前或未来的元素(比如由脚本创建的新元素),即可以给动态生成的元素绑定事件。

父元素必须是在dom上一加载的时候就有的dom元素,而非通过append动态添加,子元素则没有此限制,一般推荐用顶级父元素body即可~

这个方法的神奇之处在于“未来的元素”,也就是说还未append到dom上的元素也能用它来指定。。必须注意是用于“子元素”而非自己本身。用法如:

 

$("body").delegate(".content-top-list","click", function(){
        	//$(this)即是获取当前click的对象
                //.....
    	});

 写body是因为懒得去找子元素.content-top-list的直接父节点,注意作用对象为.content-top-list的元素。

比如1中的情形,我们可以这样绑定,而非直接通过onclick:

$(document).ready(function(){
	function getOperatorHtml(msg) {
		//...
		e += '<div class="content-top-list" name="on" data-name="'+msg.userName+'" id="'+msg.userName+'_div" >';
		//...
		return e;
	}
	
	$("body").delegate(".content-top-list","click", function(){
			var userName = $(this).data("name");
        	switchShow(userName);
    	});
	
	function switchShow(userName) {
		//...
	}
}

 注意:data("attrName")可以获取属性为data-attrName对应的值。

 

3、调用iframe里面的js函数和本页面js函数的先后顺序

之前已经讲过当一个页面嵌入iframe时,本页面和iframe页面的js互相调用的方式,这里需要注意执行顺序,如:

window.frames[0].setLate(name);
if(!isOverflow) {
  switchShow(name)
}

 这个例子里,虽然顺序是先调用iframe的js函数setLate,但是执行顺序是switchShow(name)-->window.frames[0].setLate(name)

可以理解成iframe里的js函数是以子线程的方式被执行,而本页面的js函数是主线程的方式被执行

 

4、滚动条置底

方法为: dom对象.scrollTop = dom对象.scrollHeight;

调用时需注意:

   1)对象是dom对象,如果是jquery对象,需用jquery对象[0]转换成dom对象

   2)该dom对象是存在的(即是一个dom节点真实存在)

   3)改dom对象已经显示出来了。(这点比较容易被忽视,hide时是无效的)

 

5、判断某个元素是否是显示的

if($("selector选择器“).filter(":visible").length>0)

6.前端定时器

注意每setInterval一次,就相当于创建一个定时器的“副本”一次,比如:

system["readMessage"] = window.setInterval(function (){readMessage()}, 1000);

如果调用多次,就会启动多个相同的定时器。

但是clearInterval一次,就会把所有的创建好的定时器的“副本”都给关掉。关定时器的经典写法是:

if(system["readMessage"]) {
      clearInterval(system["readMessage"]);
      system["readMessage"]=null;
}

 所以:创建定时器的时候要注意之前是否已经创建过,为避免重复创建(毕竟页面上同个定时器运行多个副本会造成资源浪费或卡顿),如果可能重复创建,建议每次创建前先调用关闭的逻辑在创建。可保证一个定时器只有一个“副本”在运行~

7.注意append也有可能触发remove

如:

var $transferContent = top.$("#" + transferFrom).find(".mianze").siblings().not("#historyChat_" + transferFrom);
$contentDiv.append($transferContent);

 会把top.$("#" + transferFrom)的这部分内容追加到$contentDiv,但同时top.$("#" + transferFrom)的这部分内容也会被remove;

而:

var $transferContent = top.$("#" + transferFrom).find(".mianze").siblings().not("#historyChat_" + transferFrom);
var $transferContent2 = $transferContent.clone();
$contentDiv.append($transferContent2);

 这样也会追加到$contentDiv,而top.$("#" + transferFrom)的这部分内容也会被保留下来。

原因:clone出来的内容不在文档流中,不clone,就指向文档流(文档流就是整个dom节点),append是节点的移动,移动当然会删除原有的。append一直就是移动节点,只是常用时经常时直接新增节点(新增的时候内容一般是自己新定义的,所以当然不涉及到删除~)

 

猜你喜欢

转载自raising.iteye.com/blog/2371369