python编程24种模式_Python编程(二十四):JavaScript进阶,DOM操作

在HTML中就是一大堆的标签,分块级和行内标签。

一、CSS补充:页面布局

CSS常用属性有:

position

background

text-align

margin

paddin

font-size

z-index

over-flow

:hover

opacity

float(clear:both)

line-height

border

color

display

主站布局:在主站中页面主要分三块:页面头部,页面主体,页面末尾,下面代码定义了页面的这三个部分。

内容自动剧中

1、第一种布局

在布局时,先考虑顶部,然后左侧菜单,右侧内容,可用3个div标签来做。例如下面代码所示。在下面的代码中,引用了一种样式min-width(最小宽度),引用该样式后,当页面缩小到最小宽度后就使用它定义的宽度。也就是说引用了这宽度的标签缩小后的像素不能小于这个宽度。

body{

margin: 0;

}

.left{

float: left;

}

.right{

float: right;

}

.pg-header{

height: 48px;

background-color: #2459a2;

color: white;

}

.pg-content .menu{

width: 20%;

background-color: red;

/*当缩小到最小宽度时就采用最小宽度*/

min-width: 50px;

}

.pg-content .content{

width: 80%;

background-color: green;

}

world

2、第二种布局

在第一种布局的基础上,使用position属性的fixed值和overflower属性的auto值实现内容超屏幕就出现滚动条,但是右侧菜单位置不会变。例如下面代码所示。

body{

margin: 0;

}

.left{

float: left;

}

.right{

float: right;

}

.pg-header{

height: 48px;

background-color: #2459a2;

color: white;

}

.pg-content .menu{

position: fixed;

top: 48px;

left: 0;

bottom: 0;

width: 200px;

background-color: #dddddd;

}

.pg-content .content{

position: fixed;

top: 48px;

right: 0;

bottom: 0;

left: 200px;

background-color: purple;

overflow: auto;

}

world

python

3、第三种布局

在第二种布局的基础上,只要改两个属性的值就能实现左侧菜单不动或者跟随滚动等。要改的属性就是position和overflow的属性值。代码示例如下,下面是样式的代码片断,其余代码与第二种布局一样。在第二个content样式中position的值是absolute,overflow的值是auto。

.pg-content .menu{

position: absolute;

top:48px;

left:0;

bottom: 0;

width: 200px;

background-color: #dddddd;

}

.pg-content .content{

position: absolute;

top:48px;

right: 0;

bottom: 0;

left:200px;

background-color: purple;

overflow: auto;

}

4、后台管理布局,第四种布局

在页面的右上角显示登录后的头像,并且鼠标放到头像上自动出现下拉菜单功能。主要运用的样式有:

position(relative, absolute), float, :hover,margin, text-align,display,z-index,overflow。

body{

margin: 0;

}

.left{

float: left;

}

.right{

float: right;

}

.pg-header{

height: 48px;

background-color: #2459a2;

color: white;

line-height: 48px;

}

.pg-header .logo{

width: 200px;

background-color: cadetblue;

text-align: center;

float: left;

}

.pg-header .user{

width: 160px;

background-color: #dddddd;

height: 48px;

padding: 0 20px;

}

.pg-header .user:hover{

background-color: rosybrown;

}

.pg-header .user .a img{

height: 40px; width: 40px; border-radius: 50%; margin-top: 4px

}

.pg-header .user .b{

z-index: 20;

position: absolute;

top: 48px;

/*right: 15px;*/

left: -10px;

background-color: red;

width: 100px;

display: none;

}

.pg-header .user:hover .b{

display: block;

}

.pg-header .user .b a{

display: block;

}

.pg-content .menu{

position: absolute;

top:48px;

left:0;

bottom: 0;

width: 200px;

background-color: #dddddd;

}

.pg-content .content{

position: absolute;

/*position: fixed;*/

top:48px;

right: 0;

bottom: 0;

left:200px;

background-color: purple;

overflow: auto;

z-index: 9;

}

我的资料

用户中心

注销

python

在网站使用图标,可参考https://fontawesome.com/?from=io这个网站上的图标,把样式下载下来解压后连同目录一起放入html的当前目录,此时可以引入该样式进行使用。例如下面这样:

三、JavaScript进阶

JavaScript里实际没有字典,它是属于对象。

在js中的循环,同样有continue和break语句。continue结束本次循环,继续下一次循环。break终止循环。

while循环,语法如下:

while(条件){

循环体

}

还有一个循环是switch...case:

