前端之勇闯DOM关
一、DOM简介
1.1什么是DOM
文档对象类型(Document Object Model,简称DOM),是W3C组织推荐的处理课扩展标记语言(HTML或者XML)的标准编程接口
W3C已经定义了一系列的DOM接口,通过这些DOM接口可以改变网页的内容、结构和样式
1.2DOM树
- 文档:一个页面就是一个文档,DOM中使用document 表示
- 元素:页面中的所有标签都是元素,DOM中使用element表示
- 节点:网页中所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
DOM把以上所有内容看作是对象
二、获取元素
2.1如何获取页面元素
- 根据ID获取
- 根据标签名获取
- 通过HTML5新增的方法获取
- 特殊元素获取
2.2根据ID获取
使用getElementById()方法可以获取带有ID的对象
<div id="name">花花</div>
<script>var namer = document.getElementById('name');console.log(namer);//<div id="name">花花</div>console.dir(namer);//div#name
</script>
- 因为我们文档页面从上往下加载,所以先得有标签,所以我们scrip写到标签的下面
- 参数:id是大小写敏感的字符串
- 返回的是一个元素对象
-
console.dir打印我们返回的元素对象,更好地查看里面的属性和方法
2.3根据标签名获取
使用getElementByTagName()方法可以返回带有知道标签名的对象的集合
<ul><li>1110</li><li>111</li><li>111</li><li>111</li><li>111</li>
</ul>
<script>var lis = document.getElementsByTagName('li');console.log(lis);
</script>
可以看见,是采用伪数组的形式存储的
所以也可以用数组的方法输出
console.log(lis[0]);
想要依次打印里面的元素可以采用遍历的方式
for (var i = 0; i < lis.length; i++) {console.log(lis[i]);
}
注意:
1.因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历
2.得到元素对象是动态的
3.如果页面只有一个li,返回的还是伪数组形式
4.如果页面中没有这个元素,返回的是空的伪数组的形式
获取某个元素(父元素) 内部所有指定标签的子元素
element.getElementsByTagName('标签名');
注意:父元素必须是单个对象(必须指明是哪一个元素对象),获取的时候不包括自己
例如:
var ul = document.getElementsByTagName('ul');
console.log(ol.getElementsByTagName('ol'));
此时将伪数组作为父元素,报错啦
要指定一个确定的元素
var ul = document.getElementsByTagName('ul');
console.log(ul[0].getElementsByTagName('ul'));
此时可以把ul里面所有li获取出来
但是这个方法还是有点麻烦,可以直接给ul一个id,根据id获取ul里面所有的li
2.4通过HTML5新增的方法获取
(1)根据类名返回元素对象集合
document.getElementsByClassName('类名');//根据类型名返回元素对象集合
例如
<div class="box">盒子1</div>
<div class="box">盒子2</div>
<div id="nav"><ul><li>首页</li><li>产品</li></ul>
</div>
<script>var boxs=document.getElementsByClassName('box');console.log(boxs);
</script>
运行结果:
(2)根据指定选择器返回第一个元素对象
document.querySelector('选择器');//根据指定选择器返回第一个元素对象
例如:
var firstBox = document.querySelector('.box');
console.log(firstBox);
var nav = document.querySelector('#nav');
console.log(nav);
var firstli = document.querySelector('li');
console.log(firstli);
运行结果:
切记里面的选择器要加符号,.box #nav.....
(3)根据指定选择器返回所有对象
document.querySelectorAll('选择器');//根据指定选择器返回所有元素对象
例如:
var allBox = document.querySelectorAll('.box');
console.log(allBox);
运行结果:
2.5获取特殊元素(body,HTML)
(1)获取body元素
document.body//返回body元素对象
实际应用:
var bodyEle = document.body;
console.log(bodyEle);
(2)获取html元素
document.documentElement//返回heml元素对象
实际应用:
var htmlEle = document.documentElement;
console.log(htmlEle);
三、事件基础
3.1事件概述
JavaScript使我们有能力创建动态页面,而事件是可以被JavaScript侦测到的行为
简单理解:触发---响应机制
事件三要素:事件源,事件类型,事件处理程序
<button id="btn">唐伯虎</button>
<script>//(1)事件源 事件:被触发的对象 谁:按钮var btn = document.getElementById('btn');//(2)事件类型 如何触发 什么事件 比如鼠标点击(onclick),还是鼠标经过,还是鼠标按下//(3)事件处理程序 通过一个函数赋值的方式完成btn.onclick = function () {alert('点秋香');}
</script>
3.2执行事件的步骤
1.获取事件源
2.注册事件(绑定事件)
3.添加事件处理程序(采取函数赋值形式)
案例:点击123,输出我被选中了
<div>123</div>
<script>//1.获取事件源var xzl = document.querySelector('div');//2.绑定事件//div.onclick//3.添加事件处理程序xzl.onclick = function () {alert('我被选中了');}
</script>
3.3常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
四、操作元素
4.1改变元素内容
element.innerText
从起始位置到终止位置的内容,但它除去html标签,同时空格和换行也会去掉
element.innerHTML
从起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
案例:点击按钮,div的文字发生变化
<button>显示时间</button>
<div>时间</div>
<p>1</p>
<script>var btn = document.querySelector('button');var div = document.querySelector('div');btn.onclick = function () {div.innerText = getDate();}function getDate() {var date = new Date();var year = date.getFullYear();var month = date.getMonth() + 1;var day = date.getDate();return year + '年' + month + '月' + day + '日';}
</script>
我们元素可以不用添加事件
var p = document.querySelector('p');
p.inner.Text = getDate();
这样的事件,刷新网页后会自动跳出所需内容
element.innerText和element.innerHTML区别
1.inner.Text不识别html标签 非标准 去除换行与空格
2.inner.HTML识别html标签 W3C标准 保留空格和换行
3.这两个属性是可读写的,可以获取元素里面的内容
4.2常用元素的属性操作
1.innerText、innerHTML 改变元素内容
2.src、href
3.id、alt、title
例如使用src
<button id="1">1</button>
<button id="2">2</button>
<img src="9.png" alt="">
<script>var but1 = document.getElementById('.1');var but2 = document.getElementById('2');var imgs = document.querySelector('img');but2.onclick = function () {imgs.src = '10.png';}but1.onclick = function () {imgs.src = '9.png';}
</script>
案例:分时显示不同图片,显示不同的问候语
<div>上午好</div>
<img src="1.png" alt="">
<script>var date = new Date();var hour = date.getHours();var img = document.querySelector('img');var div = document.querySelector('div');if (hour < 12) {div.innerHTML = '上午好';img.src = '1.png';}else if (hour == 12) {div.innerHTML = '中午好';img.src = '2.png';}else if (hour < 18) {div.innerHTML = '下午好';img.src = '3.png';}else {div.innerHTML = '晚上好';img.src = '4.png';}
</script>
4.3表达原始的属性操作
利用DOM可以操作如下表单元素的属性:
type,value,checked,selected,disabled
(1)value(表单里面的文字内容是通过value来修改的)
<button>按钮</button>
<input type="text" value="输入内容">
<script>var btn = document.querySelector('button');var input = document.querySelector('input');btn.onclick = function () {input.value = '被点击了';}
</script>
(2)disabled(让某个表单被禁用,不能再点击)
btn.disabled = true;
(3)type
input.type = '';
案例:仿京东显示密码
点击按钮将密码框切换为文本框,并可以查看密码明文
css部分
.box {position: relative;width: 400px;border-bottom: 1px solid #ccc;margin: 100px auto;
}
.box input {width: 370px;height: 30px;border: 0;outline: none;
}
.box img {top: 5px;left: 365px;position: absolute;width: 24px;
}
HTML部分
<div class="box"><label for=""><img src="yincang.png" alt=""></label><input type="password" id="">
</div>
JavaScript部分
var input = document.querySelector('input');
var img = document.querySelector('img');
var flag = 0;
img.onclick = function () {if (flag == 0) {input.type = 'text';img.src = 'display.png';flag = 1;}else {input.type = 'password';img.src = 'yincang.png';flag = 0;}
}
4.4样式属性操作
我们可以通过JS修改元素的大小、颜色、位置等样式
(1)行内样式操作
element.style
案例:点击盒子,改变背景以及宽度
css:
div {width: 200px;height: 200px;background-color: pink;
}
HTML:
<div></div>
JavaScript:
var div = document.querySelector('div');
div.onclick = function () {this.style.backgroundColor = 'purple';this.style.width = '250px';
}
注意:
1.JS里面的样式采取驼峰命名法,例如:fontSize、backgroundColor
2.JS修改style样式操作,产生的是行内样式,css权重比较高
案例:关闭二维码
css:
.box {position: relative;width: 200px;height: 200px;margin: 100px auto;
}.box .ma {width: 180px;
}.box p {position: absolute;top: -20px;left: -15px;width: 5px;
}
HTML:
<div class="box"><img src="二维码.jpg" alt="" class="ma"><p><img src="fork.png" alt=""></p>
</div>
JS:
var fork = document.querySelector('p');
var box = document.querySelector('.box');
fork.onclick = function () {box.style.display = 'none';
}
案例:循环精灵图背景
可以用for循环设置一组元素的精灵图背景
css:
.box {width: 305px;height: 170px;margin: 200px auto;
}.box li {float: left;list-style: none;width: 24px;height: 24px;margin: 15px;background: url(sprite.png);
}.box li:hover {border: 1px solid red;
}
HTML:
<div class="box"><ul><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li></ul>
</div>
JavaScript:
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {var index = i * 44;lis[i].style.backgroundPosition = '0 -' + index + 'px';
}
案例:显示隐藏文本内容
当鼠标点击文本框时,里面文字默认隐藏,当鼠标离开文本框时,文字显示
css:
input {color: #999;
}
HTML:
<input type="text" value="手机">
JavaScript:
var text = document.querySelector('input');
text.onfocus = function () {if (this.value == '手机') {this.value = '';}this.style.color = 'black';
}
text.onblur = function () {if (this.value == '') {his.value = '手机';}his.style.color = '#999';
}
(2)类名样式操作
element.ClassName
案例:使用className更改元素样式
css:
div {height: 50px;width: 50px;background-color: pink;
}.change {background-color: purple;color: #fff;font-size: 25px;margin-top: 100px;
}
HTML:
<div>文本</div>
JavaScript:
var div = document.querySelector('div');
div.onclick = function () {this.className = 'change';
}
注意:
1.如果样式修改较多,可以采取操作类名的方式更改元素样式
2.class因为是个保留字,隐藏使用className来操作元素类名属性
3.className会直接更改元素类名,会覆盖原先的类名
4.如果想要保留原先类名,可以用多类名选择器
this.className = 'first change';
案例:密码框格式提示错误信息
用户如果离开密码框。里面输入个数不是6-16,则提示错误信息,否则提示输入正确信息
css:
.register {margin: 200px 500px;
}
.ipt {height: 20px;
}
.message {display: inline-block;color: #999;font-size: 12px;padding-left: 20px;background: url(mess.png) no-repeat left center;
}
.wrong {color: red;background: url(wrong.png) no-repeat left center;
}
.right {color: green;background: url(right.png) no-repeat left center;
}
HTML:
<div class="register"><input type="password" name="" class="ipt"><p class="message">请输入6~16位密码</p>
</div>
JavaScript:
var ipt = document.querySelector('input');
var p = document.querySelector('p');
ipt.onblur = function () {if (this.value.length < 6 || this.value.length > 16) {p.className = 'message wrong';p.innerHTML = '您输入的位数不正确,要求6~16位';}else {p.className = 'message right';p.innerHTML = '您输入的位数正确';}
}
4.5排他思想
案例:点击按钮变色,上一个按钮恢复原来颜色
HTML:
<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>
<button>按钮6</button>
JavaScript:
var btns = document.querySelectorAll('button');
for (var i = 0; i < btns.length; i++) {btns[i].onclick = function () {for (var i = 0; i < btns.length; i++) {btns[i].style.backgroundColor = '';}this.style.backgroundColor = 'pink';}
}
如果有一组元素,我们想要某一个元素实现某个样式,需要用到循环的排他思想算法
案例:百度换肤
css:
* {margin: 0;padding: 0;
}body {background: url(3.png) no-repeat center top;
}.baidu {overflow: hidden;margin: 100px auto;background-color: #fffwidth: 410px;padding-top: 3px;display: flex;justify-content: center;
}.baidu li {list-style: none;
}.baidu img {width: 100px;
}
HTML:
<ul class="baidu"><li><img src="3.png" alt=""></li><li><img src="download.jpg" alt=""></li><li><img src="OIP-C.jpg" alt=""></li>
</ul>
JavaScript:
var imgs = document.querySelector('.baidu').querySelectorAll('img');
var body = document.querySelector('body');
for (var i = 0; i < imgs.length; i++) {imgs[i].onclick = function () {body.style.backgroundImage = 'url(' + this.src + ')';}
}
案例:表格隔行变色
css:
table {border-collapse: collapse;border: 1px solid skyblue;margin: 100px auto;
}th,
td {border: 1px solid skyblue;
}th {background-color: #4196c1;color: #fff;
}.bg {background-color: #0ad5eb;
}
HTML:
<table><thead><th>表头1</th><th>表头2</th></thead><tbody><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></tbody>
</table>
JavaScript:
var trs = document.querySelector('tbody').querySelectorAll('tr');
for (var i = 0; i < trs.length; i++) {trs[i].onmouseover = function () {this.className = 'bg';}trs[i].onmouseout = function () {this.className = '';}
}
案例:表单全选取消全选
css:
table {border-collapse: collapse;border: 1px solid skyblue;margin: 100px auto;
}th,
td {border: 1px solid skyblue;
}th {background-color: #4196c1;color: #fff;
}
HTML:
<table><thead><th><input type="checkbox" name="" id="j_cbAll"></th><th>表头1</th><th>表头2</th></thead><tbody id="j_tb"><tr><td><input type="checkbox" id="checkbox"></td><td>1</td><td>2</td></tr><tr><td><input type="checkbox" id="checkbox"></td><td>3</td><td>4</td></tr></tbody>
</table>
JavaScript:
var j_cbAll = document.querySelector('#j_cbAll');
var j_tbs = document.querySelector('#j_tb').getElementsByTagName('input');
j_cbAll.onclick = function () {console.log(this.checked);for (var i = 0; i < j_tbs.length; i++) {j_tbs[i].checked = this.checked;}
}
for (var i = 0; i < j_tbs.length; i++) {j_tbs[i].onclick = function () {var flag = true;for (var i = 0; i < j_tbs.length; i++) {if (!j_tbs[i].checked) {j_cbAll.checked = false;flag = false;}}j_cbAll.checked = flag;}
}
4.6自定义属性的操作
(1)获取属性值
1.element.属性
var div = document.querySelector('div');
console.log(div.id);
2.element.getAttribute('属性')
console.log(div.getAttribute('id'));
区别:
1.element.属性 获取内置属性值(元素本来自带的属性)
2.element.getAttribute('属性') 主要获取自定义属性(我们程序员自定义的属性)
(2)设置属性值
1.element.属性 = '值' 设置内置属性值
div.id = 'test';
div.className = 'navs';
2.element.setAttribute('属性','值') 主要针对于自定义属性
div.setAttribute('id','test');
div.setAttribute('class','footer');
class特殊,这里写的就是class,不是className
(3) 移除属性
element.removeAttribute('属性')
div.removeAttribute('id');
案例:tab栏切换
css:
* {margin: 0;padding: 0;
}ul {display: inline-block;
}li {font-size: 20px;list-style: none;display: inline-block;padding: 5px;line-height: 20px;
}.tab_list {width: 510px;background-color: #efecec;
}.current {background-color: #ba7272;color: #fff;
}
HTML:
<div class="tab"><div class="tab_list"><ul><li>商品介绍</li><li>规格与包装</li><li>售后与保障</li><li>商品评价</li><li>手机社区</li></ul></div><div class="tab_con"><div class="item">商品模块介绍内容</div><div class="item">规格与包装介绍内容</div><div class="item">售后与保障介绍内容</div><div class="item">商品评价介绍内容</div><div class="item">手机社区介绍内容</div></div>
</div>
JavaScript:
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {lis[i].setAttribute('index', i);var items = document.querySelectorAll('.item');lis[i].onclick = function () {for (var i = 0; i < lis.length; i++) {lis[i].className = '';}this.className = 'current';var index = this.getAttribute('index');for (var i = 0; i < items.length; i++) {items[i].style.display = 'none';}items[index].style.display = 'block';}
}
4.7H5自定义属性
自定义属性的目的:为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中、
自定义属性通过getAttribute('属性')获取
有些自定义属性不容易判断是元素的内置属性还是自定义属性
(1)设置H5自定义属性
H5规定自定义属性data-开头作为属性名并且赋值
例如:
<div data-index='1'></div>
或者用JS设置:
element.setAttribute('data-index');
(2)获取H5自定义属性
1.兼容获取 element.getAttribute('data-index');
2.H5新增element.dataset.index 或者 element.dataset['index'] ie11才开始支持
dataset是一个集合,里面存放了所有以data开头的自定义属性
如果自定义属性比较长,使用getAttribute比较方便,使用dataset的话使用驼峰命名法,例如:
<div data-list-name="andy"></div>
console.log(div.getAttribute('data-list-name');
console.log(div.dataset.listName);
五、节点操作
5.1节点概述
上面DOM树提过节点的概念,也就是页面所有内容全是节点
一般来讲,节点至少有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性
- 元素节点 nodeType值为1------------>我们主要操作的节点类型
- 属性节点 nodeType值为2
- 文本节点 nodeType值为3 (文本节点包含文字、空格、换行等)
5.2节点层级
(1)父节点
parentNode 得到的是离元素最近的节点(亲爸爸),如果找不到父元素返回null
在下面有父子关系的盒子中,要得到父元素:
<div class="box"><span class="erweima">x</span>
</div>
原来的方法:
var erweima = document.querySelector('.erweima');
var box = document.querySelector('.box');
使用 父节点:
var erweima = document.querySelector('.erweima');
console.log(erweima.parentNode);
(2)子节点
1.childNodes
childNodes得到的所有子节点包含元素节点、文本节点等等
在下面有父子关系的盒子中,要得到子元素:
<div class="box"><span class="erweima">x</span><span class="erweima">x</span><span class="erweima">x</span><span class="erweima">x</span>
</div>
原来的方法:
var box = document.querySelector('.box');
var erweima = box.querySelector('.erweima');
使用子节点:
var box = document.querySelector('.box');
console.log(box.childNodes);
如果只想获得里面的元素节点,则需专门处理:
var box = document.querySelector('.box');
for (var i = 0; i < box.childNodes.length; i++) {if (box.childNodes[i].nodeType == 1) {console.log(box.childNodes[i]);;}
}
2.parentNode .children
parentNode .children 非标准 获得所有的子元素节点
console.log(box.children);
3.parentNode.firstChild
parentNode.firstChild 获得子元素第一个节点,不管是文本节点还是元素节点
console.log(box.firstChild);
4.parentNode.lastChild
parentNode.larstChild 获得子元素最后一个节点,不管是文本节点还是元素节点
console.log(box.lastChild);
5.parentNode.firstElementChild
parentNode.firstElementChild 返回第一个子元素节点
console.log(box.firstElementChild);
6.parentNode.lastElementChild
parentNode.lastElementChild 返回最后一个子元素节点
console.log(box.lastElementChild);
注意:5和6有兼容性问题,IE9以上才支持
7.获得子元素第一个和最后一个节点的写法(开发中)
此方法无兼容性问题
console.log(box.children[0]);
console.log(box.children[box.children.length - 1]);
案例:下拉菜单
css:
* {margin: 0;padding: 0;
}a {display: inline-block;width: 69px;color: #000;text-decoration: none;
}.nav {display: inline-block;width: 210px;text-align: center;
}.nav ul {display: inline-block;
}.nav>li {width: 65px;position: relative;
}.under {display: none;position: absolute;top: 100%;left: 0;
}.under li {width: 68px;border-collapse: collapse;border: 1px solid orange;
}li {display: inline-block;list-style: none;
}.nav>li a:hover {background-color: #ec040475;
}.under li:hover {background-color: #f18e16ba;
}
HTML:
<ul class="nav"><li><a href="#">微博</a><ul class="under"><li>私信</li><li>评论</li><li>@我</li></ul></li><li><a href="#">微博</a><ul class="under"><li>私信</li><li>评论</li><li>@我</li></ul></li><li><a href="#">微博</a><ul class="under"><li>私信</li><li>评论</li><li>@我</li></ul></li>
</ul>
JavaScript:
var nav = document.querySelector('.nav');
var lis = nav.children;
for (var i = 0; i < lis.length; i++) {lis[i].onmouseover = function () {this.children[1].style.display = 'block';}lis[i].onmouseout = function () {this.children[1].style.display = 'none';}
}
(3)兄弟节点
1.node.nextSibling
node.nextSibling返回当前元素的下一个兄弟节点,找不到则返回null,包含所有节点,元素节点、文本节点等
例如在:
<div>1</div>
<span>2</span>
使用 node.nextSibling,输出#text
var div = document.querySelector('div');
console.log(div.nextSibling);//#text
2.node.previousSibling
node.previousSibling返回当前元素的上一个兄弟节点,找不到则返回null,包含所有节点,元素节点、文本节点等
例如在:
<div>1</div>
<span>2</span>
使用 node.previousSibling,输出#text
var span = document.querySelector('span');
console.log(div.previousSibling);//#text
3.node.nextElementSibling
node.nextElementSibling返回当前元素的下一个兄弟节点,找不到则返回null
var div = document.querySelector('div');
console.log(div.nextElementSibling);
4.node.previousElementSibling
node.previousElementSibling返回当前元素的上一个兄弟节点,找不到则返回null
var span = document.querySelector('span');
console.log(div.previousElementSibling);
注意:3和4有兼容性问题,只有IE9以上才支持
可以自己封装一个兼容性函数
function getNextElementSibling(element) {var el = element;while (el = el.nextSibling) {if (el.nodeType == 1) {return el;}}return null;
}
5.3创建节点
document.createElement('tagName');
因为原先不存在,根据需求生成的,又叫动态创建元素节点
5.4添加节点
node.appendChild(child);
(1)node.appendChild()
node.appendChild()将一个节点添加到指定父节点的末尾,类似于CSS里面after伪元素,又称为追加元素,类似于数组中的push
在一个ul里面添加li
var li=document.createElement('li');
var ul=document.querySelector('ul');
ul.appendChild(li);
(2) nodeinsertBefore()
nodeinsertBefore(child,指定元素)
var lili = document.createElement('li');
ul.insertBefore(lili,ul.children[0]);
案例:简单版发布留言案例
css:
li {color: plum;background-color: rgb(250, 217, 222);margin-bottom: 10px;
}textarea {margin-top: 20px;margin-left: 40px;resize: none;border: 1px solid pink;border-radius: 5px;
}
HTML:
<textarea value=""></textarea>
<button>发布</button>
<ul></ul>
JavaScript:
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
btn.onclick = function () {if (text.value == '') {alert('您没有输入内容');return false;}else {var li = document.createElement('li');li.innerHTML = text.value;ul.insertBefore(li, ul.children[0]);}
}
5.5删除节点
node.removeChild(child)方法从DOM中删除一个子节点,返回删除的节点
例如:
ul.removeChild(ul.children[0]);
案例:删除留言节点
css:
li {color: plum;background-color: rgb(250, 217, 222);margin-bottom: 10px;
}li a {float: right;
}textarea {margin-top: 20px;margin-left: 40px;resize: none;border: 1px solid pink;border-radius: 5px;
}
HTML:
<textarea value=""></textarea>
<button>发布</button>
<ul></ul>
JavaScript:
var btn = document.querySelector('button');
var text = document.querySelector('textarea');
var ul = document.querySelector('ul');
btn.onclick = function () {if (text.value == '') {alert('您没有输入内容');return false;}else {var li = document.createElement('li');li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";ul.insertBefore(li, ul.children[0]);var as = document.querySelectorAll('a');for (var i = 0; i < as.length; i++) {as[i].onclick = function () {ul.removeChild(this.parentNode);}}
}
5.6复制节点(克隆节点)
node.cloneNode()
1.如果括号参数为空或者是false,则是浅拷贝,只克隆节点本身,不克隆里面的子节点
2.如果括号参数为true,则是深拷贝,只克隆里面的内容
案例:动态生成表格
css:
thead {background: #bababa;
}th {border: 1px solid rgb(150, 149, 149);padding-left: 20px;padding-right: 20px;
}td {border: 1px solid rgb(150, 149, 149);text-align: center;
}
HTML:
<table cellspacing="0"><thead><tr><th>姓名</th><th>科目</th><th>成绩</th><th>操作</th></tr></thead><tbody></tbody>
</table>
JavaScript:
var datas = [{name: '魏璎珞',subject: 'JavaScript',score: 100
}, {name: '宏利',subject: 'JavaScript',score: 90
}, {name: '尹翼川',subject: 'JavaScript',score: 60
}]
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {var tr = document.createElement('tr');tbody.appendChild(tr);for (k in datas[i]) {var td = document.createElement('td');td.innerHTML = datas[i][k];tr.appendChild(td);}var td = document.createElement('td');td.innerHTML = '<a href="jabasctipt:;">删除</a>';tr.appendChild(td);
}
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {as[i].onclick = function () {tbody.removeChild(this.parentNode.parentNode);}
}
5.7三种动态创建元素的区别
(1)document.write()
document.write直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面全部重绘
(2)document.innerHTML
document.innerHTML将内容写入某个DOM节点,不会导致页面全部重绘
innerHTML创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
(3)document.createElement()
createElement创建多个元素效率稍微低一点,但是结构更清晰
相关文章:
前端之勇闯DOM关
一、DOM简介 1.1什么是DOM 文档对象类型(Document Object Model,简称DOM),是W3C组织推荐的处理课扩展标记语言(HTML或者XML)的标准编程接口 W3C已经定义了一系列的DOM接口,通过这些DOM接口可…...
实现鼠标拖拽图片效果
我们需要一个图片 可以是你的女朋友 可以是男朋友 ,我就拿窝的偶像 一个大佬——>甘为例吧! 哈哈哈哈哈 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport&q…...
nodejs模块暴露数据的方式,和引入(导入方式)方式
在 Node.js 中,模块之间通过 模块导出(exports) 和 模块导入(require 或 ESModule 的 import) 来进行数据和功能的共享。下面我详细总结一下两种主要的模块系统: 一、CommonJS 模块(Node.js 默认…...
AXOP33552: 400MHz 高速双通道运算放大器
AXOP33552是一款通用型高速双通道运算放大器,产品的工作电压为2V至5.5V,具有400MHz的带宽,f0.1dB的带宽为 120MHz,单通道静态电流为10mA。产品特别对噪声和THD做了优化,其噪声为5nV/√Hz 1MHz,2次谐波为-85…...
Spring Boot日志配置
目录 logback 使用logback 获取日志对象 日志级别 控制日志输出级别 日志输出格式控制 配置方式 日志转存 示例 日志是应用程序不可或缺的一部分,记录着程序运行的信息。主要作用有: 记录日常运营的重要信息记录应用报错信息记录过程数据等…...
不可变数据:基于持久化数据结构的状态管理
不可变数据:基于持久化数据结构的状态管理 一、 什么是不可变数据? 不可变数据是指一旦创建就无法更改的数据。在计算机科学中,不可变数据结构是指其内容或状态不能被修改的数据结构。在不可变数据中,所有修改操作都会生成新的数据副本&#…...
PyTorch卷积层填充(Padding)与步幅(Stride)详解及代码示例
本文通过具体代码示例讲解PyTorch中卷积操作的填充(Padding)和步幅(Stride)对输出形状的影响,帮助读者掌握卷积层的参数配置技巧。 一、填充与步幅基础 填充(Padding):在输入数据边缘…...
C++手撕STL-其叁
Deque 今天我们进入新的容器:deque,一般叫做双端队列。 比起传统的先入先出的队列queue,deque的出场率显然要低得多,事实上deque比起queue来说最大的特点就是多了一个push_front()和pop_front(),其他并没有太多不同。…...
AI大模型-window系统CPU版安装anaconda以及paddle详细步骤-亲测有效
window系统CPU版安装anaconda以及paddle详细步骤-亲测有效 一 安装anaconda 下载地址:anaconda下载 下载成功后,选择非C盘安装,按提示安装即可修改镜像文件 安装成功后,运行anaconda软件,若提示更新则点击更新,更新完后,修改镜像文件 找到用户目录下的.condarc文件,覆…...
UML概览
🥰名片: 🐳作者简介:乐于分享知识的大二在校生 🌳本系列专栏: (点击直达)统一建模语言UML 🫣致读者:欢迎评论与私信,对于博客内容的疑问都会尽量回复哒!!! 本文序: ⛰️本文介绍&…...
影刀填写输入框(web) 时出错: Can not convert Array to String
环境: 影刀5.26.24 Win10专业版 问题描述: [错误来源]行12: 填写输入框(web) 执行 填写输入框(web) 时出错: Can not convert Array to String. 解决方案: 1. 检查变量内容 在填写输入框之前,打印BT和NR变量的值ÿ…...
LLMs可在2位精度下保持高准确率
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
C语言高频面试题——结构体和联合体区别
在 C 语言中,结构体(struct) 和 联合体(union) 是两种重要的复合数据类型,用于组织和管理多个相关的变量。尽管它们在语法上有些相似,但在内存布局、用途和行为上有显著的区别。以下是详细的对比…...
App爬虫工具篇-mitmproxy
mitmproxy 是一个支持 HTTP 和 HTTPS 的抓包程序,类似 Fiddler、Charles 的功能,它通过控制台的形式和ui界面的方式 此外,mitmproxy 还有两个关联组件,一个是 mitmdump,它是 mitmproxy 的命令行接口,利用它可以对接 Python 脚本,实现监听后的处理;另一个是 mitmweb,它…...
配置openjdk调试环境
先决条件 首先在Ubuntu 18.04上编译SlowDebug版本的openjdk。注意,这里我选择的是x86处理器的电脑。苹果M系列属于ARM芯片,指令集不一样。由于我在苹果上进行垃圾回收调试的时候会报SIGILL错误。为了了解JVM的内部工作原理,不要在这种问题上…...
加油站小程序实战教程13充值规则配置
目录 1 创建数据源2 搭建管理功能最终效果 我们目前已经实现了会员的注册以及登录功能,有了基础的认证之后就进入到了业务部分的开发。会员的话首先是可以进行充值,在充值的时候通常会有一定的赠送,本篇我们来开发一下充值规则的配置功能。 1…...
jQuery — 总结
介绍 jQuery是一款高效、轻量级的JavaScript库,旨在简化网页开发中的常见任务。自2006年发布以来,它凭借直观的语法和强大的功能迅速成为前端开发的标配工具。其核心设计理念是“写更少,做更多”,通过封装复杂的原生JavaScript操作…...
【信息安全工程师备考笔记】第二章 网络信息安全概述
第二章 网络攻击原理与常用方法 2.1 网络攻击概述 概念:损害网络 系统安全属性 的危害行为 危害行为基本类型 信息泄露攻击(机密性)完整性破坏攻击(完整性)拒绝服务攻击(可用性)非法使用攻击…...
国家自然科学基金答辩ppt制作案例模板下载
国家自然科学基金 National Natural Science Foundation of China 支持基础研究,坚持自由探索,发挥导向作用,发现和培养科学技术人才,促进科学技术进步和经济社会协调发展,逐渐形成和发展了由研究项目、人才项目和环境…...
代码随想录第三十七天|华为秋季笔试真题230823
刷题小记: 主要偏向扎实编码基础的考察,但貌似近些年题目难度有所提高,仅供参考。 卡码网136.获取连通的相邻节点列表(卡码网136.获取连通的相邻节点列表) 题目分析: 题目描述: 存在N个转发…...
KUKA机器人KR 3 D1200 HM介绍
KUKA KR 3 D1200 HM是一款小型机器人,型号中HM代表“Hygienic Machine(卫生机械)用于主副食品行业”,也是一款并联机器人。用于执行高速、高精度的抓取任务。这款机器人采用食品级不锈钢设计,额定负载为3公斤ÿ…...
从零开始创建MCP Server实战指南
一、MCP协议核心概念 1.1 什么是MCP? MCP(Model Context Protocol) 是一个标准化的“沟通规则”,由公司Anthropic提出,专门用于让大语言模型(LLM,比如通义千问、ChatGPT等)与外部工…...
C语言教程(十二):C 语言数组详解
一、引言数组的基本概念 数组是一组具有相同数据类型的元素的集合,这些元素在内存中连续存储。通过一个统一的数组名和下标来访问数组中的每个元素。使用数组可以方便地处理大量相同类型的数据,避免为每个数据单独定义变量。 二、一维数组 2.1 数组的…...
Linux[基础指令][2]
Linux[基础指令][2] cp(复制) 格式:cp [-rf] 源文件 {普通文件,目录} 拷贝 cp -r 递归拷贝目录 蓝色为目录,白色为具体文件 拷贝后面加一个不存在的文件会新建文件再拷贝 cp -ir -i是覆盖的时候询问 如果目标文件存在就会覆盖原有文件 mv(重命名/剪切) 格式:mv 源文件…...
MySQL_MCP_Server_pro接入cherry_studio实现大模型操作数据库
大模型直接与数据库交互,实现基本增删改查操作。首先贴下代码地址: https://github.com/wenb1n-dev/mysql_mcp_server_pro 安装环境:win10 1、下载代码 git clone https://github.com/wenb1n-dev/mysql_mcp_server_pro 2、使用conda创建…...
linux命令集
命令 grep -r --includeAndroid.bp libcfs ./ 参数说明 选项/参数作用-r递归搜索子目录。--includeAndroid.bp仅搜索名为 Android.bp 的文件(精确匹配文件名)。libcfs要搜索的关键字(单引号包裹特殊字符如 以避免被 Shell 解析ÿ…...
数据结构:链表
链表的概念及结构: 链表的概念: 链表是一种物理储存结构上非连续的储存结构,数据元素的逻辑顺序是通过引用链接次序实现的 那物理存储结构连续是什么意思? 之前我们讲过顺序表,顺序表的底层是数组,如下…...
【高并发内存池】从零到一的项目之高并发内存池整体框架设计及thread cache设计
个人主页 : zxctscl 专栏 【C】、 【C语言】、 【Linux】、 【数据结构】、 【算法】 如有转载请先通知 文章目录 前言1. 高并发内存池整体框架设计2. 高并发内存池--thread cache2.1 定长内存池的问题2.2 整体框架2.3 自由链表2.4 thread cache哈希桶的对齐规则2.5…...
电气动调节单座V型球阀带阀杆节流套沟槽孔板的作用-耀圣
电气动调节单座V球阀杆节流套是阀门中的一个重要组件,主要用于调节和控制流体介质的流量、压力或流速,同时兼具导向、密封和稳定阀杆运动降低流速减少冲刷的作用。以下是其具体功能和应用场景的详细说明: 1. 节流与流量控制** 作用原理**&am…...
vscode使用笔记
文章目录 安装快捷键 vscode是前端开发的一款利器。 安装 快捷键 ctrlp # 查找文件(和idea的双击shift不一样) ctrlshiftf # 搜索内容...
基于 SpringAI 整合 DeepSeek 模型实现 AI 聊天对话
目录 1、Ollama 的下载配置 与 DeepSeek 的本地部署流程 1.1 下载安装 Ollama 1.2 搜索模型并进行本地部署 2、基于 SpringAI 调用 Ollama 模型 2.1 基于OpenAI 的接口规范(其他模型基本遵循) 2.2 在 IDEA 中进行创建 SpringAI 项目并调用 DS 模型 3、基…...
Idea创建项目的搭建方式
目录 一、普通Java项目 二、普通JavaWeb项目 三、maven的JavaWeb项目 四、maven的Java项目 一、普通Java项目 1. 点击 Create New Project 2. 选择Java项目,选择JDK,点击Next 3. 输入项目名称(驼峰式命名法),可选…...
【MATLAB第115期】基于MATLAB的多元时间序列的ARIMAX的预测模型
【MATLAB第115期】基于MATLAB的多元时间序列的ARIMAX的预测模型 一、简介 ARIMAX(Autoregressive Integrated Moving Average with eXogenous inputs)模型是一种结合自回归(AR)、差分(I)、移动平均&a…...
【以太网安全】——防护高级特性配置总结
目前网络中以太网技术的应用非常广泛、然后、各种网络攻击的纯在(例如针对ARP DHCP 等攻击)不仅造成了网络合法用户无法正常访问网络资源、而且对网络信息安全构成严重威胁、以下配置是对局域网安全配置命令做详解 主要的安全威胁 MAC攻击:泛洪、欺骗 …...
微信小程序 van-dropdown-menu
点击其他按钮,关闭van-dropdown-menu下拉框 DropdownMenu 引入页面使用index.wxmlindex.scssindex.ts(重点)index.ts(全部) DropdownMenu 引入 在app.json或index.json中引入组件 "usingComponents": {"van-dropdown-menu": "vant/weapp…...
再见 Smartdaili,你好 Decodo!
我们将翻开新的篇章,推出新的名称以及更好的代理和刮擦解决方案。了解我们如何帮助全球用户构建、测试和扩展他们的公共网络数据项目。 Smartproxy,即后来的Smartdaili,由一个行业专业人士和企业家团队于2018年创立,其使命是创建一…...
海量文本中的词语距离:在 O(n) 时间内找到最近的词对
想象一个巨大的日志文件、一部鸿篇巨著或者网络爬虫抓取的数据——它们可能达到 TB 级别。现在,假设你需要找出两个特定的词(比如 词语1 和 词语2)在这段庞大文本中出现时,彼此“靠得最近”的距离是多少。 挑战: …...
TextCNN 模型文本分类实战:深度学习在自然语言处理中的应用
在自然语言处理(NLP)领域,文本分类是研究最多且应用最广泛的任务之一。从情感分析到主题识别,文本分类技术在众多场景中都发挥着重要作用。最近,我参与了一次基于 TextCNN 模型的文本分类实验,从数据准备到…...
前台调用接口的方式及速率对比
一、引言 在现代 Web 开发中,前台与后台的数据交互至关重要,而调用接口是实现这一交互的关键手段。不同的接口调用方式在速率上可能存在差异,这会影响用户体验和应用性能。本文将详细介绍几种常见的前台调用接口方式,并对它们的速…...
高级java每日一道面试题-2025年4月21日-基础篇[反射篇]-如何使用反射获取一个类的所有方法?
如果有遗漏,评论区告诉我进行补充 面试官: 如何使用反射获取一个类的所有方法? 我回答: 在Java中,反射是一种强大的机制,允许程序在运行时检查或“反射”自身,从而动态地操作类、字段、方法和构造函数等。这在需要动态调用方法…...
tomcat集成redis实现共享session
中间件:Tomcat、Redis、Nginx jar包要和tomcat相匹配 jar包:commons-pool2-2.2.jar、jedis-2.5.2.jar、tomcat-redis-session-manage-tomcat7.jar 配置Tomcat /conf/context.xml <?xml version1.0 encodingutf-8?> <!--Licensed to the A…...
2.6 递归
递归 特性: >.一递一归 >.终止条件 一般为:0 1 -1 #测试函数的返回值为函数 def test_recursion():return test_recursion() print(test_recursion()) RecursionError: maximum recursion depth exceeded #案例:计算 …...
鸿蒙应用开发:如何修改APP名称与APP的图标
如何修改APP的名称? 修改APP的名称需要修改entry/src/main/resources/base/element/string.json文件 将EntryAbility_label的value修改为“需要修改成的名字”。 文件目录: 代码修改: {"string": [{"name": "modu…...
AI 模型在前端应用中的典型使用场景和限制
典型使用场景 1. 智能表单处理 // 使用TensorFlow.js实现表单自动填充 import * as tf from tensorflow/tfjs; import { loadGraphModel } from tensorflow/tfjs-converter;async function initFormPredictor() {// 加载预训练的表单理解模型const model await loadGraphMod…...
前端性能优化全攻略:JavaScript 优化、DOM 操作、内存管理、资源压缩与合并、构建工具及性能监控
1 为什么需要性能优化? 1.1 性能优化的核心价值:用户体验与业务指标 性能优化不仅是技术层面的追求,更是直接影响用户体验和业务成败的关键因素。 用户体验(UX): 响应速度:用户期望页面加载时…...
使用 acme.sh 自动更新 SSL 证书的指南
上篇文章讲了一下 如何利用acme.sh来申请ssl,但没有讲3个月到期后 如何续期,续期的时候会碰到什么问题? 1.查看当前的当前签发域名的到期时间 acme.sh list 2.重新申请ssl acme.sh --issue --dns dns_namesilo -d xxx.ai -d *.xxx.ai --dns…...
查看Spring Boot项目所有配置信息的几种方法,包括 Actuator端点、日志输出、代码级获取 等方式,附带详细步骤和示例
以下是查看Spring Boot项目所有配置信息的几种方法,包括 Actuator端点、日志输出、代码级获取 等方式,附带详细步骤和示例: 1. 使用Spring Boot Actuator Actuator是Spring Boot提供的监控和管理工具,包含/configprops端点可查看…...
C++与C
文章目录 C与C命令空间const关键字new/delete表达式引用(重点)概念引用的本质引用的使用场景引用作为函数的参数引用作为函数的返回值 总结 强制转换函数重载extern "C"默认参数 bool类型inline(内联)函数异常处理&…...
Nginx中间件的解析
目录 一、Nginx的核心架构解析 二、Nginx的典型应用场景 三、Nginx的配置优化实践 四、Nginx的常见缺陷与漏洞 一、Nginx的核心架构解析 事件驱动与非阻塞IO模型 Nginx采用基于epoll/kq等系统调用的事件驱动机制,通过异步非阻塞方式处理请求,…...
Ansys Zemax | 在 MATLAB 中使用 ZOS-API 的技巧
附件下载 联系工作人员获取附件 本文将介绍一些在MATLAB中使用 ZOS-API 的技巧,以提高您的工作效率并充分利用 ZOS-API 的功能。 简介 OpticStudio开发了应用程序接口 (API) ,用户可以使用API与不同的脚本环境进行连接和交互。使用API,用…...