动态生成元素并获取

1
2
3
<div id="container" class="container">

</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script type="text/javascript">
window.onload = function(){
function test1(){
var container = document.getElementById('container');
var html = "";
for(var i = 0;i < 5;i++){
html = '<div id="div'+i+'">'+i+'</div>'
container.innerHTML += html;
}
}

function test2(){
for(var i = 0;i < 5;i++){
var div = document.getElementById('div'+i);
console.log(div);//<div id="0"></div> -- <div id="4"></div>
}
}

test1()
test2()
}
</script>

通过test1()往container中插入五个div层,再通过test2()获取到这些div,此场景适用于动态插入多个同类型的div,并对这些div进行操作。比如,选择多张图片,每个div都是一个图片预览加上传的层,通过test2()对每个上传的层进行操作。

通过闭包在外部访问函数的私有变量

通过闭包实现外部访问函数的私有变量
接下来我们来看demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(function(){
var test = (function(){
return{
aaa : function(){
var a = 1;
function num(){
var b = 2;
return (a+","+b);
}
return num;
},
bbb : function(){
var b = test.aaa()();
alert(b);
}
}
})();
test.bbb(); // 1,2
})();

通过将aaa函数中num函数作为返回值,在bbb函数中调用aaa函数获取到num函数,执行num函数获取到变量值。
原理参考 [ JS作用域链 ]

关于CSS的层叠特性

我们先来看一个demo:

1
2
3
4
5
6
7
8
9
10
11
12
<style type="text/css">
.demo1{
color: green;
}
.demo2{
color: red;
}
.demo3{
color: blue;
}
</style>
<p class="demo1 demo2 demo3">这是一段测试文字</p>

那么段落文字是什么颜色呢?答案是blue,为什么呢?因为根据CSS的层叠特性,在同选择器等级的情况下,后定义的相同属性值会覆盖掉之前定义的属性值(注:这个和<p>中定义的class:demo1、demo2、demo3的排列顺序无关)。
所以如果是下面这个demo

1
2
3
4
5
6
7
8
9
10
11
12
<style type="text/css">
.demo1{
color: green;
}
.demo2{
color: red;
}
.demo3{
color: blue;
}
</style>
<p class=" demo3 demo1 demo2">这是一段测试文字</p>

段落文字颜色还是blue。
如果是

1
2
3
4
5
6
7
8
9
10
11
12
<style type="text/css">
.demo3{
color: blue;
}
.demo1{
color: green;
}
.demo2{
color: red;
}
</style>
<p class=" demo3 demo1 demo2">这是一段测试文字</p>

段落文字颜色就是red了。

模块·封装数据

有时候我们不希望外部访问私有变量,但希望外部可以来访问方法,我们通过模块模式来暴露相关的接口供外部调用,同时函数内部的私有变量外部又是访问不到的,从而实现了数据的封装,达到信息隐藏的目的。
接下来我们来看demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var prison = (function(){
var prisonerName = "Mike";
var jailTerm = "20 year term";
return {
prisoner : function(){
return prisonerName + "-" + jailTerm;
},
setJailTerm : function(term){
jailTerm = term;
}
};
})();
console.log(prison.prisoner()); //"Mike-20 year term"
prison.setJailTerm("Sententce commuted");
console.log(prison.prisoner()); //"Mike-Sententce commuted"

通过立即执行函数可以避免全局污染。
我们不能通过prison. prisonerName和prison. jailTerm来访问prison的变量(私有变量),因为私有变量的生命周期只存在立即执行函数的作用域内,但是我们可以通过访问prison.prisoner()和prison.setJailTerm()这两个对象方法(函数暴露的接口)来访问和修改变量值。

笔记1:关于作用域

1
2
3
4
5
6
7
8
9
var x = 10;
function foo(){
console.log(x);
}
function bar(){
var x = 20;
foo();
}
bar();

输出为:10
解析:作用域链的角度:执行bar()函数时进入到function bar()作用域里面,然后执行foo()函数,进入到function foo()作用域里面,要输出x,然后function foo()去找x,只有在全局global环境中找到了var x = 10;所以bar()就输出了10

1
2
3
4
5
6
7
8
9
var x = 10;
function bar(){
var x = 20;
function foo(){
console.log(x);
}
foo();
}
bar();

输出为:20
解析:执行bar()函数进入到function bar()作用域里面,然后执行foo()函数,进入到function foo()作用域里面,要输出x,然后function foo()去找x,根据作用域链,我们先找foo()函数里面的x,发现没有,就去找bar()函数里的x ,发现是var x = 20就停止搜索了,所以bar()就输出了20