DOM和事件案例分析
元素居中效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 400px;
height: 100px;
border: 1px solid red;
background: #ffc0cb;
padding: 10px;
position: absolute;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
var box = document.querySelector('.box');
//浏览器的宽度 - 盒子的宽度 除以2 设置为 盒子的left
center(box)
// 当窗口变化的时候也要实现居中的效果
window.onresize = function () {
center(box)
}
// 实现一个居中效果的函数
function center(ele) {
// 获取浏览器的宽高
var winHeight = window.innerHeight;
var winWidth = window.innerWidth;
// 获取元素的宽高
var eleWidth = ele.offsetWidth;
var eleHeight = ele.offsetHeight;
// console.log(eleWidth, eleHeight)
ele.style.left = (winWidth - eleWidth) / 2 + 'px';
ele.style.top = (winHeight - eleHeight) / 2 + 'px';
}
</script>
</body>
</html>
可编辑表格
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>动态生成表格</title>
<style>
table {
margin-top: 20px;
width: 800px;
border: 1px solid #ddd;
border-collapse: collapse;
}
td,
th {
border: 1px solid #ddd;
padding: 5px 10px;
}
td {
padding: 0;
height: 30px;
}
td input {
width: 100%;
height: 30px;
border: none;
background-color: #ffc;
}
</style>
<script>
window.onload = function () {
/*
动态生成可编辑表格
1)生成表格
1>序号
1-n
2>数据
根据输入值确定数据
3>删除
显示删除按钮
2)表格编辑
1>点击td时,生成一个输入框
2>把td的内容赋值给输入框
3>把输入框添加到td
3)保存编辑
把输入框的值写入td
*/
// 获取页面元素
var username = document.getElementById('username');
var age = document.getElementById('age');
var tel = document.getElementById('tel');
var qq = document.getElementById('qq');
var btnSave = document.getElementById('btnSave');
var tableList = document.getElementById('tableList');
var tbody = tableList.children[1];
// 序号
var index = 1;
// 1)生成表格
// 点击保存按钮生成表格
btnSave.onclick = function () {
// 生成一行
var tr = document.createElement('tr');
// 给可编辑的表格添加 class名 为 name
tr.innerHTML = '<td>' + index++ + '</td><td class="name">' + username.value + '</td><td class="name">' + age.value + '</td><td class="name">' + tel.value + '</td><td class="name">' + qq.value + '</td><td><button class="btnDel">删除</td>';
// 往表格里添加行
tbody.appendChild(tr);
// 删除操作
// 获取删除按钮
var btnDel = document.getElementsByClassName('btnDel');
// 绑定点击事件,移除tr
for (var i = 0; i < btnDel.length; i++) {
btnDel[i].onclick = function () {
tbody.removeChild(this.parentNode.parentNode);
}
}
// 给一个标识 标标识td中是否 有input元素
var flag = false
// 获取class名为 name 的td 绑定点击事件,然后 编辑表格
var $name = document.querySelectorAll('.name');
// 绑定点击事件, 和编辑内容
$name.forEach(function (item, index) {
item.onclick = function () {
// 如果td中没有input元素就添加 input元素
if (!flag) {
// 点击的时候可编辑 td内容
// 所有的标签中 只有input 和 textarea能页面中写内容
var input = document.createElement('input');
// 拿到原来td的内容 给到input
input.value = item.innerHTML;
// 把td的内容清空
item.innerHTML = ''
// 把input添加到 点击的这个元素中
item.appendChild(input);
// input自动获取焦点
input.focus();
// 添加input元素之后 把这个标识改为true,表示已经有input了
flag = true
}
// 当input失去焦点的时候 ,移出input元素 ,并且input的内容给到td
input.onblur = function () {
// 当失去焦点 移出input之后,把标识改为 false,表示 td中没有input元素了
flag = false
// item.innerHTML = input.value
// 拿input.value 来替换 item的所有内容
item.innerHTML = input.value
}
}
})
}
}
</script>
</head>
<body>
<label for="username">姓名</label>
<input type="text" id="username" name="username">
<label for="age">年龄</label>
<input type="text" id="age" name="age">
<label for="tel">电话</label>
<input type="text" id="tel" name="tel">
<label for="qq">QQ号</label>
<input type="text" id="qq" name="qq">
<button id="btnSave">保存</button>
<div class="list">
<table id="tableList">
<thead>
<tr>
<th width="40">序号</th>
<th width="160">姓名</th>
<th width="60">年龄</th>
<th width="160">电话</th>
<th width="160">QQ号</th>
<th width="60">操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
</body>
</html>
事件委托实现表格的复制和删除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
table {
width: 100%;
border: 1px solid #ccc;
border-collapse: collapse;
border-spacing: 0px;
}
table td {
border: 1px solid #ccc;
height: 30px;
}
</style>
</head>
<body>
<div class="box">
<h1>的使用创建dom节点动态生成表格</h1>
<label for="">行:</label>
<input type="text" id="row">
<label for="">列:</label>
<input type="text" id="col">
<input type="button" id="btn" value="生成">
<div id="output">
<!-- <table>
<tbody>
<tr>
<td>浮动法</td>
</tr>
</tbody>
</table> -->
</div>
</div>
<script>
/*
【1】先获取页面中你需要用到的元素
【2】点击生成的时候根据行和列数生成 表格
【2】拿到输入框的值
【2】根据值循环生成表格
【3】点击表格中的 复制 和删除按钮
复制:复制整行 添加 tbody
删除:把整行从tbody里面删除
*/
// 【1】先获取页面中你需要用到的元素
var output = document.querySelector('#output');
var btn = document.querySelector('#btn');
var row = document.querySelector('#row');
var col = document.querySelector('#col');
// 生成table 和tbody
var table = document.createElement('table');
var tbody = document.createElement('tbody');
// 把tbody放入table中
table.appendChild(tbody);
// 【2】点击生成的时候根据行和列数生成 表格
btn.onclick = function () {
// 1】拿到输入框的值
var _row = row.value;
var _col = col.value;
renderTable(_row, _col);
// 需要点击复制和删除按钮 ,必须保证页面中有这个两个按钮
// 等页面渲染完成之后才能执行这个操作
// 在获取元素 绑定事件
}
// 事件委托:给父元素output元素绑定事件
output.onclick = function (e) {
// 判断点击的是复制按钮,实现克隆元素
if (e.target.className === 'copy') {
var newTr = e.target.parentNode.parentNode.cloneNode(true);
tbody.appendChild(newTr)
}
// 判断点击的时候删除按钮 实现删除元素
if (e.target.className === 'delete') {
// e.target就是鼠标点击的元素
e.target.parentNode.parentNode.remove();
}
}
function renderTable(_row, _col) {
// 2】循环生成行和列
for (var i = 0; i < _row; i++) {
var tr = document.createElement('tr');
// 循环生成列数
for (var j = 0; j < _col; j++) {
var td = document.createElement('td');
td.innerHTML = '单元格' + i + j;
tr.appendChild(td);
}
// 多一列出来 存放删除和赋值按钮
var _td = document.createElement('td');
var copyEle = document.createElement('button');
// 给元素绑定给一个id属性
copyEle.className = 'copy';
copyEle.innerHTML = '复制';
var deleteEle = document.createElement('button');
deleteEle.className = 'delete';
deleteEle.innerHTML = '删除'
_td.appendChild(copyEle);
_td.appendChild(deleteEle);
// 把这个的多出来的列也放入 tr
tr.appendChild(_td)
// 把生成的tr放入tbody中
tbody.appendChild(tr);
}
// 把table放入output里面
output.appendChild(table);
}
</script>
</body>
</html>
右键菜单事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul {
list-style: none;
padding: 0;
margin: 0;
}
.contextMenu {
display: none;
position: absolute;
top: 0;
left: 0;
padding: 2px;
width: 220px;
border: 1px solid #ddd;
}
.contextMenu li {
position: relative;
padding-left: 10px;
border-bottom: 1px dotted #ddd;
line-height: 2.2;
}
.contextMenu li:hover {
background-color: #efefef;
}
.contextMenu li:last-child {
border: none;
}
.contextMenu li span {
position: absolute;
right: 5px;
top: 0;
color: #999;
}
</style>
</head>
<body>
<div class="contextMenu">
<ul>
<li class="copy">复制<span>Ctrl+C</span></li>
<li class="paste">粘贴<span>Ctrl+V</span></li>
<li class="cut">剪切<span>Ctrl+X</span></li>
<li class="delete">删除<span>Del</span></li>
<li class="save">保存<span>Ctrl+S</span></li>
</ul>
</div>
<script>
// 点击右键的时候 阻止默认的菜单 显示我们自定义的菜单
// contextmenu 右键事件 菜单事件
var contextMenu = document.querySelector('.contextMenu');
window.oncontextmenu = function (e) {
//阻止默认事件
e.returnValue = false;
contextMenu.style.display = 'block'
contextMenu.style.left = e.clientX + 'px';
contextMenu.style.top = e.clientY + 'px'
}
window.onclick = function (e) {
if (e.target.className === 'copy') {
alert('复制功能')
}
contextMenu.style.display = 'none'
}
</script>
</body>
</html>
发送信息案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.box {
width: 800px;
margin: auto;
}
.box .content {
width: 100%;
height: 350px;
border: 1px solid #ccc;
margin: 20px auto;
padding: 10px;
box-sizing: border-box;
}
.box .content li {
margin: 10px 0;
padding: 5px;
line-height: 2;
border-radius: 5px;
clear: both;
}
.box textarea {
height: 80px;
display: block;
margin: auto;
margin-top: 20px;
width: 100%;
}
.box button {
width: 80px;
height: 30px;
border: 1px solid #ccc;
float: right;
margin-top: 10px;
}
.active {
float: right;
background-color: #fc0;
color: #fff;
}
p {
color: #ccc;
font-size: 12px;
}
</style>
</head>
<body>
<div class="box">
<ul class="content"></ul>
<textarea name="" id="text" cols="30" rows="10"></textarea>
<button id="btn">发送</button>
<p>温馨提示:按 ctrl + shift键也可以发送消息哟</p>
</div>
<script>
/*
【1】点击发送按钮的时候 获取输入框的信息
【2】把信息 写入 content里面
*/
// 获取所需要的元素
var content = document.querySelector('.content');
var text = document.querySelector('#text');
var btn = document.querySelector('#btn');
// 给按钮绑定点击事件
btn.onclick = function () {
if (text.value) {
renden()
} else {
alert('请输入内容')
}
}
// 按下ctrl + shift键也可以发送信息
text.onkeydown = function (e) {
// console.log(e.ctrlKey);
// keydown 可以同时监听多个按下的事件
if (e.ctrlKey && e.shiftKey) {
if (text.value) {
renden()
} else {
alert('请输入内容')
}
}
}
function renden() {
// 获取输入框的内容 并且还要创建一个元素来接收内容
var li = document.createElement('li');
li.className = 'active';
li.innerHTML = text.value;
// 把创建的这个标签写入 content
content.appendChild(li);
// 清空输入框的内容
text.value = ''
}
</script>
</body>
</html>
根据数据生成表单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="" id="form"></form>
<!-- <p>
<label for="">用户名:</label>
<input type="text">
</p>
<p>
<label for="">密码:</label>
<input type="password">
</p> -->
<script>
var arr = [
{
label: "用户名",
name: "username",
type: "text"
}, {
label: "密码",
name: "password",
type: "password"
}, {
label: "性别",
name: "gender",
type: "select",
value: ['男', '女', '不男', '不女', 'Gay', '妖王']
}, {
label: "爱好",
name: "hobby",
type: "checkbox",
value: ['篮球', '足球', '羽毛球', '兵乓球', '爬山', '购物', '旅游', '看美女']
}, {
label: '是否已婚',
name: 'married',
type: 'radio',
value: ['已婚', '未婚']
},
{
label: '简介',
name: 'resume',
type: 'textarea'
}];
var form = document.querySelector('#form');
// 循环数组 根据数组的数据生成表单
arr.forEach(function (item, index) {
// 生成一个p标签
var p = document.createElement('p');
var label = document.createElement('label');
label.innerHTML = item.label + ':';
p.appendChild(label);
var input;//不能直接创建input标签,
// 而是根据 数组对象中 type类型来判断我到底生成什么的标签
// type为 text,password就生input
// 如果为 radio,checkbox 就生成 span标签,然后根据对象中的value循环生成input元素
// type 为select 生成 select标签
// type 为 textarea 生成textarea
switch (item.type) {
case 'text':
case 'password':
input = document.createElement('input');
input.type = item.type;
input.id = item.name;
p.appendChild(input)
break
case 'radio':
case 'checkbox':
// 要来包裹爱好 value循环生成的值
input = document.createElement('span');
item.value.forEach(function (items, index) {
var inp = document.createElement('input');
// 存放文字
var text = document.createElement('label');
text.innerHTML = items;
inp.type = item.type;
// 给input添加name属性,实现单选按钮的切换
inp.name = item.name
input.appendChild(inp);
input.appendChild(text);
})
p.appendChild(input)
break
case 'select':
input = document.createElement('select');
// 循环对象中的value 生成option标签
item.value.forEach(function (items, index) {
var option = document.createElement('option');
option.innerHTML = items;
input.appendChild(option)
})
p.appendChild(input)
break
case 'textarea':
input = document.createElement('textarea');
p.appendChild(input)
}
// 把p标签 添加到form中
form.appendChild(p)
})
</script>
</body>
</html>
补充:编辑表格
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.main,
table {
width: 800px;
margin: 0 auto;
}
.main {
height: 40px;
line-height: 40px;
}
table,
th,
td {
border: 2px solid black;
border-collapse: collapse;
}
.optd {
width: 200px;
}
input {
font-size: 14px;
height: 20px;
border-radius: 2px;
border: 1px solid;
margin: 2px;
}
.addTable {
padding: 10px;
position: fixed;
top: 0px;
left: 0px;
bottom: 0px;
right: 0px;
background: rgba(21, 20, 20, 0.2);
display: none;
}
.addTable table {
text-align: center;
margin-bottom: 10px;
position: absolute;
top: 50%;
left: 50%;
background: #fff;
transform: translate(-50%, -50%);
}
.confirm {
position: absolute;
top: 60%;
left: 50%;
width: 800px;
transform: translateX(-50%);
text-align: center;
height: 40px;
line-height: 40px;
}
.confirm input {
height: 40px;
width: 100px;
}
</style>
</head>
<body>
<div class="main">
<input type="button" value="新增一行" id="add" />
</div>
<table id="table">
</table>
<div class="addTable" id="addRow">
<table>
<!-- <tr>
<th>学号</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
</tr>
<tr>
<td><input type="text" id="number" /></td>
<td><input type="text" id="name" /></td>
<td>
<select id="gender">
<option>男</option>
<option>女</option>
</select>
</td>
<td><input type="text" id="age" /></td>
</tr> -->
</table>
<div class="confirm">
<input type="button" value="确定" id="sure" />
<input type="button" value="取消" id="cancle" />
</div>
</div>
<script>
function $id(id) {
return document.getElementById(id);
}
// 兼容
function setInnerText(element, text) {
if (element.innerText !== undefined) {
element.innerText = text;
} else {
element.textContent = text;
}
}
function getInnerText(element) {
if (element.innerText !== undefined) {
return element.innerText;
} else {
return element.textContent;
}
}
var head = ["学号", "姓名", "性别", "年龄", "操作"];
var data = [
{ "number": "001", "name": "张三", "gender": "男", "age": 16 },
{ "number": "002", "name": "王五", "gender": "女", "age": 17 },
{ "number": "003", "name": "李葫芦", "gender": "男", "age": 15 },
{ "number": "004", "name": "小明", "gender": "男", "age": 18 },
{ "number": "005", "name": "小红", "gender": "女", "age": 16 }
];
var table = $id("table");
var headtr = document.createElement("tr");
table.appendChild(headtr);
// 循环给headtr里面添加th
for (var i = 0; i < head.length; i++) {
var th = document.createElement("th");
setInnerText(th, head[i]);
headtr.appendChild(th);
}
// data数据,调用函数createRow
for (var i = 0; i < data.length; i++) {
var tr = createRow(data[i]);
table.appendChild(tr);
}
function moveUp() {
var tr = this.parentNode.parentNode;
var previous = tr.previousElementSibling;
if (previous.previousElementSibling) {
table.insertBefore(tr, previous);
} else {
alert("已经是第一行了");
}
}
function moveDown() {
var tr = this.parentNode.parentNode;
var next = tr.nextElementSibling;
if (next) {
if (next.nextElementSibling) {
table.insertBefore(tr, next.nextElementSibling);
} else {
table.appendChild(tr);
}
} else {
alert("已经是最后一行了!!")
}
}
function deleteRow() {
var res = confirm("确定要删除?");
if (res) {
var tr = this.parentNode.parentNode;
table.removeChild(tr);
}
}
// 添加绑定事件
$id("add").onclick = function () {
$id("addRow").style.display = "block";
}
$id("sure").onclick = function () {
var number = $id("number").value;
var name = $id("name").value;
var opts = $id("gender").getElementsByTagName("option");
var gender;
for (var i = 0; i < opts.length; i++) {
if (opts[i].selected) {
gender = getInnerText(opts[i]);
break;
}
}
var age = $id("age").value;
var obj = {
number: number,
name: name,
gender: gender,
age: age
};
var tr = createRow(obj);
table.appendChild(tr);
$id("addRow").style.display = "none";
}
// 封装createRow函数
function createRow(obj) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var key in obj) {
var td = document.createElement("td");
setInnerText(td, obj[key]);
tr.appendChild(td);
}
var optd = document.createElement("td");
optd.className = "optd";
var up = document.createElement("input");
up.type = "button";
up.value = "向上移动";
up.onclick = moveUp;
optd.appendChild(up);
var down = document.createElement("input");
down.type = "button";
down.value = "向下移动";
down.onclick = moveDown;
optd.appendChild(down);
var del = document.createElement("input");
del.type = "button";
del.value = "删除";
del.onclick = deleteRow;
optd.appendChild(del);
tr.appendChild(optd);
return tr;
}
// 取消按钮绑定事件
$id("cancle").onclick = function () {
$id("addRow").style.display = "none";
}
</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>
* {
padding: 0;
margin: 0;
}
html,
body {
height: 100%;
}
ul,
li {
list-style: none;
}
.box {
display: flex;
justify-content: space-evenly;
align-items: center;
height: 0px;
background: #ddd;
overflow: hidden;
transition: height 1s;
}
.box1 {
height: 240px
}
.box li {
width: 300px;
}
.box li img {
width: 100%;
}
</style>
</head>
<body>
<ul class="box" style="background:#ddd no-repeat center center">
<li><img src="images/1.jpg" alt=""></li>
<li><img src="images/2.jpg" alt=""></li>
<li><img src="images/3.jpg" alt=""></li>
</ul>
<button class="btn">换肤</button>
<script>
/*
换肤案例:
【1】点击换肤的时候,显示图片的容器(改变高度)
高度为0 隐藏
高度为240 显示 .box{height:240px}
当盒子没有box1的时候那么久给元素添加box1名,如果有box就移出box1
【2】点击图片的时候,把图片的路径给到 body
// box.className += 'box1'
// if (flag) {
// box.classList.remove('box1');
// flag = false;
// } else {
// box.classList.add('box1');
// flag = true;
// }
// classList 获取元素class属性的一些方法的对象
// classlist.add() 添加
// classlist.remove() 移出
// classlist.toggle() 转换,有就移出,没有就添加
*/
let btn = document.querySelector('.btn');
let box = document.querySelector('.box');
var flag = false;
btn.onclick = function () {
box.classList.toggle('box1');
}
box.onclick = function (e) {
document.body.style.background = 'url(' + e.target.src + ') no-repeat center center / 100% 100%';
box.classList.toggle('box1')
}
</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>
html,
body {
overflow: hidden;
}
body,
div,
h2,
p {
margin: 0;
padding: 0;
}
body {
color: #fff;
background: #000;
font: 12px/2 Arial;
}
p {
padding: 0 10px;
margin-top: 10px;
}
span {
color: #ff0;
padding-left: 5px;
}
#box {
position: absolute;
width: 300px;
height: 150px;
background: #333;
border: 2px solid #ccc;
}
#box h2 {
height: 25px;
line-height: 25px;
cursor: move;
/*手型:移动*/
background: #222;
border-bottom: 2px solid #ccc;
text-align: right;
padding: 0 10px;
}
#box h2 a {
color: #fff;
font: 12px/25px Arial;
text-decoration: none;
outline: none;
}
</style>
</head>
<body>
<div id="box">
<h2><a href="#">点击回放拖动轨迹</a></h2>
<p><strong>Drag:</strong><span>false</span></p>
<p><strong>offsetLeft:</strong><span>0</span></p>
<p><strong>offsetTop:</strong><span>0</span></p>
</div>
<script>
window.onload = function () {
/*
两个阶段:
【1】拖拽阶段
1.在元素上按下 mousedown,同时给document添加 mousemove 事件
记录光标在元素上的位置
2.但在元素上鼠标抬起 mouseup,解除 document的 mousemove 事件
3.mousemove过程,将盒子的 左边和上边的位置 以对象的形式存在数组中
【2】回放阶段
1.点击回放的时候,把存入数组中的 数据一次取出添加给 元素
*/
var box = document.getElementById('box');
var h2 = box.children[0];
var dragSpan = box.children[1].children[1];
var leftSpan = box.children[2].children[1];
var topSpan = box.children[3].children[1];
var links = h2.children[0];
var arr = [];
// 给h2绑定点击事件
h2.onmousedown = function (e) {
// console.log(1);
var obj = {};
obj.x = box.offsetLeft;
obj.y = box.offsetTop;
arr.push(obj);
// 获取点击时候,光标在元素上的位置
var ox = e.offsetX;
var oy = e.offsetY;
dragSpan.innerHTML = 'true';
document.onmousemove = function (evt) {
box.style.left = evt.clientX - ox + 'px'
box.style.top = evt.clientY - oy + 'px';
leftSpan.innerHTML = evt.clientX - ox;
topSpan.innerHTML = evt.clientY - oy;
var obj = {};
obj.x = evt.clientX - ox;
obj.y = evt.clientY - oy;
arr.push(obj);
}
}
document.onmouseup = function () {
document.onmousemove = null;
dragSpan.innerHTML = 'false'
}
links.onclick = function () {
clearInterval(links.timer);
var i = 0;
links.timer = setInterval(function () {
box.style.left = arr[i].x + 'px';
box.style.top = arr[i].y + 'px';
leftSpan.innerHTML = arr[i].x;
topSpan.innerHTML = arr[i].y;
i++;
if (i === arr.length) {
clearInterval(links.timer);
arr = [];
}
}, 10)
}
}
</script>
</body>
</html>
元素在窗口内拖拽(不超出窗口范围)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
width: 110px;
height: 100px;
background: pink;
position: absolute;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
/*
1.当鼠标在box盒子按下的时候
2.并且鼠标window中移动时候 box元素跟着鼠标一起移动
*/
var box = document.querySelector('.box');
box.onmousedown = function () {
console.log(1);
// 按下之后 在window中移动
window.onmousemove = function (e) {
// box元素跟着光标移动
// 获取光标在可视窗口的坐标
e = e || window.event;
// box.offsetWidth / 2 盒子宽度的一半
// box.offsetHeight /2 盒子高度的一半
var x = e.clientX - box.offsetWidth / 2;
var y = e.clientY - box.offsetHeight / 2;
// 边界值的判断
// 当l盒子的left 和top 小于0 的时候,直接强制等于0
// left 和 top的极限值为0
if (x <= 0) {
x = 0;
}
if (y <= 0) {
y = 0;
}
// 判断left的最大极限 浏览器的宽度 - 盒子的宽度
if (x >= window.innerWidth - box.offsetWidth) {
x = window.innerWidth - box.offsetWidth
}
//判断top的极限值
if (y >= window.innerHeight - box.offsetHeight) {
y = window.innerHeight - box.offsetHeight
}
// 然后把这个值赋值给box的left和top值
box.style.left = x + 'px';
box.style.top = y + 'px'
}
}
// 当鼠标在任何位置抬起来的时候,要把移动事件清除
window.onmouseup = function () {
//清除一个事件,只需要将事件的值设置null
window.onmousemove = null;
};
</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>
ul {
list-style: none;
padding: 0;
margin: 0;
}
body {
background: #23384e;
font: 12px/1.5 \5fae\8f6f\96c5\9ed1;
}
.search,
.search .inner-box,
.search .box,
.search .select,
.search a {
background: url(images/search.jpg) no-repeat;
}
.search,
.search .box,
.search .inner-box {
height: 34px;
}
.search {
position: relative;
width: 350px;
margin: 10px auto;
}
.search .box {
background-position: right 0;
}
.search .inner-box {
background-repeat: repeat-x;
background-position: 0 -34px;
margin: 0 20px 0 40px;
}
.search .select {
float: left;
color: #fff;
width: 190px;
height: 22px;
border: none;
cursor: pointer;
margin-top: 4px;
line-height: 22px;
padding-left: 10px;
background-position: 0 -68px;
}
.search a {
float: left;
width: 80px;
height: 24px;
color: #333;
letter-spacing: 4px;
line-height: 22px;
text-align: center;
text-decoration: none;
background-position: 0 -90px;
margin: 4px 0 0 10px;
}
.search a:hover {
color: #f60;
background-position: -80px -90px;
}
.search ul {
position: absolute;
top: 26px;
left: 40px;
color: #fff;
width: 198px;
background: #2b2b2b;
border: 1px solid #fff;
display: none;
}
.search ul li {
height: 25px;
line-height: 24px;
cursor: pointer;
padding-left: 10px;
margin-bottom: -1px;
border-bottom: 1px dotted #fff;
}
.search ul li:hover,
.search ul li.active {
background: #8b8b8b;
}
</style>
</head>
<body>
<div class="search">
<div class="box">
<div class="inner-box">
<input type="text" id="keyword" class="select" autocomplete="off" placeholder="请选择游戏名称">
<a href="#">搜索</a>
</div>
</div>
<ul class="list">
<li>地下城与勇士</li>
<li>魔兽世界(国服)</li>
<li>魔兽世界(台服)</li>
<li>热血江湖</li>
<li>大话西游II</li>
<li>QQ幻想世界</li>
</ul>
</div>
<script>
/*
实现的功能:
【1】搜索框获取焦点的时候 显示下拉下单
【1】获取元素
【2】搜索框失去焦点时候 隐藏下拉菜单
一下两个功能只有在获取焦点的时候才会有用
【3】按下鼠标的上下键 可以动态选中 li元素(给li元素添加 active 这个class名)
【4】当按下 enter键的时候,把拥有 activeclass名的元素的内容 赋值给搜索框
*/
var keyword = document.querySelector('#keyword');
var list = document.querySelector('.list');
var lists = document.querySelectorAll('.list>li');
var index = -1;
// 绑定获取焦点事件
keyword.onclick = function (event) {
list.style.display = 'block';
document.onkeydown = function (e) {
// 按下下键
if (e.keyCode === 40) {
index++;
if (index > lists.length - 1) {
index = 0;
}
// 排他思想
for (var i = 0; i < lists.length; i++) {
lists[i].className = '';
}
lists[index].className = 'active';
//index = 1;
}
if (e.keyCode === 38) {
index--;
if (index < 0) {
index = lists.length - 1;
}
// 排他思想
for (var i = 0; i < lists.length; i++) {
lists[i].className = '';
}
lists[index].className = 'active';
}
if (e.keyCode === 13) {
// 把当前选中的li的内容赋值给 搜索框 lists[index]
// console.log(lists[index].innerHTML);
keyword.value = lists[index].innerHTML;
list.style.display = 'none';
keyword.blur();
}
}
// 点击li的时候,把li的内容赋值给keyword
lists.forEach(function (items, index) {
items.onclick = function () {
for (var i = 0; i < lists.length; i++) {
lists[i].className = '';
}
lists[index].className = 'active';
keyword.value = this.innerHTML;
}
})
// 阻止事件的传播
event.cancelBubble = true;
}
// 失去焦点的时候 隐藏下拉菜单
// keyword.onblur = function () {
// list.style.display = 'none';
// }
document.onclick = function () {
list.style.display = 'none';
}
</script>
</body>
</html>
全选和反选
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
padding: 0;
margin: 0;
}
.wrap {
width: 300px;
margin: 100px auto 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
width: 300px;
}
th,
td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
th {
background-color: #09c;
font: bold 16px "微软雅黑";
color: #fff;
}
td {
font: 14px "微软雅黑";
}
tbody tr {
background-color: #f0f0f0;
}
tbody tr:hover {
cursor: pointer;
background-color: #fafafa;
}
</style>
</head>
<body>
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="j_cbAll" />
</th>
<th>商品</th>
<th>价钱</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPhone8</td>
<td>8000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Pro</td>
<td>5000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>iPad Air</td>
<td>2000</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>Apple Watch</td>
<td>2000</td>
</tr>
</tbody>
</table>
</div>
<script>
// 1. 全选和取消全选做法: 让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可
// 获取元素
var j_cbAll = document.getElementById('j_cbAll'); // 全选按钮
var j_tbs = document.getElementById('j_tb').getElementsByTagName('input'); // 下面所有的复选框
// 注册事件
j_cbAll.onclick = function () {
// this.checked 它可以得到当前复选框的选中状态如果是true 就是选中,如果是false 就是未选中
console.log(this.checked);
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].checked = this.checked;
}
}
// 2. 下面复选框需要全部选中, 上面全选才能选中做法: 给下面所有复选框绑定点击事件,每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的, 上面全选就不选中。
for (var i = 0; i < j_tbs.length; i++) {
j_tbs[i].onclick = function () {
// flag 控制全选按钮是否选中
var flag = true;
// 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中
for (var i = 0; i < j_tbs.length; i++) {
if (!j_tbs[i].checked) {
flag = false;
break; // 退出for循环 这样可以提高执行效率 因为只要有一个没有选中,剩下的就无需循环判断了
}
}
j_cbAll.checked = flag;
}
}
</script>
</body>
</html>
某东显示和隐藏密码
<style>
.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 {
position: absolute;
top: 2px;
right: 2px;
width: 24px;
}
</style>
<div class="box">
<label for="">
<img src="images/close.png" alt="" id="eye">
</label>
<input type="password" name="" id="pwd">
</div>
<script>
// 1. 获取元素
var eye = document.getElementById('eye');
var pwd = document.getElementById('pwd');
// 2. 注册事件 处理程序
var flag = 0;
eye.onclick = function () {
// 点击一次之后, flag 一定要变化
if (flag == 0) {
pwd.type = 'text';
eye.src = 'images/open.png';
flag = 1; // 赋值操作
} else {
pwd.type = 'password';
eye.src = 'images/close.png';
flag = 0;
}
}
删除留言
思路分析:
- 当我们给文本域里面的值赋值给li的时候,多添加一个删除链接;
- 需要把所有的链接获取过来,当我们点击当前的链接的时候,删除当前的链接所在的小 li ;
- 阻止链接跳转需要添加 javascript:void(0); 或者 javascript:;
<!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>
动态生成表格
思路分析:
- 因为里面的数据是动态的,所以需要js动态生成。这里模拟数据,自己定义好数据,数据采取对象形式存储;
- 所有的数据都是放到tbody里面的行里面;
- 因为行很多,需要循环创建多个行(对应多个人);
- 每个行里面又有很多单元格(对应里面的数据),还需要继续使用循环创建多个单元格,并把数据存入里面(双重for循环);
- 最后一列单元格是删除,需要单独创建单元格;
- 最后添加删除操作,单击删除,可以删除当前行;
<!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>
table {
width: 500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
</style>
</head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1.先去准备好学生的数据
var datas = [{
name: '牛一',
subject: 'JavaScript',
score: 100
}, {
name: '牛二',
subject: 'JavaScript',
score: 98
}, {
name: '牛三',
subject: 'JavaScript',
score: 99
}, {
name: '牛五',
subject: 'JavaScript',
score: 88
}, {
name: '牛六六',
subject: 'JavaScript',
score: 0
}];
// 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr
// 1. 创建 tr行
var tr = document.createElement('tr');
tbody.appendChild(tr);
// 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数 for循环遍历对象 datas[i]
for (var k in datas[i]) { // 里面的for循环管列 td
// 创建单元格
var td = document.createElement('td');
// 把对象里面的属性值 datas[i][k] 给 td
// console.log(datas[i][k]);
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
// 3. 创建有删除2个字的单元格
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除 </a>';
tr.appendChild(td);
}
// 4. 删除操作 开始
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function () {
// 点击a 删除 当前a 所在的行(链接的爸爸的爸爸) node.removeChild(child)
tbody.removeChild(this.parentNode.parentNode)
}
}
// for(var k in obj) {
// k 得到的是属性名
// obj[k] 得到是属性值
// }
</script>
</body>
</html>
当数据增多时,渲染到页面的数据
//当数据增多时
var datas = [{
name: '牛一',
subject: 'JavaScript',
score: 100
}, {
name: '牛二',
subject: 'JavaScript',
score: 98
}, {
name: '牛三',
subject: 'JavaScript',
score: 99
}, {
name: '牛五',
subject: 'JavaScript',
score: 88
}, {
name: '牛六六',
subject: 'JavaScript',
score: 60
}, {
name: '牛二',
subject: 'JavaScript',
score: 98
}, {
name: '牛二',
subject: 'JavaScript',
score: 98
}, {
name: '牛二',
subject: 'JavaScript',
score: 98
}, {
name: '牛二',
subject: 'JavaScript',
score: 98
}];