创建元素document.createElement("元素名")
创建一个<ul>
元素:const ul = document.createElement("ul")
此时的 ul 并没有直接添加到页面之中,而是存储在了内存 ul 之中。所以不会在 HTML 页面之中显示出来。
往页面添加元素
添加一个新创建好的元素需要给它一个父级元素,它会往该父级元素之下添加内容。
语法:document.父级元素.appendChild(创建好在内存之中的元素名)
appendChild()
,是将元素最做父级的最后一个子元素插入的
往body
中添加刚刚创建好的 ul 元素,此时body
就是ul
的父级document.body.appendChild(ul)
和创建添加元素一样,只是需要用到
querySelector
选择刚刚创建好的或者自己想要添加的元素作为添加内容的父级
let li = document.createElement("li")
document.querySelector.appendChild(li)
父元素.insertBefore(新元素,参考的位置), 不存在, insertAfter()
ul.insertBefore(li, place);
5. 向元素之中添加内容:如文本innerHTML
或innerText
方法
innerHTML
可以将文本中的 html 标签解析出来innerText
纯文本,不解析 html 代码
往 li 标签之中添加内容
li.innerText = "我是纯文本"
>
这里使用 for 循环来演示一下
for (let i =0;i<5;i++){
li = document.createElement("li")
li.innerHTML = "我是标签"+(i+1)
document.querySelector("ul").appendChild(li)
}
通过想替换的元素的父级.replaceChild(替换的元素,被替换的元素位置)
const place = document.querySelector("li:nth-of-type(3)");
const place1 = document.querySelector("li:nth-of-type(1)");
// 实际上以下这行代码等于: document.querySelector("ul").replaceChild(place, place1);
ul.replaceChild(place, place1);
删除操作
删除操作不需要元素的参考。所以直接查找到元素即可执行删除操作。
ul.removeChild(document.querySelector("li:last-of-type"));
链式操作
链式操作是将代码有序的执行,如创建和添加元素:
document.body.apendChild(document.createElement("ul")).appendChild("li")
文档片段
文档片段是什么:文档片段是将创建的文档对象临时储存到一个内存之中,避免每往页面添加一次数据就会导致页面刷新或重新渲染一次,浪费服务器资源或造成卡顿,所以将数据临时存储到内存之中,最后通过一次性输出的方式使页面只刷新一次即可完成操作,节省资源和时间,能大大提高网站的加载速度。
文档树将采用方法:
new createDocumentFargment()
>
// 创建文档树
const frag = document.createDocumentFragment();
// 创建子元素
for (let i = 0; i < 1000; i++) {
li = document.createElement("li");
li.innerHTML = "我是第" + (i + 1) + "个元素";
// 将所有子元素添加到文档树之中
frag.appendChild(li);
}
// 创建ul
const ul = document.createElement("ul");
// 将文档树挂载到ul,以ul为父级
ul.appendChild(frag);
// 往页面之中添加元素
document.body.appendChild(ul);
toDolist
<title>toDolist</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #d2ffc1;
}
h2 {
margin-top: 1.5em;
color: #03a3ff;
text-align: center;
}
form {
display: grid;
grid-template-columns: 5em, 20em;
gap: 0.5em;
place-content: center;
margin-top: 1.5em;
}
button,
form > div > input {
border-radius: 0.4em;
}
li {
margin-top: 2em;
text-align: center;
}
</style>
</head>
<body>
<h2>toDolist留言板实战</h2>
<form action="" onsubmit="return false">
<div>
<label for="comment">请留言:</label>
<input
type="text"
id="comment"
name="comment"
placeholder="请输入内容"
/>
</div>
<button>立即提交</button>
</form>
<ul id="list"></ul>
<script>
// 获取到输入框和列表元素
const comment = document.querySelector("#comment");
const list = document.querySelector("#list");
// 给文本框添加事件
comment.addEventListener("keyup", show, false);
function show(ev) {
console.log(ev.key);
if (ev.key === "Enter") {
console.log(comment.value);
// 做一个非空判断
// 非空判断需要用到一个方法:trim()
if (comment.value.trim().length === 0) {
alert("请输入留言内容,留言内容不能为空!");
comment.focus();
return false;
}
// 通过了非空验证,就将留言以列表的形式添加到页面
const li = document.createElement("li");
li.innerHTML =
comment.value + ' <button onclick="del(this)">删除</button>';
// 判断留言内容是否存在,若不存在即生成第一个,若存在,在第一个子元素之前生成
if (list.childElementCount === 0) {
list.appendChild(li);
} else {
list.insertBefore(li, list.firstElementChild);
}
// 清空输入框
comment.value = null;
}
}
// 执行删除留言的操作
function del(ele) {
console.log(ele);
// 要删除的是button的父元素li
if (confirm("是否删除")) list.removeChild(ele.parentNode);
}
</script>
</body>
const tab = document.querySelector(".tab");
const items = document.querySelectorAll(".item");
// 绑定事件,鼠标滑过切换
tab.addEventListener("mouseover", show, false);
// 事件回调show
function show(ev) {
// 移除tab子元素下的所有样式
Array.from(tab.children).forEach((item) =>
item.classList.remove("active")
);
// 将用户当前的选择项激活
ev.target.classList.toggle("active");
// 清空内容区内容,并根据data-index索引对应值相等来显示对应的内容
items.forEach((item) => item.classList.remove("active"));
// 查询对应的data-index的值,如果相等就显示
items.forEach((item) =>
item.dataset.index === ev.target.dataset.index
? item.classList.toggle("active")
: null
);
}
原理:通过操作背景图片样式的 url 地址替换来实现。
<style>
body {
background-image: url(static/images/1.jpg);
background-repeat: no-repeat;
background-size: cover;
}
</style>
</head>
<body>
<div class="container">
<img src="static/images/1.jpg" alt="" />
<img src="static/images/2.jpg" alt="" />
<img src="static/images/3.jpg" alt="" />
</div>
<script>
document
.querySelector(".container")
.addEventListener(
"click",
(ev) =>
(document.body.style.backgroundImage = "url(" + ev.target.src + ")")
);
</script>
懒加载:视口高度 clientHeight、滚动高度 scrollTop 和元素偏移高度 offsetTop
clientHeight
:视口高度,它总是小于设备屏幕尺寸。通过document.documentElement.clientHeight
获取,要注意不是 viewHeight,因为它是看过的高度。scrollTop
:滚动高度,就是滚动条上边距可视区域顶部的高度。它加上视口高度所包括的内容就是用户可以浏览的内容。通过document.documentElement.scrollTop
获取。offsetTop
:元素偏移高度,元素在文档流中,到文档顶部的高度。通过元素的 offsetTop
属性获取。
下面开始实战:
<!-- 一部分图片代码,不提供全部了 -->
<div class="container">
<img src="images/temp.jpg" alt="" data-src="images/img-1.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-2.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-3.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-4.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-5.jpg" />
<img src="images/temp.jpg" alt="" data-src="images/img-6.jpg" />
</div>
// 获取到所有图片
const imgs = document.querySelectorAll(".container img");
// 查询获取当前视口的高度
const clientHeight = document.documentElement.clientHeight;
// 监听滚动条事件
window.addEventListener("scroll", lazyload, false);
// load: 当页面加载成功时自动执行,将已进入可视区的图片显示出来,不要出现首页空白
window.addEventListener("load", lazyload, false);
// 懒加载的回调
function lazyload() {
// 动态获取滚动条的高度
let scrollTop = document.documentElement.scrollTop;
// 遍历显示图片(当图片进入可视区域后显示)
imgs.forEach((img) => {
if (img.offsetTop <= clientHeight + scrollTop) {
img.src = img.dataset.src;
// 如果感觉图片显示太快,可以用定时器来控制一下
setTimeout(() => {
img.src = img.dataset.src;
}, 500);
}
});
}