- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
先做个自我介绍,本人是一个没人写前端所以就自学前端的后端程序员🙇。在此项目中我会和大家一起从零基础开始学习前端,从后端程序员的视角来看前端,受限于作者的水平本项目暂时只会更新到前端框架VUE,不会涉及node.js。该项目适合零基础的小白或者和我一样开发网站没人写前端所以自学前端的后端程序员😂。
该项目的学习顺序是按照我自己学习时总结出来的,其中的每个知识点都是我认真去理解的,同时也查了很多的资料,所有的参考资料我都放在了文章末尾。尊重开源,尊重知识产权。每一个案例我都亲手写过并觉得不错才放上去的。每次的代码和笔记我都放在了开源仓库里,有需要的同学请不要吝啬给我一个star。如果觉得本文写的不错的话记得点赞+关注,你们的支持是我坚持下去的动力😃。
风急天高猿啸哀,渚清沙白鸟飞回。
无边落木萧萧下,不尽长江滚滚来。
万里悲秋常作客,百年多病独登台。
艰难苦恨繁霜鬓,潦倒新停浊酒杯。
——杜甫《登高》
语雀地址:https://www.yuque.com/beilayanmen
Github地址:https://github.com/SuZui-cn/my-web
Gitee地址:https://gitee.com/north_gate/my-web
个人博客地址:https://foollyone.cn/
DOM介绍
获取节点
通过ID获取
用类名获取
用CSS选择器获取
用name属性获取
用标签获取
获取属性
获取元素内容
获取表单数据
创建节点
插入节点
删除节点
事件
轮播图案例
在本节中会学习如何使用DOM,也就是用js操作标签和属性,还是一样的,学计算机就要多写代码。所以再次建议大家多写代码。
先来介绍一下什么是DOM。
文档对象模型(DOM)是表示和操作HTML和XML文档内容的基础API。API不是特别复杂,但是需要理解大量的架构细节。首先,应该理解HTML或XML文档的嵌套元素在DOM树对象中的表示。HTML文档的树状结构包含表示HTML标签或元素(如、
)和表示文本字符串的节点,它也可能包含表示HTML注释的节点。
——弗兰纳根《JavaScript权威指南》
节点演示如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>网页标题</title>
</head>
<body>
<h1>这是一级标题</h1>
<p>这里<i>是</i>段落</p>
</body>
</html>
我们把上面的代码转换成树状图,如下图:
在上面的图中,每个方框是文档的一个节点,它表示一个Node对象。同时,上图包含了3种不同类型的节点。树形的根部是Document节点,它代表整个文档。代表HTML元素的节点是Element节点,代表文本的节点是Text节点。Document、Element和Text是Node的子类,在第四部分中它们有自己的条目。Document和Element是两个重要的DOM类,本章大部分内容将阐述它们的属性和方法。
注意,通用的Document和Element类型与HTMLDocument和HTMLElement类型之间是有严格的区别的。Document类型代表一个HTML或XML文档,Element类型代表该文档中的一个元素。HTMLDocument和HTMLElement子类只是针对于HTML文档和元素。
在一个节点之上的直接节点是其父节点,在其下一层的直接节点是其子节点。在同一层上具有相同父节点的节点是兄弟节点。在一个节点之下的所有层级的一组节点是其后代节点。一个节点的任何父节点、祖父节点和其上层的所有节点是祖先节点。
文档节点的部分层次结构图:
大多数客户端JavaScript程序运行时总是在操作一个或多个文档元素。当这些程序启动时,可以使用全局变量document来引用Document对象。但是,为了操作文档中的元素,必须通过某种方式获得或选取这些引用文档元素的Element对象。DOM定义许多方式来选取元素,查询文档的一个或多个元素有如下方法:
任何HTML元素可以有一个id属性,在文档中该值必须唯一,即同一个文档中的两个元素不能有相同的ID。可以用Document对象的getElementById()方法选取一个基于唯一ID的元素。
pass:在使用getElementById()
方法的时候里面的参数不需要加#
。
HTML元素的class属性值是一个以空格隔开的列表,可以为空或包含多个标识符。它描述一种方法来定义多组相关的文档元素:在它们的class属性中有相同标识符的任何元素属于该组的一部分。在JavaScript中class是保留字,所以客户端JavaScript使用className属性来保存HTML的class属性值。class属性通常与CSS样式表一起使用,对某组内的所有元素应用相同的样式。
CSS选择器可以使用下面的方法选取元素:通过ID、名字、标签名和类名。与CSS3选择器的标准化一起的另一个称做“选择器API”的W3C标准定义了获取匹配一个给定选择器的元素的JavaScript方法。该API的关键是Document方法querySelectorAll()。它接受包含一个CSS选择器的字符串参数,返回一个表示文档中匹配选择器的所有元素的NodeList对象。与前面描述的选取元素的方法不同,querySelectorAll()返回的NodeList对象并不是实时的:它包含在调用时刻选择器所匹配的元素,但它并不更新后续文档的变化。如果没有匹配的元素,querySelectorAll()将返回一个空的NodeList对象。如果选择器字符串非法,querySelectorAll()将抛出一个异常。
除了querySelectorAll(),文档对象还定义了querySelector()方法。与querySelectorAll()的工作原理类似,但它只是返回第一个匹配的元素(以文档顺序)或者如果没有匹配的元素就返回null。
pass:CSS定义了“:first-line”和“:first-letter”等伪元素。在CSS中,它们匹配文本节点的一部分而不是实际元素。如果和querySelectorAll()或querySelector()一起使用它们是不匹配的。而且,很多浏览器会拒绝返回“:link”和“:visited”等伪类的匹配结果,因为这会泄露用户的浏览历史记录。
HTML的name属性最初打算为表单元素分配名字,在表单数据提交到服务器时使用该属性的值。类似id属性,name是给元素分配名字,但是区别于id,name属性的值不是必须唯一:多个元素可能有同样的名字,在表单中,单选和复选按钮通常是这种情况。而且,和id不一样的是name属性只在少数HTML元素中有效,包括表单、表单元素、和元素。基于name属性的值选取HTML元素,可以使用Document对象的getElementsByName()方法。
getElementsByName()定义在HTMLDocument类中,而不在Document类中,所以它只针对HTML文档可用,在XML文档中不可用。它返回一个NodeList对象,后者的行为类似一个包含若干Element对象的只读数组。在IE中,getElementsByName()也返回id属性匹配指定值的元素。为了兼容,应该小心谨慎,不要将同样的字符串同时用做名字和ID。
Document对象的getElementsByTagName()方法可用来选取指定类型(标签名)的所有HTML或XML元素。例如,如下代码,在文档中获得包含所有元素的只读的类数组对象:
HTML元素由一个标签和一组称为属性(attribute)的名/值对组成。例如,<a>元素定义了一个超链接,它的href属性值作为链接的目的地址。HTML元素的属性值在代表这些元素的HTMLElement对象的属性(property)中是可用的。DOM还定义了另外的API来获取或设置XML属性值和非标准的HTML属性。
比如下面的获取图片标签的属性。
在DOM中我们可以通过innerHTML
或者 innerText
来获取内容。操作如下:
同时我们也可以使用这两个属性给标签设置内容,但是我们需要知道这两个属性在设置内容上的区别,innerHTML
如果设置的内容含有标签的话会渲染,而 innerText
则不会渲染。
具体如下:
我们可以使用value
属性来获取表单的数据。
具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<form>
用户名:<input type="text" name="username" />
<br />
密码:<input type="password" name="password" />
<br>
性别:<input type="radio" name="sex" value="男">男</input>
<input type="radio" name="sex" value="女">女</input>
<br>
<input type="button" onclick="show()" value="提交">
</form>
<script>
function show(){
var username = document.getElementsByName("username")[0]
var password = document.getElementsByName("password")[0]
var man = document.getElementsByName("sex")[0]
var woman = document.getElementsByName("sex")[1]
console.log(username.value)
console.log(password.value)
// 对于单选框我们需要使用checked属性来判断是否选中,
// 选中时checked返回为真,反之为假。
if (woman.checked){
console.log("女")
}else if(man.checked){
console.log("男")
}
}
</script>
</body>
</html>
创建新的Element节点可以使用Document对象的createElement()方法。给方法传递元素的标签名:对HTML文档来说该名字不区分大小写。
让我们来看一个案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<ul>
<li>123</li>
</ul>
<script>
// 1. 创建节点元素节点
var li = document.createElement('li');
// 2. 添加节点 node.appendChild(child) node 父级 child 是子级 后面追加元素 类似于数组中的push
var ul = document.querySelector('ul');
ul.appendChild(li);
// 3. 添加节点
var lili = document.createElement('li');
</script>
</body>
</html>
具体效果如下:
我们再来看一个留言发布的案例
具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
}
textarea {
width: 200px;
height: 100px;
border: 1px solid pink;
outline: none;
resize: none;
}
ul {
margin-top: 50px;
}
li {
width: 300px;
padding: 5px;
background-color: rgb(245, 209, 243);
color: red;
font-size: 14px;
margin: 15px 0;
}
</style>
</head>
<body>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul></ul>
<script>
// 1. 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2. 注册事件
btn.onclick = function () {
if (text.value == '') {
alert('您没有输入内容');
return false;
} else {
// console.log(text.value);
// (1) 创建元素
var li = document.createElement('li');
// 先有li 才能赋值
li.innerHTML = text.value;
// (2) 添加元素
ul.appendChild(li);
}
};
</script>
</body>
</html>
在上面插入节点的案例上,我们来引入删除节点。点击删除的时候,留言的内容会被删除掉。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
padding: 100px;
}
textarea {
width: 200px;
height: 100px;
border: 1px solid pink;
outline: none;
resize: none;
}
ul {
margin-top: 50px;
}
li {
width: 300px;
padding: 5px;
background-color: rgb(245, 209, 243);
color: red;
font-size: 14px;
margin: 15px 0;
}
li a {
float: right;
}
</style>
</head>
<body>
<textarea name="" id=""></textarea>
<button>发布</button>
<ul></ul>
<script>
// 1. 获取元素
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
// 2. 注册事件
btn.onclick = function () {
if (text.value == '') {
alert('您没有输入内容');
return false;
} else {
// console.log(text.value);
// (1) 创建元素
var li = document.createElement('li');
// 先有li 才能赋值
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
// (2) 添加元素
// ul.appendChild(li);
ul.insertBefore(li, ul.children[0]);
// (3) 删除元素 删除的是当前链接的li 它的父亲
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
// node.removeChild(child); 删除的是 li 当前a所在的li this.parentNode;
ul.removeChild(this.parentNode);
};
}
}
};
</script>
</body>
</html>
事件本身并不是一个需要定义的技术名词。简而言之,事件就是Web浏览器通知应用程序发生了什么事情。
常见的事件:
我们之前使用到的onclick
就是点击事件。接下来我们用两个案例来介绍一下事件。
当我们在浏览器按下键盘的s
的时候会聚焦到输入框中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<input type="text" />
<script>
// 核心思路: 检测用户是否按下了s 键,如果按下s 键,就把光标定位到搜索框里面
// 使用键盘事件对象里面的keyCode 判断用户按下的是否是s键
// 搜索框获得焦点: 使用 js 里面的 focus() 方法
var search = document.querySelector('input');
document.addEventListener('keyup', function (e) {
// console.log(e.keyCode);
if (e.keyCode === 83) {
search.focus();
}
});
</script>
</body>
</html>
第二个案例:当我们在输入框里输入内容的时候,上方会出现一个文本框,里面输出我们输入的内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="请输入您的快递单号" class="jd" />
</div>
<script>
// 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
// 表单检测用户输入: 给表单添加键盘事件
// 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
// 如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
jd_input.addEventListener('keyup', function () {
// console.log('输入内容啦');
if (this.value == '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
});
// 当我们失去焦点,就隐藏这个con盒子
jd_input.addEventListener('blur', function () {
con.style.display = 'none';
});
// 当我们获得焦点,就显示这个con盒子
jd_input.addEventListener('focus', function () {
if (this.value !== '') {
con.style.display = 'block';
}
});
</script>
</body>
</html>
我这里写的轮播图的原理就是把图片水平排列,设置一个展示区域,区域以外设为不可见,然后水平平移图片。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
* {
margin: 0;
padding: 0;
}
.total {
height: 250px;
width: 655px;
overflow: hidden;
}
#banner {
height: 250px;
width: 3275px;
}
li {
float: left;
width: 655px;
height: 250px;
list-style: none;
}
img {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="total">
<ul id="banner">
<li><img src="lunbo1.jpg" /></li>
<li><img src="lunbo2.jpg" /></li>
<li><img src="lunbo3.png" /></li>
<li><img src="lunbo4.png" /></li>
<li><img src="lunbo1.jpg" /></li>
</ul>
</div>
<script>
var curindex = 0;
var maxlen =
document.getElementById('banner').getElementsByTagName('li').length - 1;
var timer = null;
timer = setInterval(change_auto, 1000);
function change_auto() {
if (curindex < maxlen) {
curindex++;
get_next();
} else {
curindex = 0;
get_reset();
}
}
var width = 655;
function get_next() {
var totalbanner = document.getElementById('banner');
totalbanner.style.marginLeft = '-' + width * curindex + 'px';
totalbanner.style.transition = 0.3 + 's';
}
function get_reset() {
var totalbanner = document.getElementById('banner');
totalbanner.style.marginLeft = '0px';
totalbanner.style.transition = '0s';
}
</script>
</body>
</html>
我正在努力做到这一点 在我的操作中从数据库获取对象列表(确定) 在 JSP 上打印(确定) 此列表作为 JSP 中的可编辑表出现。我想修改然后将其提交回同一操作以将其保存在我的数据库中(失败。当我使用
我有以下形式的 Linq to Entities 查询: var x = from a in SomeData where ... some conditions ... select
我有以下查询。 var query = Repository.Query() .Where(p => !p.IsDeleted && p.Article.ArticleSections.Cou
我正在编写一个应用程序包,其中包含一个主类,其中主方法与GUI类分开,GUI类包含一个带有jtabbedpane的jframe,它有两个选项卡,第一个选项卡包含一个jtable,称为jtable1,第
以下代码产生错误 The nested query is not supported. Operation1='Case' Operation2='Collect' 问题是我做错了什么?我该如何解决?
我已经为 HA redis 集群(2 个副本、1 个主节点、3 个哨兵)设置了本地 docker 环境。只有哨兵暴露端口(10021、10022、10023)。 我使用的是 stackexchange
我正在 Desk.com 中构建一个“集成 URL”,它使用 Shopify Liquid 模板过滤器语法。对于开始日期为 7 天前而结束日期为现在的查询,此 URL 需要包含“开始日期”和“结束日期
你一定想过。然而情况却不理想,python中只能使用类似于 i++/i--等操作。 python中的自增操作 下面代码几乎是所有程序员在python中进行自增(减)操作的常用
我需要在每个使用 github 操作的手动构建中显示分支。例如:https://gyazo.com/2131bf83b0df1e2157480e5be842d4fb 我应该显示分支而不是一个。 最佳答
我有一个关于 Perl qr 运算符的问题: #!/usr/bin/perl -w &mysplit("a:b:c", /:/); sub mysplit { my($str, $patt
我已经使用 ArgoUML 创建了一个 ERD(实体关系图),我希望在一个类中创建两个操作,它们都具有 void 返回类型。但是,我只能创建一个返回 void 类型的操作。 例如: 我能够将 book
Github 操作仍处于测试阶段并且很新,但我希望有人可以提供帮助。我认为可以在主分支和拉取请求上运行 github 操作,如下所示: on: pull_request push: b
我正在尝试创建一个 Twilio 工作流来调用电话并记录用户所说的内容。为此,我正在使用 Record,但我不确定要在 action 参数中放置什么。 尽管我知道 Twilio 会发送有关调用该 UR
我不确定这是否可行,但值得一试。我正在使用模板缓冲区来减少使用此算法的延迟渲染器中光体积的过度绘制(当相机位于体积之外时): 使用廉价的着色器,将深度测试设置为 LEQUAL 绘制背面,将它们标记在模
有没有聪明的方法来复制 和 重命名 文件通过 GitHub 操作? 我想将一些自述文件复制到 /docs文件夹(:= 同一个 repo,不是远程的!),它们将根据它们的 frontmatter 重命名
我有一个 .csv 文件,其中第一列包含用户名。它们采用 FirstName LastName 的形式。我想获取 FirstName 并将 LastName 的第一个字符添加到它上面,然后删除空格。然
Sitecore 根据 Sitecore 树中定义的项目名称生成 URL, http://samplewebsite/Pages/Sample Page 但我们的客户有兴趣降低所有 URL(页面/示例
我正在尝试进行一些计算,但是一旦我输入金额,它就会完成。我只是希望通过单击按钮而不是自动发生这种情况。 到目前为止我做了什么: Angular JS - programming-fr
我的公司创建了一种在环境之间移动文件的复杂方法,现在我们希望将某些构建的 JS 文件(已转换和缩小)从一个 github 存储库移动到另一个。使用 github 操作可以实现这一点吗? 最佳答案 最简
在我的代码中,我创建了一个 JSONArray 对象。并向 JSONArray 对象添加了两个 JSONObject。我使用的是 json-simple-1.1.jar。我的代码是 package j
我是一名优秀的程序员,十分优秀!