switch(name){

case "1":

console.log(123);

break;

case "2":

console.log(456);

break;

default :

console.log('999');

}

1、函数

JavaScript的函数有:普通函数,匿名函数,自执行函数。

普通函数,定义及调用方法如下:

function func(arg){

return arg+1;

}

var result = func(1);

console.log(result);

除上了面的普通函数外,还有匿名函数,例如:

setInterval(function(){

console.log(123);

}, 5000)

上面这段代码调用了定时器函数seInterval。第一个参数是一个匿名函数,第二个参数是时间5000毫秒。

匿名函数就是没有函数名字的函数。

还有自执行函数,例如:

function func(arg){

console.log(arg)

}

func(123) //这几行代码可以写为下面的形式:

(function(arg){console.log(arg)})(1)

上面这一行代码就是自执行函数,由两个括号定义()(),第一个括号内是函数体,第二括号是调用函数,也可以传参数。

自执行函数:创建函数并且自动执行。

自执行函数举例,代码如下所示,运行下面代码后,浏览器首先会弹出一个窗口显示“hello world”,接着在console上显示“hello michael”。

(function (arg1, arg2) {

console.log(arg1)

alert(arg2)

} )('hello michael', 'hello world')

2、JS序列化

JSON.stringify() 将对象转换为字符串

JSON.parse() 将字符串转换为对象类型

在console上操作

现有下面一个数组:

nums = [11,22,33,4,5]

JSON.stringify(nums) //把nums转换成了字符串,输出如下:

"[11,22,33,4,5]"

也可以把这个字符串赋值给一个变量

var s = JSON.stringify(nums)

还可以使用JSON.parse()方法把字符串转换成数组,该方法更常用:

newnums = JSON.parse(s)

newnums // 此时已是一个数组,输出如下:

[11, 22, 33, 4, 5]

3、转义

decodeURI() URl中未转义的字符

decodeURIComponent() URI组件中的未转义字符

encodeURI() URI中的转义字符

encodeURIComponent() 转义URI组件中的字符

escape() 对字符串转义

unescape() 给转义字符串解码

URIError 由URl的编码和解码方法抛出

下面用代码来理解这几个方法的涵义。

现假设有下面这个url变量:

url = "https://www.baidu.com/s?ie=UTF-8&wd=d成都"

encodeURI(url) // 把url中的中文转义成特殊字符,输出如下:

"https://www.baidu.com/s?ie=UTF-8&wd=d%E6%88%90%E9%83%BD"

newurl = encodeURI(url) //把转义后的url赋值给变量newurl

decodeURI(newurl) // 使用decodeURI把newurl中的中文转义回来,输出如下:

"https://www.baidu.com/s?ie=UTF-8&wd=d成都"

newurl2 = encodeURIComponent(url) // 使用encodeURIComponent进行转义,输出如下:

"https%3A%2F%2Fwww.baidu.com%2Fs%3Fie%3DUTF-8%26wd%3Dd%E6%88%90%E9%83%BD"

从上面的输出可以看出,使用encodeURIComponent时,只有url中的英文字母没有被转义,其它的中文字符和特殊符号全部被转义了。

decodeURIComponent(newurl2) //decodeURIComponent就是转义回来,输出如下:

"https://www.baidu.com/s?ie=UTF-8&wd=d成都"

当登录某个网站时,第一次输入用户名和密码后,第二次打开该网站就已经进入登录状态。这是因为第一次登录时,服务端向浏览器发送了cookie,浏览器把这个cookie保存到本地硬盘。下次再打开这个网站时就使用这个cookie请求网站,这样就获得了登录状态。所以cookie被拿到其他电脑上,也是可以用的。

由于服务器端发送过来的数据可能包含中文、特殊符号等,这就需要进行转义。将数据经过转义后,保存在cookie中。

举例:给某个网站进行点赞

通常要点赞操作,都要求先登录。由于登录后服务器端会给客户端发送cokie,可以先进行登录拿到这个cookie,下次登录时带上这个cookie,这样就能自动登录后点赞。

4、eval

在python中eval只能计算简单的表达式,而exec可以计算复杂的表达式。在JavaScript中的eval,可以计算简单的表达式,也可以计算复杂的表达式。

5、时间

在JavaScript中的Date对象,Date是一个类。

var d = new Date() //此时d就当前的一个时间对象

这个时间对象有很多的方法可以对d中的值进行访问和操作。比如:

d.getDay() //输出是星期几,如输出5表示星期五。

