一、案例:推盒子
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="css/reset.min.css">
<style>
html,
body {
height: 100%;
}
.container {
box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
margin: -200px 0 0 -200px;
width: 400px;
height: 400px;
background: lightblue;
}
.container .box {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
background: lightcoral;
/* CSS3动画 */
transition: .3s linear;
}
</style>
</head>
<body>
<div class="container">
<div class="box"></div>
</div>
<script src="js/jquery.min.js"></script>
<script>
let $container = $('.container'),
$box = $container.children('.box');
$(document).on('keydown keypress', function (ev) {
// 1.首先获取按键码和元素当前的 TOP / LEFT
let code = ev.keyCode,
T = parseFloat($box.css('top')),
L = parseFloat($box.css('left')),
step = 30;
// 2.根据键盘码计算移动的距离
switch (code) {
case 37:
L -= step;
break;
case 38:
T -= step;
break;
case 39:
L += step;
break;
case 40:
T += step;
break;
}
// 4.边界判断
let minL = 0,
maxL = $container.outerWidth() - $box.outerWidth(),
minT = 0,
maxT = $container.outerHeight() - $box.outerHeight();
L = L < minL ? minL : (L > maxL ? maxL : L);
T = T < minT ? minT : (T > maxT ? maxT : T);
// 3.把最新的样式重新赋值为盒子
$box.css({
left: L,
top: T
});
});
</script>
</body>
</html>
二、案例:自定义菜单
// 1. 获取鼠标的位置
// 2. 把 ul 的 left 和 top 设置为鼠标的位置
// 3. 把盒子的 display 属性设为 block;
let menu = document.getElementById('menu');
document.oncontextmenu = function (e) {
e.preventDefault();
// 1. 获取鼠标的位置
let left = e.clientX;
let top = e.clientY;
// 2. 上一步获取的值设置给 ul
menu.style.left = left + 'px';
menu.style.top = top + 'px';
// 3. 让 ul 显示出来
menu.style.display = 'block';
};
// 增加刷新功能
let refresh = document.getElementById('refresh');
refresh.onclick = function () {
// 刷新页面的方法:
// 1. reload
// window.location.reload();
// 2. 重新给 location 的 href 属性赋值
// window.location.href 获取当前页面的 url;如果给 href 属性赋值一个 url,页面就会跳转到这个 url 指向的页面
window.location.href = window.location.href;
};
三、enter 和 over 的区别
/*
* over: 当从父元素进入子元素会触发父元素 out 事件;接着触发子元素的 over 事件,因为冒泡,又会触发父元素的 over 事件;
*
* */
inner.onmouseenter = function () {
console.log('inner enter');
};
inner.onmouseleave = function () {
console.log('inner leave');
};
outer.onmouseenter = function () {
console.log('outer enter');
};
outer.onmouseleave = function () {
console.log('outer leave');
};
/*
* enter: 从父元素进入子元素并不会触发父元素的 leave 事件,接下来触发子元素的 enter 事件,而且不会冒泡,进而父元素的 enter 事件不会触发;
* */
// 如果以后项目中用到这种大盒子套小盒子的,尽量用 enter 事件;
四、onload 和 DOMContentLoaded
// window.onload 页面中所有的资源(css、js、图片、字体)全部加载完成后,才会触发;
// DOM0级事件:
window.onload = function () {
console.log('window onload');
};
// DOMContentLoaded 页面中的 DOM 结构加载解析完成后就会触发;(DOM2 级事件)
// DOM2 级事件绑定
document.addEventListener('DOMContentLoaded', function () {
console.log('DOM Content Loaded');
}, false);
// DOMContentLoaded 触发早于 window.onload ;
// 以后经常会见到这样写的代码:
document.addEventListener('DOMContentLoaded', function () {
// 在这里面写了很多的业务逻辑,表示页面中的 DOM 结构加载完成后再执行这个回调函数中的代码;
// 因为 JS 是用来操作 DOM 的,这样写是保证 DOM 结构加载解析完成,再操作 DOM 更安全;
}, false);
五、obj 和 key 的问题
let obj = {
name: 'mb', // 对象的属性名都是字符串类型的
id: 17
};
let obj2 = {};
for (let key in obj) {
obj2[key] = obj[key];
/* obj[key] 写在方括号中的 key 没有引号,就是变量,最终被添加到 obj2 中的属性是 key 变量代表的值;第一次遍历 obj key代表的是 'name' 属性,所以第一次给 obj2 添加了一个'name' 属性,值 'mb' ,第二次 key 代表 'id',所以给 obj2 添加的属性是 'id',值是17;所以最后 obj2 是{name: 'mb', id: 17}
*/
}
let obj3 = {};
for (let attr in obj) {
obj3.attr = obj[attr];
/*obj3.attr 写在.后面的 attr 是死的属性,不是变量,表示的就是 'attr' 属性,给 obj3 添加的属性 就是 'attr' ,第一遍历时,给 obj3 添加了 'attr' 属性,obj3 就是 {attr: 'mb'};第二次遍历时,obj3.attr 表示 obj3['attr'],此时obj3['attr']有值,所以本次不是添加是修改,就把obj3 修改成了 {attr: 17};*/
}
// obj.key 等价于 obj['key']