JavaScript元素相关
获取元素
根据标签id
document.getElementById();
根据标签名
document.getElementByTagName();
返回的是获取过来的元素对象集合,以伪数组的形式存储,可以采取遍历的方式来获取伪元素中的对象,得到的元素对象是动态的
还可以获取父元素内部所有指定标签名的子元素
父元素必须是单个对象,获取时不包括父元素自己
html5新增 获取元素
根据类名获取
document.getElementByClassName();
根据选择器
document.querySelector()
.ClassName
#idName
方法返回文档中与指定选择器或选择器组匹配的第一个 Element对象。 如果找不到匹配项,则返回null。
document.querySelectorAll()
指定选择器的所有元素对象
获取特殊元素body html
document.body()
document.documentElement()
事件基础
事件是可以被js侦测到的行为
触发–相应机制
三要素
事件源:事件被触发的对象
事件类型:如何触发
事件处理程序:通过函数赋值完成
<body>
<button id="btn">我是一个按钮</button>
<script>
var btn = document.getElementById('btn');
btn.onclick =function () {
alert('你好牛,真的按到我了呢!');
}
</script>
</body>
执行事件的过程
- 获取事件源
- 注册事件、绑定事件
- 添加事件处理程序
操作元素
element.innerText()
从起始位置到终止位置的内容,不包括html标签,去除空格和换行
element.innerHtml()
W3C标准
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
这两个元素可读写
例子
如果是要按按钮触发图片的更换,应该也获取图片这一元素
图片地址后面要加.jpg
<button id="hh">我是按钮1</button>
<button id="xx">我是按钮2</button>
<img src="./pic/abcd.jpg" alt="">
<script>
var img =document.querySelector('img');
var hhh = document.getElementById('hh');
hhh.onclick = function() {
img.src = './pic/pic2.jpg';
}
var xxx = document.getElementById('xx');
xxx.onclick = function() {
img.src = './pic/pic1.jpg';
}
</script>
<img src="./pic/morning.png" alt="">
<div>Happy Everyday</div>
<script>
var img = document.querySelector('img');
var div = document.querySelector('div');
var date = new Date();
var h = date.getHours();
if(h<12) {
img.src = './pic/morning.png';
div.innerHTML = '早上好哦宝贝';
}
else if(h < 18) {
img.src = './pic/fighting.png';
div.innerHTML = '下午好哦宝贝'
} else {
img.src = './pic/evening.png';
div.innerHTML = '晚上好哦宝贝'
}
</script>
<body>
<button>我是一个可爱的按钮(●'◡'●)</button>
<input type="text" value="你要输入啥呢">
<script>
var btn = document.querySelector('button');
var input = document.querySelector('input');
btn.onclick = function() {
//input.innerHTML=''; 这个是普通盒子比如div标签元素里面的内容,表单里面的值是通过value修改的
input.value='哎呀,我被点击了!';
btn.disabled = true ;
}
btn.onmouseout = function() {
input.value='不要走,嘤嘤嘤';
}
</script>
</body>
btn.disabled = true ;
表单禁用
this.disabled = true ;
this指向的是表单的调用者 btn
样式属性操作
我们可以通过js修改元素的大小颜色和样式
element.style : 样式比较少,功能简单
element.className : 将样式写入CSS,js只用添加这个样式即可,会直接覆盖原先的类名,要想保留,就两个类名都写上,中间用空格隔开(多类名选择器)
this.className = 'change' ;
- js里面的样式采取驼峰命名法
- js修改style的样式产生的是行内样式,CSS权重比较高
例子:搜索栏
<style>
input {
color: #999;
}
</style>
</head>
<body>
<input type="text" value="手机" name="" id="">
<script>
var text = document.querySelector('input');
// 获得焦点事件
text.onfocus = function () {
if(text.value === '手机') {
this.value = ' ';
}
//获得焦点把文本框颜色变深
this.style.color = '#333';
}
text.onblur = function () {
if(text.value === ' ') {
this.value = '手机';
}
this.style.color = '#999';
}
</script>
</body>
例子:密码框明文密文转换
<style>
.box {
position: relative;
width: 400px;
/* border : 1px solid #ccc; */
margin: 100px;
}
.box input {
width: 370px;
height: 30px;
border: 0;
outline: none;
}
.box img {
position: absolute;
top: 2px;
right: 2px;
width: 24px;
}
</style>
</head>
<body>
<div class="box">
<label for="">
<img src="./pic/images1/close.png" alt="" id="eye">
</label>
<input type="password" id="pwd">
</div>
<script>
var eye =document.getElementById('eye');
var pwd =document.getElementById('pwd');
// 元素多用id获取元素
let flag=0;
eye.onclick = function () {
if(flag == 0) {
pwd.type ='text';
eye.src ='./pic/images1/open.png';
flag=1;
} else {
pwd.type ='password';
eye.src ='./pic/images1/close.png';
flag=0;
}
}
</script>
</body>
排他思想
如果有同一组元素,要实现某个同样的样式,需要用到循环的排他思想算法
- 所有元素全部清除样式
- 给当前元素设置样式
- 注意不能颠倒顺序
例子:按钮换色
<body>
<button>我是按钮</button>
<button>我是按钮</button>
<button>我是按钮</button>
<button>我是按钮</button>
<button>我是按钮</button>
<script>
var btn= document.getElementsByTagName('button');
for(let i=0;i<btn.length;i++) {
btn[i].onclick = function () {
for(let j=0;j<btn.length;j++) {
btn[j].style.backgroundColor='';
// 这里不能留空。。。不然会设置颜色回默认失败
}
btn[i].style.backgroundColor='pink';
}
}
</script>
</body>
例子:换背景图
例子:表格高亮
例子:表单全选和取消全选
<body>
<div class="box">
<table>
<thead>
<tr>
<td><input type="checkbox" id="j_cbAll"></td>
<th>goods</td>
<th>price</td>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td><input type="checkbox"></td>
<td>iphone</td>
<td>2000</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>ipad</td>
<td>3000</td>
</tr>
<tr>
<td><input type="checkbox"></td>
<td>MacBook</td>
<td>2500</td>
</tr>
</tbody>
</table>
</div>
<script>
var j_cbAll = document.getElementById('j_cbAll');
var j_tbs = document.getElementById('j_tb').getElementsByTagName('input');
j_cbAll.onclick = function() {
console.log(this.checked) ;//得到当前复选框的选定状态
for(let i=0;i<j_tbs.length;i++) {
j_tbs[i].checked = this.checked;
}
}
for(let j=0;j<j_tbs.length;j++) {
j_tbs[j].onclick = function () {
let flag=true;
for(let k=0;k<j_tbs.length;k++) {
if(!j_tbs[k].checked) {
flag=false;
break;
}
}
j_cbAll.checked=flag;
}
}
</script>
</body>
自定义属性操作
获取
element.属性
获取内置属性值–元素本身自带的属性
element.getAttribute(‘属性’)
程序员自行添加的属性称为自定义属性(data-index)
设置
element.属性=‘值’;
element.setAttribute(‘属性’,‘值’)
修改clss时修改的是’Class’不是’ClassName’
移除
element.removeAttribute(‘属性’);
例子:tab栏切换
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
.tab {
width: 978px;
margin: 100px auto;
}
.tab_list {
height: 39px;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab_list li {
float: left;
height: 39px;
line-height: 39px;
padding: 0 20px;
text-align: center;
cursor: pointer;
}
.tab_list .current {
background-color: #c81623;
color: #fff;
}
.item_info {
padding: 20px 0 0 20px;
}
.item {
display: none;
}
</style>
</head>
<body>
<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价(50000)</li>
<li>手机社区</li>
</ul>
</div>
<div class="tab_con">
<div class="item" style="display: block;">
<!-- <div class="item"> -->
商品介绍模块内容
</div>
<div class="item">
规格与包装模块内容
</div>
<div class="item">
售后保障模块内容
</div>
<div class="item">
商品评价(50000)模块内容
</div>
<div class="item">
手机社区模块内容
</div>
</div>
</div>
<script>
var tab_list = document.querySelector('.tab_list');
var lis = tab_list.querySelectorAll('li');
var items = document.querySelectorAll('.item');
for(let i=0;i<lis.length;i++) {
lis[i].setAttribute('index',i);
lis[i].onclick = function() {
for(let j=0;j<lis.length;j++) {
console.log('hi');
lis[j].className=' ';
//这里需要空格来置空or不留空格都行。。,注意Class的写法qwq
}
this.className='current';
var index=this.getAttribute('index');
for(let j=0;j<items.length;j++) {
items[j].style.display='none';
}
items[index].style.display='block';
}
}
</script>
html5自定义属性
为了保存并使用数据,有些数据可以保存到页面中而不可以保存到数据库里
h5规定自定义属性以data-开头为属性名并赋值
dataset是一个集合,存放了所有以data-开头的自定义属性,ie11才开始使用
element.dataset.index
element.dataset[‘index’]
如果自定义属性里面有多个链接的单词采用驼峰命名法
节点操作
父节点
node.parentNode 可以返回某节点的父节点,是距离最近的一个父节点,如果指定节点没有父节点,则返回null
子节点
node.childNodes (换行属于文本节点)包括所有子节点,包括文本(nodeType3)、元素结点(nodeType1)
node.children 是一个只读属性,返回所有子元素结点,其余节点不返回
第一个和最后一个子元素
node.firstChild:返回的是子节点,不管是文本还是元素结点
node.lastChild:返回的是子节点,不管是文本还是元素结点
node.firstElementChild:返回的是子元素节点,ie9以上使用
node.LastElementChild
实际使用:
node.children[0]
node.children[node.children.length-1]
例子:下拉菜单
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
}
a {
text-decoration: none;
font-size: 14px;
}
.nav {
margin: 100px;
}
.nav>li {
position: relative;
float: left;
width: 80px;
height: 41px;
text-align: center;
}
.nav li a {
display: block;
width: 100%;
height: 100%;
line-height: 41px;
color: #333;
}
.nav>li>a:hover {
background-color: #eee;
}
.nav ul {
display: none;
position: absolute;
top: 41px;
left: 0;
width: 100%;
border-left: 1px solid #FECC5B;
border-right: 1px solid #FECC5B;
}
.nav ul li {
border-bottom: 1px solid #FECC5B;
}
.nav ul li a:hover {
background-color: #FFF5DA;
}
</style>
</head>
<body>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
<li>
<a href="#">微博</a>
<ul>
<li>
<a href="">私信</a>
</li>
<li>
<a href="">评论</a>
</li>
<li>
<a href="">@我</a>
</li>
</ul>
</li>
</ul>
<script>
var nav = document.querySelector('.nav');
var lis = nav.children;
for(let 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';
}
}
</script>
兄弟节点
node.nextSibling:返回当前元素下一个兄弟节点,找不到则返回null,同样也是包含所有节点
node.previousSibling
node.nextElementSibling
node.previousElementSibling
兼容性问题:自己封装一个兼容性函数
function getNextElementSibling(element) {
var el =element;
while(el=el.nextSibling) {
if(el.nodeType == 1) {
return e1;
}
}
return null;
}
创建节点
document.createElement(’ ');创建由tagName指定的HTML元素,因为这些元素原先不存在,是根据我们需求动态生成的,因此也成为动态创建元素节点
添加节点
**node.appendChild(child);**将一个节点添加到指定父元素的子节点列表末尾
node.insertBefore(child,指定元素);
例子:评论发布
<textarea name="" id=""></textarea>
<button>发布</button>
<ul></ul>
<script>
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 {
let li =document.createElement('li');
li.innerHTML = text.value;
ul.insertBefore(li,ul.children[0]);
}
}
</script>
删除节点
node.removeChild(child);
阻止链接跳转
javascript:;
javascript:void(0);
例子:评论删除
<script>
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 {
let li =document.createElement('li');
li.innerHTML = text.value + "<a href='javascript:;'>删除</a>";
ul.insertBefore(li,ul.children[0]);
}
var as = document.querySelectorAll('a');
// 这个不能写在里面,因为每点击一次发布就得检索按钮的个数;写在外面的话程序运行一次就结束了,没有检索到按钮的个数
for(let i=0;i<as.length;i++) {
as[i].onclick = function() {
// a所在的li即是a的父节点
ul.removeChild(this.parentNode);
}
}
}
</script>
删除按钮不能正常运行的原因:因为每点击一次发布就得检索按钮的个数;写在外面的话程序运行一次就结束了,没有检索到按钮的个数
复制节点
node.cloneNode();
该方法返回调用该方法的结点的一个副本
如果括号为空或者里面为false则为浅拷贝,只复制节点本身,不克隆里面的子节点
参数为true则为深拷贝
例子:动态生成表格
<body>
<table>
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
<script>
var datas =[{
name : '黄小迪',
subject : 'java',
score :100
},{
name : '黄小瑜',
subject : 'javascript',
score :100
},{
name : '黄小鱼',
subject : 'C++',
score :100
}]
console.log(datas.length);
var tbody =document.querySelector('tbody');
for(let i=0;i<datas.length;i++) {
// 创建行
var tr =document.createElement('tr');
tbody.appendChild(tr);
for(let j in datas[i]) {
// 行里面创建单元格
let td = document.createElement('td');
// 把对象里面的属性值 给td
td.innerHTML = datas[i][j];
tr.appendChild(td);
}
let td = document.createElement('td');
td.innerHTML='<a href="javascript:;">删除</a>'
tr.appendChild(td);
}
var as = document.querySelectorAll('a');
for(let i=0;i<as.length;i++) {
as[i].onclick = function() {
//点击a删除a所在的行,链接的父节点的父节点
tbody.removeChild(this.parentNode.parentNode);
}
}
</script>
</body>
三种创建元素的方式区别:
document.write();
document.write(<div>111</div>)
直接将内容写入页面的内容流,文档流执行完毕,会导致页面重绘
innerHTML
将内容写入某个DOM结点,不会导致页面重绘,创建多个元素效率更高(不采用拼接字符串,而是数组形式拼接),结构稍微复杂
document.createElement()
创建多个元素效率稍低,但是结构清晰