d.getMinutes() // 输出的是分钟

n = d.getMinutes() + 5 //分钟加5

d.setMinutes(n) // 修改时间对象d的分钟值

当然还有很多的方法可以进行获取和设置。这里就不一一列出。可以总结为下面两点:

d.getXXX() 是获取某个值

d.setXXX(n) 根据提供的参数去设置某个值

6、作用域

其他语言:以代码块作为作用域。比如下面这段java代码。

public void Func(){

if(1==1){

string name = 'java';

}

console.writeline(name);

}

Func() // 调用函数

上面代码用python的视角看,应该是可以正常运行,但是在java中name变量是局部变量,只在if的代码块中生效,也是在if对应的一对大括号{}中生效,出了这对大括号就失效,在这对大括号外面访问name变量就会报错。

下面再来看python代码的作用域。

情况一,代码如下:

def func():

if 1==1:

name = 'python'

print(name)

func() # 调用函数,这个可以正常运行。

情况二,代码如下:

def func():

if 1==1:

name = 'python'

print(name)

func() # 调用函数,可以正常运行

print(name) # 访问name变量,不能正常运行,报错:变量未定义

从上面的例子可以看出,在python中是以函数为作用域的,在其他语言中,是以代码块(块级)为作用域的。在JavaScript中,也是以函数作为作用域的。例如下面代码所示:

function func(){

if(1==1){

var name = 'michael';

}

console.log(name)

}

func() //函数可以正常执行,输出:michael

JavaScript作用域小结:

a. 以函数作为作用域,但要排除变量名前用let关键字。

b. 函数的作用域在函数未被调用之前,已经创建。当解释器编译函数代码时,作用域就已经创建。

c. 函数的作用域存在作用域链,并且也是在被调用之前创建。函数内嵌套函数,解释器遇到函数就解释为作用域,这就是作用链。例如下面代码所示。

name = 'michael'; //定义一个全局变量

function func(){

var name = 'tom';

function inner(){

var name = 'jack';

//console.log(name)首先在inner函数内部找变量name,未找到就往上层找

console.log(name);

}

inner() // 调用inner函数,输出:jack

}

func() // 调用func函数,输出:jack

理解了上面的例子,下面再来看一个例子,对作用域链进一步的理解,代码如下:

name = 'michael'; //定义一个全局变量

function func(){

var name = 'tom';

function inner(){

console.log(name);

}

return inner; //返回的是函数对象,不是调用函数

}

var ret = func() // ret是inner函数对象

ret() // 调用inner函数,输出:tom

对上面的示例理解后,继续看下面的代码示例。解释器在解释的时候遇到函数会创建作用域。

name = 'michael'; //定义一个全局变量

function func(){

var name = 'tom';

function inner(){

console.log(name);

}

var name = 'jack';

return inner; //返回的是函数对象,不是调用函数

}

var ret = func() // ret是inner函数对象

ret() //调用inner函数,输出是:jack

d. 函数内部局部变量声明提前。

var nn; // 这行代码定义一个变量nn,但未赋值,JavaScript会默认给变量一个特殊值undefined。

示例一,代码如下:

函数在解释过程中,解释器会把函数中未定义的变量提前声明为:var nm;

function func(){

console.log(nm); // 此时: var nm;

var nm = 'michael';

}

func(); // 此时调用函数,输出是:undefined

示例二,代码如下:

function func(){

console.log(nm);

}

func(); // 未在函数内部声明变量nm,调用函数会报错

7、JavaScript面向对象

在JavaScript中关键字this相当于python中的self。

function foo(){

var nm = 'michael';

}

foo() // 调用函数

在函数中使用this关键字,面向对象

function foo(){

this.name = 'michael'; // 使用关键字this

}

下面来创建对象:必须要使用关键字new

var obj = new foo();

访问对象中的方法或变量:访问foo()函数中的name变量。

obj.name; // 值是:michael

也可以在创建对象函数时,传递参数,例如下面:

function Foo(n){

this.name = n;

}

var obj = new Foo('michael') //创建对象时传递参数

从上面示例可以看出,在javascript中创建函数与创建对象的区别:

a. this代指对象(python中的self)

b. 创建对象时使用new关键字, new 函数名()

在javascript中创建函数,函数有关键字this,相当于在创建类,看下面代码:

function Foo(n){

this.name = n;

this.sayNmae = function(){

console.log(this.name);

}

}

var obj1 = new Foo('michael'); // 创建对象obj1

obj1.name; // 访问类Foo的name属性

