人生苦短,我用python-- Day16 JavaScript补充+Dom补充
1.在Day15里面写过,JavaScript中有字典,其实JavaScript中没有字典,而是对象
2.Day15里面说的循环,里面可以使用cntinue跳出本次循环,break跳出全部循环;
循环支持for(有两种循环写法);while循环;
条件语句支持
1,if(){...}else{...} ;
2, if(){...}else if(){...}else{...}
3,switch(name){case '1':age = 123;break;case '2':age = 456;break;default :age = 777;}
下面是今天的内容
1.函数
普通函数
function funname(){
......;
}
匿名函数
<!--没有名字,称之为匿名函数--> setInterval(function(){ console.log(123) },5000)
自执行函数
<!--设置一个形参arg,执行函数时候附一个实参为1--> function(arg){ console.log(arg) }(1)
2.序列化
JSON.stringify() 将对象转换成字符串
l = [11,22,33,44]
[11, 22, 33, 44]
JSON.stringify(l)
"[11,22,33,44]"
l_str=JSON.stringify(l)
"[11,22,33,44]"
JOSN.parse() 将字符串转换成对象类型
new_list = JSON.parse(l_str)
[11, 22, 33, 44]
3.转义
- decodeURI( ) URl中未转义的字符
url_new = 'https://www.baidu.com/s?wd=%E5%A4%AA%E6%97%A9'
url_new_new = decodeURI(url_new) "https://www.baidu.com/s?wd=太早"
- decodeURIComponent( ) URI组件中的未转义字符 转义了冒号和双斜杠
url "https://www.baidu.com/s?wd=太早" newurl = encodeURIComponent(url) "https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D%E5%A4%AA%E6%97%A9"
- encodeURI( ) URI中的转义字符
url = 'https://www.baidu.com/s?wd=太早'
url_new = encodeURI(url) "https://www.baidu.com/s?wd=%E5%A4%AA%E6%97%A9"
- encodeURIComponent( ) 转义URI组件中的字符
newurl ="https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D%E5%A4%AA%E6%97%A9" decodeURIComponent(newurl) "https://www.baidu.com/s?wd=太早" decodeURI(newurl) "https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D太早"
- escape( ) 对字符串转义
- unescape( ) 给转义字符串解码
- URIError 由URl的编码和解码方法抛出
4.eval
JavaScript中的eval是Python中eval和exec的合集,既可以编译代码也可以获取返回值。
eval可以实现字符串的运算
5.时间
JavaScript中提供了时间相关的操作,时间操作中分为两种时间:
- 时间统一时间
- 本地时间(东8区)
更多操作参见:http://www.shouce.ren/api/javascript/main.html
data是一个对象,如果我们要使用这个对象首先要实例化这个对象
data = new data() Wed Nov 23 2016 14:32:53 GMT+0800 (CST)
获取当前的时间的分钟为多少
data = new data() Wed Nov 23 2016 14:32:53 GMT+0800 (CST) min = data.getMinutes() 32
需要说的是,实例化一个data的对象,会把实例化那一时刻的时间封装到data这个变量中,时间并不是变化的
6.JavaScript 作用域
python中的作用域是以函数当做作用域
执行成功:
def func(): if 1==1: name = 'sean' print(name) func()
执行失败:
def func(): if 1==1: name = 'sean' print(name) func() print(name)
1.JavaScript中也是以函数作为作用域;
2.函数的作用域在函数未被调用之前已经创建
解释:当解释编译解释的过程中,作用域就已经创建。
3.函数的作用域存在作用域链,并且也是在被调用之前创建
解释:函数的作用域存在作用域链
xo = 'sean'; "sean" <!--定义一个函数fun--> function fun(){ xo = 'tom'; <!--里面套一个函数inner--> function inner(){ xo = 'jack'; console.log(xo); } }
当fun函数被调用的时候,会一次执行到最里面的inner函数,它会打印一个xo的变量,如果inner作用域有xo变量那么就打印,如果没有就向上找看fun的作用域
里面是有xo这个变量,如果依旧没有就去最外面找。如果找到了就打印,如果没找到就报错
解释:作用域链在被调用之前就被创建
xo = 'sean' "sean" <!--定义一个函数fun--> function fun(){ xo = 'tom'
<!--里面套一个函数inner--> function inner(){ console.log(xo) } return inner; } a = fun() inner(){ console.log(xo) } a()
当执行fun()函数的时候 结果a=inner这个函数,我们加上括号看一下执行结果,执行以下a(),
结果是:
tom
我们解释下为什么是tom,而不是sean;有的童鞋说了,现在这个a函数不是在最外面了嘛,为什么会调用里面的xo变量呢?因为我们说过在作用域链未被调用之前,
作用域链的的作用域就已经被创建
4.函数内部局部变量声明提前
function func(){ console.log(xxoo); var xxoo = 'sean'; }
当执行func()函数的时候,结果是什么?
undefined
解释:
当解释器解释JavaScript代码的时候,函数里面的局部变量都会被先声明,声明的过程为:
var xxoo;
因为只是声明了一个xxoo变量,并未赋值,所以现在的值是undefined,因此上面的结果也是undefined;这里就体现了“函数内部局部变量声明提前”
7、JavaScript面向对象
function Foo(n) { this.name = n; } var obj = new Foo('sir')
a.封装一个对象的时候,this关键字相当于对象名;(和python中的self功能相似)
b.创建对象时,new关键字进行创建,方法为 new 函数()即可
8、DOM补充
8.1 查找
8.1.1 直接查找
var obj = documetn.getElemntById('i1')
8.1.2 间接查找
8.2 操作
8.2.1 文件内容操作:
innerText:只获取内容
innerHTML:全部内容,各种标签都能拿到
注意:不管是获取内容还是操作内容,innerText都是字符串的格式,innerHtml则会转义特殊字符(标签)
获取数据的区别
obj = document.getElementById('1') <div id="1">" 老男孩 "<a>google</a></div> obj.innerText "老男孩 google" obj.innerHTML " 老男孩 <a>google</a> "
赋值的区别
innerText:
innerHTML:
input类的value属性
获取:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id =1> <input type="text" id="2"> </div> </body> </html>
obj = document.getElementById('2') <input type="text" id="2"> obj.value "asdf"
赋值:
select标签的value属性
获取:
赋值:
也可以使用selectedIndex属性进行select标签进行获取或赋值
onfocus事件:
是获取鼠标焦点事件
onblur事件:
是失去鼠标焦点事件
写一个输入用户名的案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div> <input style="color: #7B7B7D;" type="text" value="请输入用户名" id="i1" onfocus= "Focus()" onblur="Blur()"> </div> <script> function Focus(){ var obj = document.getElementById('i1'); var val = obj.value; if (val == '请输入用户名'){ obj.value = ''; } } function Blur() { var obj = document.getElementById('i1'); var val = obj.value; if (val == 0){ obj.value = '请输入用户名'; } } </script> </body> </html>
样式操作
一个标签可以定义一个或多个class的值,当使用JS获取的时候,classname能获取到class对应的所有值,拿到的是一个字符串;classlist能获取到class对应的所有值,拿到的是一个列表,这个有两个方法,分别为add(添加一个值)、remove(删除一个值);这样操作的最小单元是由一个或多个组成的样式集合;
还可以使用如下方法进行操作:
这样操作最小单元为一个属性,而不是由多个属性放在一起的一个class
属性操作
增加一个属性:setAttribute
删除一个属性:removeAttribute
查看所有属性:
实验案例:
写一个点某个按钮,能增加输入框的功能
方法一:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p> <input type="button" value='添加' onclick="AddEle();"> <div id="1"> <input type="text" /> <hr> </div> </p> <script> function AddEle() { // 创建一个标签 var tag = "<p><input type='text' /></p>" // 把tag变量值增加到id为1的标签最后面 document.getElementById(1).insertAdjacentHTML("beforeEnd",tag) } </script> </body> </html>
方法二:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <p> <input type="button" value='添加' onclick="AddEle();"> <div id="1"> <input type="text" /> <hr> </div> </p> <script> function AddEle() { // 创建一个标签 var tag = document.createElement('input'); tag.setAttribute('type','text'); tag.style.color = 'red'; tag.style.fontSize = '20px'; // 把tag变量值增加到id为1的标签最后面 var p = document.createElement('p'); p.appendChild(tag) document.getElementById(1).appendChild(p); } </script> </body> </html>
上面方法一种有一个关键字为:berforeEnd、其实还有三个关键字功能类似我们来说一下:
beforeBegin(标签里面的第一个位置)、afterBegin(标签同级的第一个位置)、beforeEnd(标签里面的最后位置)、afterEnd(标签同级的最后位置)
提交表单
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form id="f1" action="http://www.baidu.com"> <input type="text"> <!--方法一通过input标签进行提交--> <input type="submit" value="提交"> <!--方法二通过a标签借助js进行提交,其实任何标签通过dom都能提交表单--> <a onclick="submitForm()"> 提交 </a> </form> <script> function submitForm() { document.getElementById('f1').submit(); } </script> </body> </html>
其他:
console.log() 输出信息
alert(123) 弹出框
var v = confirm(‘真的要删除吗?’) v获取返回值,如果点确定v为true,如果点取消v为false
location.href 获取当前url
location.href = ‘http://www.baidu.com’ 重定向
location.href = location.href 页面刷新
location.reload() 页面刷新
setInterval(function(){
......
},5000) 定时器一直执行(没有清除的情况下),每隔5秒执行以下这个方法
var obj = setInterval(function(){
.....
},5000)
clearInterval(obj); 清除这个定时器,要注意的是这个清除定时器执行于定时器之前
setTimeout(function(){
....
},5000); 定时执行,只执行一次;当后面设置的时间,到了后才会执行function里面的代码
clearTimeout 清除这个定时器,使用方法和clearInterval的使用方法是一样的
Dom--->事件
实验案例:写一个行为 样式 结构 相分离的页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style> #i1{ background-color: red; width: 380px; height: 400px; } </style> <body> <div id="i1"> 123 </div> <script> var tar = document.getElementById('i1'); tar.onclick = function () { console.log('123456') } </script> </body> </html>
实验案例:写一个各行高亮的案例
dom0的方法,这里的dom0是写dom的等级,dom0等级最低;初学者一般都这么写,但是效率低,看起来low;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1px" width="300px"> <tr onmousemove="t1(0);" onmouseout="t2(0);"><td>1</td><td>2</td><td>3</td></tr> <tr onmousemove="t1(1);" onmouseout="t2(1);"><td>1</td><td>2</td><td>3</td></tr> <tr onmousemove="t1(2);" onmouseout="t2(2);"><td>1</td><td>2</td><td>3</td></tr> </table> <script> function t1(n) { var mytrs = document.getElementsByTagName('tr')[n]; // console.log(mytrs) mytrs.style.backgroundColor="red"; } function t2(n) { var mytrs = document.getElementsByTagName('tr')[n]; mytrs.style.backgroundColor = ''; } </script> </body> </html>
dom2方法实现,使代码更简便
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1px" width="300px"> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> <tr><td>1</td><td>2</td><td>3</td></tr> </table> <script> var myTrs = document.getElementsByTagName('tr'); var len = myTrs.length; // 循环拿到的所有的tr的列表 for (var i=0;i<len;i++){ // 分别给每个tr绑定一个onmouseout事件 myTrs[i].onmousemove = function () { // 谁调用这个函数,this就指向谁 this.style.backgroundColor="red"; } } // 循环拿到的所有的tr的列表 for (var i=0;i<len;i++){ // 分别给每个tr绑定一个onmouseout事件 myTrs[i].onmouseout = function () { // 谁调用这个函数,this就指向谁 this.style.backgroundColor=""; } } </script> </body> </html>
通过上面 两种方法的操作,我们知道了绑定事件有两种方法,
第一种方法是直接在标签上绑定事件即可
第二种方法是先获取Dom对象,然后进行绑定
docment.getElementById('xx').onclick = function(){...}
this,如果使用第一种方式进行绑定事件,需要绑定的时候传一个参数叫this,不要叫引号,下面定义方法的时候直接使用形参接受this即可
<input id ='i1' type='text' onclick='ClickOn(this)'> function ClickOn(self){ //self 就是当前点击的标签, }
this,如果使用第二种方式进行绑定事件,不需要传参数,谁调用当前方法,this就指向谁
<input id = 'i1' type='text'> document.getElementById('i1').onclick = function(){ //this 指代当前点击的标签,触发function的标签 }
第三种绑定事件的方法:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <style> #main{ background-color: red; width: 300px; height: 300px; } #content{ background-color: wheat; width: 100px; height: 100px; } </style> <body> <div id="main"> <div id="content"></div> </div> <script> var mymain = document.getElementById('main'); var mycontent = document.getElementById('content'); // 第三种绑定事件模式,有三个参数,意思分别为(要绑定的时间,执行的方法,冒泡模式或捕捉模式) mymain.addEventListener('click',function () {console.log('mymain')},false); mycontent.addEventListener('click',function () {console.log('mycontent')},false); </script> </body> </html>
讲一下冒泡模式和捕捉模式有什么区别:
冒泡模式是下面的最先执行,捕捉模式是最上面的先执行;
所有上面的第三种绑定方法,如果点击里面那个div的话,如果是false的话,那么肯定是先打印mycontent;如果为True的话反之
事件举例:
JavaScript此法分析解析:
看一下下面代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script> function t1(age) { console.log(age); var age = 27; console.log(age); function age() {} console.log(age) } t1(2) </script> </body> </html>
看一下输出结果:
哈哈 是不是人生观被颠覆了。。。。我们来解释下为什么会这样
函数在进行调用之前会进行词法分析,函数在形成调用的那一瞬间会有一个活动对象,叫做active object 简称AO,
分析步骤为:首先分析形势参数--->分析函数内局部变量--->分析函数内声明表达式
在第一个步骤中:形势参数:形势参数有一个age,这个形势参数会赋值到AO上----->AO.age == undifined;发现有一个实际参数2传过来了,那么AO.age=2;把原先的undifined覆盖了
在第二个步骤中:局部变量,发现有一个age局部变量,此时AO.age==2,如果AO对象上有这个局部变量不做任何改变
在第三个步骤中:函数声明表达式(优先级高,直接进行赋值),所有这里的AO.age=function()
现在AO对象上有一个age值为function{},所以第一个console的时候会打印function;往下继续走这是age重新赋值了,等于27.因此第二个console等于27;继续往下走
是一个空的函数体,没有任何操作,所有age还是27,因此第三个console等于27;结果就是我们看到的那样的了