这一篇记录一下DOM、jQuery以及Vue的东西。

DOM

DOM(Document Object Model)是JS操作网页的接口,脚本可以对其进行各种操作(比如增删改内容)。浏览器会根据DOM模型,将结构化文档(比如HTML和XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构都有对外接口。浏览器解析HTML文档并形成DOM的过程类似于编译器解析源代码并生成抽象语法树的过程,也是进行词法分析和语法分析。而DOM中的树形结构关系通过对象的嵌套来实现的。比如document是根节点,这个对象下面有body键,值则为body对象。

节点

DOM的最小组成单位叫做节点(node)。文档的树形结构(DOM树),就是由各种不同类型的节点组成。比如:

  • Document:整个文档树的根节点
  • DocumentType:doctype标签(比如<!DOCTYPE html>)
  • Element:网页的各种HTML标签(比如<body>、<a>等)
  • Text:标签之间或标签包含的文本
  • Comment:注释

每一个节点都是一个JS对象,会有一些内置的方法,比如innerHTML、getAttribute等。上面的几种节点类型则是不同的类,它们都继承于Node类,所以这些对象会有共同和不同的操作方法。

节点树

DOM
浏览器原生提供document节点,代表整个文档。其实写HTML代码就能感受出来每个标签元素之间的层次结构,DOM树中的父子关系跟这种层次结构式是类似的。

JS操纵网页

JS通过以下方式来获取DOM中的节点

1
2
3
var x = document.getElementById("test1");//查找id为test1的元素
var y = document.getElementsByTageName("p");//查找标签名为p的元素
var z = document.getElementsByClassName("test2");//查找类名为test2的元素

拿到节点后,则可以调用节点的方法和属性

  • 操纵html:
    • document.write() 直接向HTML输出流写内容。
    • document.getElementById("test1").innerHTML="new text" 修改id为test1的元素的HTML文本
    • document.getElementById("test1).atrribute="new attrValue 修改id为test1的元素的某一属性值
  • 操纵css,跟上面是一样的,style也是一种属性。
    • document.getElementById(test1).style.property=new style 修改id为test1的元素的某一样式

DOM事件

上面的JS代码是对HTML直接进行增删改,而如果想添加一个触发条件,这个条件可以是一个HTML事件,比如:点击鼠标、按下键盘等等。在DOM中,每个节点是一个JS对象,对象拥有一些预定义的属性,包括用于事件处理的属性,如onclick, onmouseover, onload等,通过将这些事件属性设置为函数来响应事件。写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
function changeText(id){
id.innerHTML="new text";
}
</script>
</head>
<body>
<div id="test" onclick="changeText(this)">old text</div>
<div onclick="document.write('new')">old</div>
</body>
</html>

还有另一种更为灵活的方式:element.addEventListener(event, function, useCapture); 其中event为绑定的事件(onclick……),function为响应函数,useCature用于指定是冒泡还是捕获,false为冒泡,true为捕获。这种方式允许向同一个元素添加多个事件,且不会覆盖已存在的事件,即对于同一事件,可以有多个响应函数。对于外层div内层p的嵌套关系,假如两个标签都绑定有onclick事件的响应函数,点击p标签的文本时,若为捕获则先执行外层响应函数后执行内层响应函数,若为冒泡则顺序相反。

removeEventListener(event,function)用来移除事件与响应函数的绑定关系。

jQuery

write less,do more
jQuery是一个JavaScript函数库,使用时可以本地引入或网址url引入(放在head部分),比如谷歌的:http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js。
基本语法:$(selector).action()

  • 美元符号定义jQuery
  • 选择符(selector)“查询”和“查找” HTML 元素
  • jQuery的action()执行对元素的操作

Jquery操作多用以下形式:

1
2
3
$(document).ready(function(){
//……
});

这是为了防止文档在完全加载(就绪)之前运行jQuery代码。如何选择HTML元素?

1
2
3
4
$("tagName") $(".className") $("#idname") $("[attribute]")
// 也可将上面三种写法组合起来,达到“并”的效果
// 对于有多个满足要求的HTML元素,可以用:first来指定第一个xx元素
// eg:$("p:last") 最后一个p标签对应的元素

具体使用例子:

  • $(document).ready(function) //将函数绑定到文档的就绪事件(当文档完成加载时)
  • $(selector).click(function) //触发将函数绑定到被选元素的点击事件
  • $(selector).dblclick(function) //触发将函数绑定到被选元素的双击事件

总结:jQuery操作其实就是使得原生JS操作DOM更加简单和方便,通过$来选择DOM元素,同时内嵌了一系列的事件和效果。效果函数也有挺多,比如淡出效果fadeOut。不列举了,之后需要再即查即用。text()、html()等方法可以在选择元素后拿到原始文本内容或者html标签内容。比如$(“p:first”).html()即返回第一个p标签的html文本

Vue

官方文档

想单独写一篇来学Vue来着,结果发现跟着官网或者菜鸟教程效果会更好一些。学了点Vue的东西,慢慢体会到响应式框架的含义了。用下面的例子来说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello-Vue</title>
<script src="https://cdn.staticfile.org/vue/3.2.36/vue.global.min.js"></script>
</head>
<body>
<div id="app" class="demo">
<img v-bind:src="imageSrc">
{{message}}<!--文本插值-->
</div>
<script>
const HelloVueApp = {
data() {
return {
imageSrc: 'example.com/example.png',
message: 'hello vue!'
}
}
}
Vue.createApp(HelloVueApp).mount('#app')
</script>
</body>
</html>

上边代码中把img标签的src属性跟imageSrc变量绑定在一起,当imageSrc变量被JS修改时,src属性值也会相应进行修改,这就是Vue响应式的特点。同样的,message是嵌入HTML中的一个文本字符串,发生改变时显示的内容也会随之改变,Vue应用动态地响应数据的变化,并负责将数据的变化反映到视图上。

  • v-bind用于绑定属性值,v-bind:attrName=”attrValue”
  • v-on用于绑定事件,比如v-on:click=”handleFunction”
  • v-show用于绑定是否显示该标签内容
  • v-if用于分支控制,若v-if=”varName”,varName为true则显示,为false则隐藏

Vue的组件,就是将HTML、CSS和JS封装在一起的一个.vue文件,可以扩展HTML元素,封装可重用的代码,跟函数有一点像。使用组件需要创建一个实例。且组件里也可以使用组件,被使用的为子组件,所以一个页面就是一个组件树。

Node.js

简单说 Node.js 就是运行在服务端的 JavaScript,不支持传统js中DOM和BOM的操作,基于Google的V8引擎。具体运用:

1
console.log("hello world");

将上面代码存为helloworld.js文件,终端运行命令:

1
node helloworld.js

输出即可得到结果 hello world

传统php+Apache/Nginx的后端模式中,需要Apache或者Nginx来处理服务器接收到的HTTP请求。而在Nodejs中需要用js代码实现这样的功能。Nodejs应用三部分:

  • require 指令:在 Node.js 中,使用 require 指令来加载和引入模块,引入的模块可以是内置模块,也可以是第三方模块或自定义模块。
  • 创建服务器:服务器可以监听客户端的请求,类似于 Apache 、Nginx 等 HTTP 服务器。
  • 接收请求与响应请求:服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。
1
const module = require('module-name');

用于导入所需模块,module-name为文件路径或模块名。简单的Nodejs应用举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var http = require('http');
http.createServer(function (request, response) {

    // 发送 HTTP 头部
    // HTTP 状态值: 200 : OK
    // 内容类型: text/plain
    response.writeHead(200, {'Content-Type': 'text/plain'});

    // 发送响应数据 "Hello World"
    response.end('Hello World\n');
}).listen(8888);//监听8888端口

// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');

npm

npm是Nodejs的包管理工具,可用以下命令安装需要导入的模块:

1
npm install ModuleName

安装好之后,模块就放在了工程目录下的node_modules目录中,因此在代码中只需要通过require(‘ModuleName’)的方式导入即可。安装分为全局和本地安装,区别在于npm install (-g),全局的方式则安装在系统集中的位置,本地安装则位于项目本地目录下。package.json位于模块的目录下,用于定义包的属性,包含包的基本信息。

1
2
npm uninstall ModuleName # 卸载模块
npm update ModuleName # 更新模块

个人也可以创建并发布模块,之后供其他用户使用。总的来说,通过npm导入模块,就是向Nodejs的官方注册表(一个集中的源代码库)发送请求,拿到模块的源代码;而发布自己的模块则是将源代码加入代码库中。