obj1.sayNmae() //调用函数

var obj2 = new Foo('jack'); // 创建对象obj2

obj2.name;

obj2.syaName();

上面创建了两个对象obj1和obj2,这样做看似没有问题,两个对象都会保存一份函数代码。但在javascript中不是这样的,在javascript中有原型。

8、类的原型

类的原型(prototype),使用类的原型在类外边定义方法,例如下面这样:

// 先创建一个类Foo

function Foo(n){

this.name = n;

}

// 定义类Foo的原型

Foo.prototype = {

'sayName': function(){

console.log(this.name)

}

}

var obj1 = new Foo('michael');

obj1.sayName() // 先去类中找sayName,类再去原型中找看有没有这个方法

var obj2 = new Foo('jack');

在javascript中原型可以认为是一个字典,键是方法名,值是方法。

9、JavaScript正则表达式

a. 定义正则表达式

/.../ 用于定义正则表达式

/.../g 表示全局匹配

/.../i 表示不区分大小写

/.../m 表示多行匹配

JS正则匹配时本身就是支持多行,此处多行匹配只是影响正则表达式^和$,m模式也会使用^$来匹配换行的内容)

var pattern = /^Java\w*/gm;

var text = "JavaScript is more fun than \nJavaEE or JavaBeans!";

result = pattern.exec(text)

result = pattern.exec(text)

result = pattern.exec(text)

注:定义正则表达式也可以 reg= new RegExp()

b. 匹配

JavaScript中支持正则表达式,其主要提供了两个功能:

test(string) 检查字符串中是否和正则匹配

n = 'uui99sdf'

reg = /\d+/

reg.test(n) ---> true

只要正则在字符串中存在就匹配,如果想要开头和结尾匹配的话,就需要在正则前后加 ^和$

exec(string) 获取正则表达式匹配的内容,如果未匹配,值为null,否则,获取匹配成功的数组。

非全局模式

获取匹配结果数组,注意:第一个元素是第一个匹配的结果,后面元素是正则子匹配(正则内容分组匹配)

var pattern = /\bJava\w*\b/;

var text = "JavaScript is more fun than Java or JavaBeans!";

result = pattern.exec(text) //输出如下:

["JavaScript", index: 0, input: "JavaScript is more fun than Java or JavaBeans!", groups: undefined]

var pattern = /\b(Java)\w*\b/;

var text = "JavaScript is more fun than Java or JavaBeans!";

result = pattern.exec(text) // 输出如下:

["JavaScript", "Java", index: 0, input: "JavaScript is more fun than Java or JavaBeans!", groups: undefined]

全局模式

需要反复调用exec方法,来一个一个获取结果,直到匹配获取结果为null表示获取完毕

var pattern = /\bJava\w*\b/g;

var text = "JavaScript is more fun than Java or JavaBeans!";

result = pattern.exec(text) // 输出:

["JavaScript", index: 0, input: "JavaScript is more fun than Java or JavaBeans!", groups: undefined]

var pattern = /\b(Java)\w*\b/g;

var text = "JavaScript is more fun than Java or JavaBeans!";

result = pattern.exec(text) // 输出:

["JavaScript", "Java", index: 0, input: "JavaScript is more fun than Java or JavaBeans!", groups: undefined]

c. 字符串中相关方法

obj.search(regexp) 获取索引位置,搜索整个字符串,返回匹配成功的第一个位置(g模式无效)

obj.match(regexp) 获取匹配内容,搜索整个字符串,获取找到第一个匹配内容,如果正则是g模式找到全部

obj.replace(regexp, replacement) 替换匹配替换,正则中有g则替换所有,否则只替换第一个匹配项,

$数字:匹配的第n个组内容;

$&:当前匹配的内容;

$`:位于匹配子串左侧的文本;

$':位于匹配子串右侧的文本

$$:直接量$符号

四、DOM,文档对象模型

把整个HTML当作一个对象来操作。对象还可以嵌套对象。

在DOM中动作可以分为两类:查找和操作

1、查找和操作

有直接查找和间接查找

直接查找:如:var obj = docment.getElementById('i1');

间接查找:

innerText,仅获取文本。

innerHTML,获取全部内容。

value,对于input标签来说:获取和修改input文本框的值。

value,对于select标签来说,获取和修改选中的value值。

对于select标签来说,还有一个特有属性selectedIndex,如:obj.selectedIndex

value对于textarea标签来说,value获取当前标签中的值。

当对innerText或innerHTML赋值的时候,标签下的全部内容都被修改成这一个值。

当赋值的是HTML代码时,就会有不同的情况,例如:

obj.innerText = "百度" //页面上只显示这个字符串

obj.innerHTML = "百度" //页面上显示百度两个字并且是超链接

在input标签中,value获取当前标签中的值。

现有下面HTML代码片断,如下所示,运行后在页面上显示python linux。此时进终端执行命令:

var obj = document.getElementById('i1'); // 获取id号为i1的标签

obj.innerText // 获取id号为i1的文本内容,输出是:"python linux"

python

linux

继续看下面HTML代码片断,下面代码与上面代码不同之处是在a标签内添加了span标签。此时通过终端获取文本内容。

代码片断是:

python

linux

HTML

根据上面的代码片断,在终端执行命令:

var obj = document.getElementById('i1'); // 获取id号为i1的标签

obj.innerText // 获取id号为i1的文本内容,输出是:"python linux HTML"

从上面的输出可以看出,innerText获取到的是标签id号为i1下面的所有文本内容。

此时执行命令:obj.innerHTML,会把对应标签id号为i1下面的所有内容都能拿到,包括标签。

obj.innerHTML的输出如下:"

python

linux

HTML

"

注意区分innerText和innerHTML获取到的内容的差别。

value和select用法举例,有下面HTML代码片断,value可修改input文本框的值,select可以修改选择的值。

python

linux

HTML

成都

北京

上海

在终端上进行操作:

运行上面代码后,在页面的文本框中输入内容"michael",此时可以通过value修改,方法如下:

obj = document.getElementById("i2"); //获取id号为i2的对象

obj.value // 获取值,输出是:michael

obj.value = "jack"; //修改文本框中的值,此时页面中文本框的内容是:jack

下面对选择框的对象进行操作

obj2 = document.getElementById("i3"); // 获取id为i3的对象

obj2.value // 输出默认是第一个option标签的value值,输出:11,选择框上选择的是:成都

obj2.value = 13; //修改选择框的值为13,此时选择框上选择的是:上海

obj2.selectedIndex // 获取选择框中的索引,由于上面选择了上海,此时输出是:2,默认是0开始。

obj2.selectedIndex = 0 //修改选择框的选项为0,即选择成都

对于textarea(可输入多行文本)标签的查找和修改操作方法,与上面的input和select标签一样。

有了上面的操作方法,下面做一个搜索框的示例,当鼠标不在搜索框中时,显示请“输入关键字”。

主要通过标签的两个属性来完成,就是移到焦点(onfocus)和移出焦点(onblur)。详细情况如下面代码所示。

function Focus() {

var tag = document.getElementById("i1");

var val = tag.value;

if(val == "请输入关键字"){

tag.value = "";

}

}

function Blur() {

var tag = document.getElementById("i1");

var val = tag.value;

if(val.length ==0){

tag.value = "请输入关键字";

}

}

在这段代码中,用到了DOM编程中方法,通过获取标称的id号,进而通过id号操作标签的value值。然后通过标签两个

属性移到焦点(onfocus)和移出焦点(onblur)调用对应的函数来完成这两个动作。

上面用了很长的一段代码实现的这个功能,其实在最新的浏览器中,可以用一句HTML语言完成,就是:

但是在老的浏览器不支持这样做。

2、DOM样式操作

通过className属性操作标签内的class属性值,达到修改样式的目的。

className

classList: classList.add, classList.remove

继续以上面的HTML代码片断为例,在终端上操作:

obj = document.getElementById('i1'); // 获取id号为i1的标签,obj输出是:

obj.className = 'c1 c2'; //给标签添加class属性并指定值,或者修改class属性的值

obj.classList; // 以列表方式输出标签内的class属性值,输出如下:

DOMTokenList(2) ["c1", "c2", value: "c1 c2"]

obj.classList.add('c3') // 给class列表再添加一个值c3

obj.classList; // 此时的输出如下:

DOMTokenList(3) ["c1", "c2", "c3", value: "c1 c2 c3"]

obj.classList.remove('c2') // 移除一个属性值c2

obj.classList; // 此时的输出如下:

DOMTokenList(2) ["c1", "c3", value: "c1 c3"]

在上面对class属性值进行操作时,操作的最小对象是一个样式的集合。还可以通过对象的style属性进行单个样式的

操作。例如下面这样:

obj.style.fontSize = '16px'; //给标签添加一个字体大小样式

obj.style.color = 'red'; //设置字体颜色为红色

obj.style.backgroundColor = 'green'; //设置背景颜色

这里要注意一的点是在CSS和JavaScript中,对样式字母的写法表示:

在CSS中:设置字体是font-size,在JS中是:fontSize。

在CSS中:设置背景色是background-color,在JS中是:backgroundColor。

3、属性操作

给某个标签添加属性和删除属性,使用到的方法是setAttribute(), removeAttribute()。

现在假设有obj变量,内容如下所示:

现在给这个变量对应的标签添加属性:

obj.setAttribute('nm', 'michael'); //添加属性nm,值是michael,参数是键值对

obj // 此时obj的输出如下所示:

obj.removeAttribute('value'); //删除标签的value属性

obj // 此时obj的输出如下所示:

obj.attributes // 获取标签所有的属性,以字典的形式返回

NamedNodeMap {0: id, 1: onfocus, 2: onblur, 3: type, 4: nm, id: id, onfocus: onfocus, onblur: onblur, type: type, nm: nm, …}

上面说了3个常用的属性操作,分别是:attributes, setAttribute, removeAttribute。

4、创建标签操作,并添加到HTML中

第一种创建标签方式:使用字符串方式。通过使用对象的insertAdjacentHTML就去添加,代码示例如下:

function AddEle() {

// 创建一个标签

var tag = "


"

// 将标签添加到i1里面

document.getElementById('i1').insertAdjacentHTML('beforeEnd', tag)

}

运行上面的代码,在页面上有一个"++"的按钮,点一次添加一个input标签。代码中的


是分割线。当然也可以

把这上


标称换成想要的标签,以达到不同的目的。

在这条语句document.getElementById('i1').insertAdjacentHTML('beforeEnd', tag)的insertAdjacentHTML

的第一个参数有选项4个:beforeBegin, afterBegin, beforEnd, afterEnd

第二种创建标签的方式,通过对象去创建,代码示例如下:

function AddEle() {

// 创建一个input标签

var tag = document.createElement("input"); //让document帮助创建标签

tag.setAttribute('type', 'text'); // 添加属性

tag.style.fontSize = '20px'; // 添加样式

tag.style.color = 'red'; // 设置颜色

//创建一个p标签,并将input标签包含在p标签内部

var p = document.createElement('p');

p.appendChild(tag);

// 将标签添加到i1里面

document.getElementById('i1').appendChild(p);

}

在上面代码中,在函数AddEle()创建了两个标签,并对input标签创建了样式。还可以设置样式中其它各种属性。这里首先通过var tag = document.createElement("input");创建input标签,紧接着对这个标签对象设置属性和样式。接着又通过var p = document.createElement('p');创建了p标签,然后使用p.appendChild(tag);方法将input标签添加到p标签内部。后面通过document.getElementById('i1').appendChild(p);方法获取id号为i1的标签,并在其后面添加一个子标签p。这样就完成了点击页面上的“++”按钮自动添加标签功能。

5、DOM提交表单操作

之前提交表单是通过form标签的input标签中的type="submit"值提交的。其实在div标签中也可以提交表单。

在div标签中添加onclick事件,通过调用js方法提交。代码片断如下所示:

确定

function submitForm() {

document.getElementById("f1").submit();

}

在上面的代码中,在div标签内添加了onclick属性,它的值是一个函数。在这个函数中使用DOM的submit()方法实现提交表单。其实任何标签通过DOM都可以提交表单。

6、DOM其它操作

console.log 输出框(终端输出)

alert 弹出框(弹窗)

confirm 确认框,例如:

var a = confirm("确定要提交?"); // 当添加到某个标签的提交事件中,点击提交时会弹出确认框,当

点击确定时a的值是true,点击取消时,a的值是false。可输出该值进行验证。

console.log(a); // 输出a值

// URL和刷新

location.href 获取当前URL

location.href = "url" 设置当前URL,重定向,跳转

location.reload() 重新加载,页面刷新,与下面的这个命令是一样的效果:

location.href = location.href

// 定时器

setInterval 多次定时器,参数可以是函数。定时器一直执行。

clearInterval 清除多次定时器

setTimeout 单次定时器,到达设定的时间才去执行。

clearTimeout 清除单次定时器

var obj = setInterval(function(){

console.lgo(1);

//clearInterval(obj); //清除操作放在函数内部。

}, 1000);

clearInterval(obj);

上面代码中obj是定时器对象,clearInterval(obj)清除这个obj定时器。这个清除操作也可以放在函数内部。

下面代码的意思是说到达第二个参数设定的时间5秒(5000毫秒),就去执行第一个参数。只执行一次。

setTimeout(function(){

console.log('timeout');

}, 5000);

var t = setTimeout(function(){}, 5000) //设置一个定时器

clearTimeout(t) // 删除一个定时器

定时器举例,在页面上有一删除按钮,当点这个按钮后,在页面上显示“已删除”三个字5秒,5秒过后就消失。代码片断如下所示:

function DeleteEle() {

document.getElementById("status").innerText = "已删除";

setTimeout(function () {

document.getElementById("status").innerText = "";

}, 5000)

}

7、DOM事件

前面用过的事件有:onclick, onblur, onfocus

下面写一个页面,要求做到行为,样式,结构,相互分离。行为就是js,样式就是css,结构就是HTML,它们之间要相互分离。代码片断如下所示。

#test{

background-color: indianred;

width: 300px;

height: 400px;

}

python

var mydiv = document.getElementById("test")

// console.log(mydiv)

mydiv.onclick = function () {

console.log('hello')

}

上面这段简短的代码就实现了行为、样式、结构相互分离的功能。

现在假设有这个需求,在页面上有一个表格,将鼠标移到某一行,访行就高亮显示,移出鼠标后就恢复原样显示。代码片断如下所示,下面代码中使用了两个事件:onmouseover(鼠标移到上面),onmouseout(鼠标移出)。

123
123
123

function t1(n) {

var myTrs = document.getElementsByTagName("tr")[n]

// console.log(myTrs) //输出看下myTrs是什么

myTrs.style.backgroundColor = "yellow"

}

function t2(n) {

var myTrs = document.getElementsByTagName("tr")[n]

myTrs.style.backgroundColor = ''

}

上面这个代码可以实现当鼠标移到某一行就高亮显示,鼠标移出就恢复原来的颜色。但上面的代码中,在每一行都添加了onmouseover,onmouseout两个事件,当这个表格有成千上万行就不能这样做了。

下面使用另外一种方式来实现,先用DOM的方法获取表格的标签再进行相应的操作。代码如下所示。在这个代码片断中使用了this关键字,这里的this关键字的意思是谁调用这个函数,this就指向谁,进而对谁进行操作。

123
123
123

var myTrs = document.getElementsByTagName("tr");

var len = myTrs.length;

for(var i=0;i

myTrs[i].onmouseover = function () { // 定义了匿名函数

this.style.backgroundColor = 'red'; // 这里的this意思是:谁调用这个匿名函数,this就指向谁。

}

}

for(var i=0;i

myTrs[i].onmouseout = function () { // 定义了匿名函数

this.style.backgroundColor = ''; // 这里的this意思是:谁调用这个匿名函数,this就指向谁。

}

}

在上面代码中的这一行this.style.backgroundColor = 'red';,把this换成myTrs[i]不能执行,是因为作用域的问题。因为循环结束后还没有触发相应的事件,而i的值已经是最后一个了。

从上面的代码可以看出,绑定事件的两种方式:

a. 直接标签中的onclick属性绑定,例如:οnclick="xxx();", onfocus等

b. 先获取DOM对象,然后进行绑定,例如:

document.getElementById('xx').onclick

document.getElementById('xx').onfocus

this关键字:当前触发事件的标签

a. 第一种绑定方式,在标签中通过事件绑定,参数传递的是this

function ClickOn(self){

// self 当前点击的标签

}

b. 第二种绑定方式,通过DOM方法获取标签ID号,进而对该标签添加onclick事件及动作

document.getElementById("i1").onclick = function(){

// this 代指当前点击的标签

}

c. 第三种绑定方式,同一个事件绑定多个方法,采用addEventListener方法。

addEventListener方法有三个参数:第一个是事件,第二个是对应事件的操作,第三个是false和true。

当第三个参数是false时是冒泡模型,为true时是捕捉模型

mydiv.addEventListener('click',function(){console.log('hello')}, false)

mydiv.addEventListener('click',function(){console.log('python')}, false)

第三种绑定方式完整例子,代码片断如下所示。

#main{

background-color: red;

width: 300px;

height: 400px;

}

#content{

background-color: pink;

width: 150px;

height: 200px;

}

var mymain = document.getElementById('main');

var mycontent = document.getElementById('content');

//第三个参数是false是冒泡模型,即点击第二个div的区域时,终端先输出content,后输出main.

//点击第一个div的区域时,只输出main

//mymain.addEventListener('click',function(){console.log('main')},false);

//mycontent.addEventListener('click',function(){console.log('content')},false);

// 当第三个参数是true时,点击第二个div的区域时,先输出main,后输出content。

//点击第一个div的区域时,只输出main

mymain.addEventListener('click',function(){console.log('main')},true);

mycontent.addEventListener('click',function(){console.log('content')},true);

在上面的代码中,addEventListener方法的第三个参数是fasle时是冒泡模型,即点击第二个div标签事件先触发,第一个div标签事件后触发。当第三个参数是true是,是捕捉模型,即当点击第二个div标签时第一个div标签的事件先触发,第二个div标签的事件后触发。两种方式中,当点击第一个div标签时,只触发第一个标签的事件,不触发第二个标签的事件。

例题:下面代码获取某个网站的所有div标签,然后将div标签的内容清空。代码如下所示。

tag = document.getElementsByTagName('div');

len = tag.length;

for(var i=0;i

tag[i].onmouseover = function () {

this.innerText = '';

}

}

具体事件大致有这些:

属性 此事件发生在何时

onabort 图像的加载被中断

oublur 元素失去焦点

onchange 域的内容被改变

onclick 当用户点击某个对象时调用的事件句柄

ondblclick 当用户双击某个对象时调用的事件句柄

onerror 当加载文档或图像时发生错误

onfocus 元素获得焦点

onkeydown 某个键盘按键被按下

onkeypress 某个键盘按键被按下并松开

onkeyup 某个键盘按键被松开

onload 一张页面或一幅图像完成加载

onmousedown 鼠标按钮被按下

onmousemove 鼠标被移动

onmouseout 鼠标从某元素移开

onmouseover 鼠标移到某元素之上

onmouseup 鼠标按键被松开

onreset 重置按钮被点击

onresize 窗口或框架被重新调整大小

onselect 文本被选中

onsubmit 确认按钮被点击

onunload 用户退出页面

8、JavaScript函数调用分析

在JS中函数调用之前会进行词法分析,词法分析过程中会有一个活动对象(Active Object,简称AO)。在词法分析过程中,有果有变量名重复的会以最后一个变量为活动对象。在调用时就处于调用阶段,就会根据词法分析过程的最新变量去执行。例如下面代码所示。

function t1(age) {

console.log(age); //执行这条语句时,会从活动对象上去找,所以输出是函数:ƒ age() {}

var age = 20; // 由于在执行阶段,这里会覆盖上一个age

console.log(age); // 20

function age() {} // 由于在执行阶段,这个函数没有调用,直接通过

console.log(age); // 20,由于age没有改变,这里还是输出20

}

t1(5); //调用函数

在上面代码中,t1(5);是在调用函数,并且给函数传递一个参数5,这个函数在定义时确实有一个形式参数。但在这个t1()函数被调用之前会先进行词法分析,词法分析过程中有一个活动对象(Active Object,简称AO)。下面来看下这个分析过程,分析过程分为三步进行:

1. 形式参数;

2. 局部变量;

3. 函数声明表达式。

根据上面三个步骤,在t1(5);调用函数前,先对函数进行词法分析,即是下面这样:

1. 形式参数分析,此时有形式参数age,分析得到的结果是:

AO.age = undifined; 但在调用函数时有传参数,所以

AO.age = 3;

2. 局部变量分析,接下对函数内定义的局部变量进行分析,由于在函数中定义了局部变量age,函数还是执行阶段,所以

AO.age = undifined;

3. 函数声明表达式分析,在上面代码中,在t1()函数内部定义了一个空函数age(),所以

AO.age = ƒ age() {};

经过了上面的函数记法分析过程,接下来就是调用函数,在调用函数时,活动对象AO.age = ƒ age() {};所以函数中第一个console.log(age)的输出是:ƒ age() {}。此时函数内部有同名的局部变量age,并且age=20。所以第二个console.log(age)的输出是:20。接下执行到函数:function age(){},由于该函数未被调用,所以直接通过,此时age的值仍然是20。所以到第三个console.log(age)输出仍然是:20。所以最终的输出是:

ƒ age() {}

20

20

例如下面这个函数,利用上面的词法分析过程就可以理解,在函数调用时,输出是undifined。

function t2(){

console.log(name);

var name = 'python';

}

t2(); //调用函数,输出是:undifined

前端学习:

多写,多练,HTML标签、CSS属性、JS方法等不一定要全记住,但常用的要记住。当要使用某个标签时记不住,就多查手册。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值