WebAPI
根据id获取元素
格式:
//获得的变量为对象,类型为HTMLDivElement,id的值区分大小写
var 变量名 = document.getElementById(id值);
根据标签名来获取元素
格式:
//获得的变量为动态集合,类型为HTMLCollection,集合中的每一个元素是HTMLDivElement类型的对象
var 变量名 = document.getElementsByTagName(标签名);
动态集合
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
var divs = document.getElementsByTagName('div');
console.log(divs.length); //0
</script>
</head>
<body>
<div id="a1">say</div>
<div>hello</div>
<div>world</div>
<script type="text/javascript">
console.log(divs.length); //3
</script>
</body>
分析: 在页面的head中,html还没有执行到body,所以divs动态集合里面什么元素都没有,当页面执行完div后,再来看divs集合时,里面有了元素
demo
获取 id 为 container 的div下面的所有div元素
<div id="container">
<div>11111</div>
<div>222222</div>
<p>pppp</p>
<span>span</span>
</div>
<div>hello</div>
<div class="main">world</div>
<div>sss</div>
<script type="text/javascript">
var container = document.getElementById('container');
var containerDivs = container.getElementsByTagName('div');
console.log(containerDivs);
</script>
根据标签的 name 属性获取元素
格式:
//根据标签的name属性获取元素,变量是集合
var 变量名 = document.getElementsByName(name的值);
根据标签的 class 属性获取元素
浏览器兼容性问题,IE9以后才支持
格式:
//根据标签的class属性获取元素,变量是集合
var 变量名 = document.getElementsByClassName(class的值);
根据CSS的选择器来获取某一个元素
浏览器兼容性问题,IE8以后才支持
//根据选择器查找元素,只返回选择器组的第一个元素
var 变量名 = document.querySelector(选择器);
根据CSS的选择器来获取所有的元素
浏览器兼容性问题,IE8以后才支持
//根据选择器查找元素
var 变量名 = document.querySelectorAll(选择器);
事件
事件列表
事件 | 名称 | 英文名称 |
---|---|---|
onclick | 点击事件 ,一般用于按钮点击 | click |
onfocus | 获得焦点事件,一般用于文本框光标获取 | focus |
onblur | 失去焦点事件,一般用于文本框光标失去 | blur |
onmouseover | 鼠标悬停事件 | mouseover |
onmouseout | 鼠标离开事件 | mouseout |
onmouseenter | 鼠标悬停事件(不会触发冒泡事件) | mouseenter |
onmouseleave | 鼠标离开事件(不会触发冒泡事件) | mouseleave |
onmousemove | 鼠标移动事件 | mousemove |
onmousedown | 鼠标按下事件 | mousedown |
onmousewheel | 鼠标滚轮滚动事件 | mousewheel |
onkeydown | 键盘按下事件,键盘所输入的内容还没有展示到页面,可以通过代码修改 | keydown |
onkeyup | 键盘弹起事件,键盘所输入的内容已经展示到页面 | keyup |
onload | 加载完成事件 | load |
onunload | 页面离开事件,对象一般是window,关闭页面时会先卸载window,所以onunload对应的事件函数不会执行,但是刷新页面时,会先卸载页面再加载页面,这个时候是可以执行事件函数的 | unload |
onscroll | 鼠标滚动事件,一般配合scroll系列属性使用,滚动条滚动事件 | scroll |
注册事件
方法一:
<body>
<input type="button" id="bth" value="切换" />
<script>
//1. 获取按钮元素
var bth = document.getElementById('bth');
//2. 给按钮注册事件
bth.onclick = function () {
alert('来吧,满足你')
}
</script>
</body>
方法二:
<body>
<input type="button" id="bth" value="切换" />
<script>
//1. 获取按钮元素
var bth = document.getElementById('bth');
//2. 给按钮注册事件,这边的函数名不能带小括号,带小括号的作用是调用函数,这里是把函数赋给事件,而不是把调用函数的结果赋给事件!
bth.onclick = 函数名;
function 函数名 () {
alert('来吧,满足你')
}
</script>
</body>
属性操作
一般情况下,通过document对象获取到的对象,他的属性一般跟它对应的标签相同,但是也有特殊情况如下:
标签中的属性 | 通过document对象获取到的对象的属性 |
---|---|
class | className |
取消a标签的默认跳转行为
方法一:
给指向a标签的点击事件加上return false
<a href="http://www.baidu.com">百度</a>
<script>
var a = document.getElementsByTagName('a');
a[0].onclick = function() {
alert('不再跳转到百度');
//加上return false就不会执行a标签的默认跳转
return false;
}
</script>
方法二:
<!--void 运算符对给定的表达式进行求值,然后返回undefined-->
<a href="javascript:void(0)">百度</a>
<a href="javascript:void 0">百度</a>
<a href="javascript:undefined">首页</a>
获取标签之间的内容
<body>
<div id="box">
我是一个div
<span>这是一个span</span>
</div>
<script>
var box = document.getElementById('box');
//innerHTML获取内容的时候,如果内容中有标签,会把标签获取到
//原封不动输出内容
console.log(box.innerHTML); //我是一个div<span>这是一个span</span>
//innerText获取内容的时候,如果内容中有标签会把标签过滤掉
//去除前后的空白和换行
console.log(box.innerText);
</script>
</body>
运行结果:
innerHTML 和 innerText 的区别
- innerHTML获取内容的时候,如果内容中有标签,会把标签获取到,并原封不动输出内容
- innerText获取内容的时候,如果内容中有标签会把标签过滤掉,并去除前后的空白和换行
- 使用 innerHTML 属性可以在 div 中赋值一个 html 标签语句
- 使用 innerText 属性只能赋值一个文本,不能赋值一个 html 标签语句,因此他可以把标签在网页中显示出来,但是如果想要在 html 页面中显示标签需要使用下面的转义符,因此用他显示标签比较方便
HTML转义符
1. " "
2. ' '
3. & &
4. < <
5. > >
6. 空格
7. © ©
处理浏览器兼容性问题的思路(了解)
如何知道浏览器是否支持元素的某个属性?
当这个对象的属性不存在的时候返回的是undefined,当属性存在的时候返回该属性的类型
demo:处理浏览器是否兼容innerText或者textContent
function getInnerText(element) {
//当属性的值的类型为string,返回innerText的值
if(typeof element.innerText === 'string'){
return element.innerText;
}else {
return element.textContent;
}
}
表单元素中的特殊属性
- disabled:禁用属性
- checked:复选框选中属性
- selected:下拉菜单选中属性
这三个属性只有一个值,所以在 javascript 中获取这三个属性的值的时候得到的是 true 或者 false
demo:
<input type="text" name="xm" id="xm" disabled="disabled" />
<script>
var xm = document.getElementById('xm');
console.log(xm.disabled); //true
</script>
自定义属性
定义: 我们给 html 标签强加上它没有的属性,叫我们的自定义属性
demo:
<!--div的本身并没有age和personName属性,我们给他强加了这个属性,就是自定义属性-->
<div id="box" age="18" personName="zhangsan">张三</div>
<script>
var box = document.getElementById('box');
//获取自定义属性的值
var boxAge1 = box.getAttribute('age');
var boxPersonName1 = box.getAttribute('personName');
console.log(boxAge1,boxPersonName1); //18 zhangsan
//设置自定义属性的值
box.setAttribute('age',23);
box.setAttribute('sex','男');
var boxAge2 = box.getAttribute('age');
var boxPersonName2 = box.getAttribute('personName');
var sex2 = box.getAttribute('sex');
console.log(boxAge2,boxPersonName2,sex2); //23 zhangsan 男
//移除自定义属性
box.removeAttribute('sex');
var boxAge3 = box.getAttribute('age');
var boxPersonName3 = box.getAttribute('personName');
var sex3 = box.getAttribute('sex');
console.log(boxAge3,boxPersonName3,sex3); //23 zhangsan null
</script>
|| 运算符
运算规则:
- 如果第一个数转换为 boolean 为 true ,直接返回这个数
- 如果第一个数转换为 boolean 为 false,返回第二个数
demo:
var m;
var n1 = m || 0;
console.log(n1); //0
var n2 = 0 || m;
console.log(n2); //undefined
var n3 = 1 || m;
console.log(n3); //1
var n4 = false || true;
console.log(n3); //false
节点
节点的分类
节点类型 | 代表值 |
---|---|
属性节点 | |
元素节点 | 1 |
文本节点 | 3 |
注释节点 | 8 |
节点必有的属性
- parentNode 父节点,每一个节点有且只有一个父节点
- childNodes 子节点,获取该节点下所有子节点
- nodeType 节点类型
- nodeName 节点名称
- nodeValue 节点的值,除了文本节点和注释节点,一般都是null
- children 子元素集合,获取该节点下所有的子元素
- firstChild 获取第一个子节点
- lastChild 获取最后一个子节点
- firstElementChild 获取第一个子元素节点(只读,不能设置修改值)
- lastElementChild 获取最后一个子元素节点(只读,不能设置修改值)
- nextSibling 相邻的下一个兄弟节点
- previousSibling 相邻的上一个兄弟节点
- nextElementSibling 获取下一个兄弟元素节点
- previousElemnetSibling 获取上一个兄弟元素节点
demo:
判断下面的div#main下面有几个子节点?
<div id="main">
<div>Hello world</div>
<p>Hello world</p>
<input type="text" value="张三" />
</div>
<script>
var main = document.getElementById('main');
console.dir(main.childNodes); //7
</script>
a标签跳转调用方法
<a href="javascript:dd()">首页</a>
<script>
function dd() {
alert('首页跳转');
}
</script>
动态创建元素
方法一:document.write()
特点: 会把html文档中的所有内容都覆盖掉
demo:
<input type="button" id="bth" value="按钮" />
<script>
var bth = document.getElementById('bth');
bth.onclick = function() {
document.write('<h4>Hello world</h4>');
}
</script>
效果:
点击之前:
点击之后:
方法二:element.innerHTML
demo:点击按钮动态生成列表
<input type="button" value="按钮" id="bth" /> <br />
<div id="lb" >
</div>
<script>
var bth = document.getElementById('bth');
var datas = ['张三','李四','王五','赵六','唐七'];
var datasHTML = [];
bth.onclick = function() {
var lb = document.getElementById('lb');
for(var i = 0; i < datas.length; i++) {
var data = datas[i];
datasHTML[i] = '<li>'+data+'</li>';
}
lb.innerHTML = '<ul>'+datasHTML.join('') +'</ul>';
}
</script>
解析: 因为字符串不可变,每次拼接字符串都需要开辟新的内存,对于大量数据而言很影响效率。如果不使用字符串,直接对 innerHTML 属性进行操作,每一次拼接 innerHTML 都需要重新绘制页面,同样影响效率。所以我们使用数组来操作,最后只需要把数组转换为字符串即可,不需要重新开辟内存空间了
方法三:document.createElement()
<input type="button" value="按钮" id="bth" /> <br />
<div id="lb" >
</div>
<script>
var bth = document.getElementById('bth');
var datas = ['张三','李四','王五','赵六','唐七'];
var datasHTML = [];
bth.onclick = function() {
var lb = document.getElementById('lb');
//清空元素内的子元素,防止按钮重复点击
lb.innerHTML = '';
//创建ul标签,并获取ul对象
var ul = document.createElement('ul');
//将创建的标签放入#lb的div里面
lb.appendChild(ul);
for(var i = 0; i < datas.length; i++) {
//创建li标签,并获取li对象
var li = document.createElement('li');
//设置li的属性
li.innerText = datas[i];
//将创建的标签放入ul里面
ul.appendChild(li);
}
}
</script>
解析: 通过 document.createElement() 不仅可以创建元素,同时还能获取到创建的元素的对象,通过对象可以对创建的元素进行事件样式的动态操作,比较方便,但是需要注意的是, element.innerHTML 会覆盖掉你所选择的元素下面的所有内容,而 appendChild 只是添加子节点,不会覆盖掉元素中原来的内容,在一定的逻辑关系下,需要进行一个清空操作,防止按钮重复点击,如果你选择的对象没有其他的元素,那么你可以直接使用 element.innerHTML 进行清空,如果有,那么你需要先获取你添加的对象的集合,再遍历执行 removeChild 方法清空你之前所添加的元素
appendChid() 和 insertBefore() 和 replaceChild()
函数 | 作用 |
---|---|
appendChid() | 在指定元素中的末尾添加元素,如果被插入的元素已经存在于当前文档中,则首先会从原来的位置移除,然后插入到新的位置 |
insertBefore() | 在指定元素中的指定的子元素之前插入新的元素,两个参数(需要插入的元素,参考子元素) |
replaceChild() | 在指定元素中,替换指定的子元素,两个参数(新的元素,被替换的子元素) |
demo:
<ul id="students">
<li>张三</li>
<li>李四</li>
<li>王五</li>
<li>赵六</li>
<li>唐七</li>
</ul>
在ul中的最后添加一个li
var ul = document.getElementById('students');
var li = document.createElement('li');
li.innerText = '宋八';
ul.appendChild(li);
运行结果:
在ul的第三个li标签前面加一个li标签
var ul = document.getElementById('students');
var li = document.createElement('li');
li.innerText = '小红';
ul.insertBefore(li,ul.children[2]);
运行结果:
将李四替换成小黄
var ul = document.getElementById('students');
var li = document.createElement('li');
li.innerText = '小黄';
ul.replaceChild(li,ul.children[1]);
运行结果:
appendChid() 特殊用法
通过按钮点击将 值为张三的 li 标签移入到另一个 ul 中
<input type="button" value="按钮" id="bth" />
<ul id="students">
<li>张三</li>
<li>李四</li>
<li>王五</li>
<li>赵六</li>
<li>唐七</li>
</ul>
<ul id="students2">
</ul>
<script>
var bth = document.getElementById('bth');
bth.onclick = function() {
var students = document.getElementById('students');
var students2 = document.getElementById('students2');
students2.appendChild(students.children[0]);
}
</script>
demo:选择水果
<body>
<!--multiple属性使得select框可以多选-->
<select name="" id="fruits1" class="dll" multiple="multiple">
<option value="">香蕉</option>
<option value="">苹果</option>
<option value="">橘子</option>
<option value="">葡萄</option>
<option value="">西瓜</option>
</select>
<input type="button" value=">>" id="bth1" />
<input type="button" value="<<" id="bth2" />
<input type="button" value=">" id="bth3" />
<input type="button" value="<" id="bth4" />
<select name="" id="fruits2" class="dll" multiple="multiple">
</select>
<script>
//id可以直接获取对象,不需要写document.getElementById
bth1.onclick = function() {
//这个集合为可变集合
var fruits1Options = fruits1.children;
var length = fruits1Options.length;
for( var i = 0 ; i < length; i++) {
fruits2.appendChild(fruits1Options[0]);
}
}
bth2.onclick = function() {
//这个集合为可变集合
var fruits1Options = fruits2.children;
var length = fruits1Options.length;
for( var i = 0 ; i < length; i++) {
fruits1.appendChild(fruits1Options[0]);
}
}
bth3.onclick = function() {
//selected只有一个值所以是boolean类型
var fruits1Options = fruits1.children;
for( var i = 0 ; i < fruits1Options.length; i++) {
if(fruits1Options[i].selected) {
//必须在appendChild之前去掉,因为appendChild之后集合中就没有这个元素对象了
fruits1Options[i].selected = false;
fruits2.appendChild(fruits1Options[i]);
i--;
}
}
}
bth4.onclick = function() {
//selected只有一个值所以是boolean类型
var fruits1Options = fruits2.children;
for( var i = 0 ; i < fruits1Options.length; i++) {
if(fruits1Options[i].selected) {
//必须在appendChild之前去掉,因为appendChild之后集合中就没有这个元素对象了
fruits1Options[i].selected = false;
fruits1.appendChild(fruits1Options[i]);
i--;
}
}
}
</script>
</body>
运行结果:
给元素注册多个事件函数
使用 on+事件名称 = 事件函数 来注册事件,无法给同一个对象的同一个事件注册多个事件函数,如果想要注册多个事件函数,可以使用以下格式
浏览器兼容性问题,ie9之后才兼容
元素对象.addEventListener(事件名称,事件函数)
demo:
<input type="button" value="按钮" id="bth" />
<script>
bth.addEventListener('click',function() {
alert('hello world!');
})
bth.addEventListener('click',function() {
alert('hello javascript!');
})
</script>
移除事件
demo:让按钮只能点击一次
方法一:
bth.onclick = function() {
alert('Hello world!');
//移除事件
bth.onclick = null;
}
方法二:
//如果想要移除事件,使用addEventListener注册事件的时候就不能使用匿名函数
bth.addEventListener('click',sysoHello);
function sysoHello() {
alert('Hello world!');
//移除事件
bth.removeEventListener('click',sysoHello);
}
事件的三个阶段
- 捕获阶段:事件从元素标签的最外层往最里层注册事件
- 执行当前目标阶段:当事件注册到最里层之后,从最里层开始执行事件
- 冒泡阶段:从最里层往最外层执行事件
demo:
<div id="box1" style="width:300px;height:300px;background-color:red;">
<div id="box2" style="width:200px;height:200px;background-color:pink;">
<div id="box3" style="width:100px;height:100px;background-color:yellow;"></div>
</div>
</div>
box1.addEventListener('click',function() {
console.log('box1');
})
box2.addEventListener('click',function() {
console.log('box2');
})
box3.addEventListener('click',function() {
console.log('box3');
})
运行结果:
干预事件的执行顺序
box1.addEventListener('click',function() {
console.log('box1');
},true)
box2.addEventListener('click',function() {
console.log('box2');
},true)
box3.addEventListener('click',function() {
console.log('box3');
},true)
运行结果:
分析: 默认不写的情况下,addEventListener 函数的第三个参数为 false,冒泡执行事件函数,由内向外。如果第三个参数为 true,则反过来由外向内执行事件函数
事件委托
原理: 事件冒泡,当某一个标签不方便处理事件的时候,我们可以将事件交给这个标签的上一级标签去处理
demo:高亮显示美女标签
<ul id="ul">
<li>西施</li>
<li>貂蝉</li>
<li>昭君</li>
<li>凤姐</li>
<li>芙蓉姐姐</li>
</ul>
思路: 以前的做法是获取 ul 对象,得到他下面的所有的子元素标签的集合,遍历注册点击事件,但是如果 li 有无穷多个,这种做法就会很占内存。事件冒泡告诉我们 li 标签的点击事件可以冒泡到 ul ,我们可以用 ul 去委托事件
//e 是事件的隐藏参数,当事件发生时,可以获取一些和事件相关的数据
ul.onclick = function(e) {
//处理浏览器兼容问题
e = e || window.event;
//先让所有li去除高亮显示
for(var i = 0; i < this.children.length; i++) {
this.children[i].style.backgroundColor = 'white';
}
//获取当前事件真正的目标对象
var li = e.target || e.srcElement;
li.style.backgroundColor = 'red';
}
事件的对象
事件的对象可以通过两种方法获取,第一种就是如上面的 demo ,通过给事件函数传递隐藏参数获取事件对象,第二种可以使用 window.event 来获取,有的时候低版本的浏览器不兼容第一种,可以使用第二种
事件对象里面的属性和方法:
属性名称 | 作用 |
---|---|
target | 获取当前事件真正的目标对象 |
srcElement | 获取当前事件真正的目标对象(兼容性比target强) |
type | 获取事件名称(当多个事件指向同一个事件函数,可以用于判断事件的行为) |
clientX | 获取鼠标在浏览器可视区域的横坐标(被滚动条翻上去看不见的内容不算可视区域) |
clientY | 获取鼠标在浏览器可视区域的纵坐标(被滚动条翻上去看不见的内容不算可视区域) |
pageX | 获取鼠标在浏览器相对于整个页面的横坐标 |
pageY | 获取鼠标在浏览器相对于整个页面的纵坐标 |
keyCode | 获取键盘输入的内容的键盘码,一般是ASCAll码,这个属性一般用在键盘事件中 |
preventDefault() | 阻止或取消默认行为,比如取消a标签的跳转行为,他比 return false 好在不会终止我们的事件函数 |
stopPropagation() | 停止事件传播,阻止冒泡 |
demo
demo1:图片跟着鼠标移动
//body代表页面上的有效区域,document代表整个页面
document.onmousemove = function (e) {
//先清除img
var body = document.querySelector('body');
var img1 = document.querySelector('img');
if(img1 != undefined){
body.removeChild(img1);
}
//处理浏览器兼容性问题
e = e || window.event;
//获取横坐标
var x = e.pageX;
var y = e.pageY;
//创建img标签
var img = document.createElement('img');
img.src = 'img/tianshi.gif';
img.style.margin=y+'px '+x+'px';
body.appendChild(img);
}
demo2:获取鼠标在盒子里面的坐标
box.onclick = function(e) {
//处理兼容性问题
e = e || window.event;
//获取盒子在页面上的坐标(只读属性,不能设置值)
var x = this.offsetLeft;
var y = this.offsetTop;
//获取鼠标在页面的坐标
var mouseX = e.pageX;
var mouseY = e.pageY;
//输出鼠标在盒子上的坐标
var mouseBoxX = mouseX - x;
var mouseBoxY = mouseY - y;
console.log(mouseBoxX,mouseBoxY);
}
BOM
window
window 是浏览器的顶级对象,当我们调用 window 下面的成员的时候,可以省略 window ,例如 docment , alert(),包括我们定义的全局变量都是属于 window 的,因此我们在定义全局变量的时候要注意不要跟window里面的成员有冲突
demo:
console.dir(window); //打印查看window对象
var div = window.document.createElement('div');
window.console.dir(window.div);
window.alert('hello');
//window中有name属性
var name = 123;
console.log(name); //123
//不是number类型了
console.log(typeof name); //string
//window中有top属性
var top = 123;
console.log(top); // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
console.log(typeof top); //object
三种对话框
格式:
alert(需要弹出显示的内容);
//变量用于接收用户在对话框中输入的内容,点取消返回null,如果什么都不填点确定返回undefined
var 变量名 = prompt(提示内容,默认值);
//询问框,用户按确定返回true给变量,按取消返回false给变量
var 变量名 = confirm(提示内容);
demo:
bth1.onclick = function() {
alert('Hello world!');
}
bth2.onclick = function() {
var userName = prompt('请输入用户名');
console.log(userName);
}
bth3.onclick = function() {
var isSure = confirm('是否删除数据?');
console.log(isSure);
}
alert:
prompt
confirm
两种定时器
格式:
//间隔时间是毫秒,setTimeout只会执行一次,返回值是一个整数,为定时器的标识
var 变量 = setTimeout(函数名,间隔时间);
//取消定时器的执行,传入的是定时器的标识
clearTimeout(变量);
//间隔时间是毫秒,setInterval会执行多次,返回值是一个整数,为定时器的标识
var 变量 = setInterval(函数名,间隔时间);
//取消定时器的执行,传入的是定时器的标识
clearInterval(变量);
demo:让盒子跑起来
bth.onclick = function() {
box.style.left = 0 + 'px';
var intervalID = setInterval(function() {
var jl = box.offsetLeft;
if(jl >= 500){
clearInterval(intervalID);
}else{
box.style.left=jl + 5 + 'px';
}
},20)
}
location
成员 | 作用 |
---|---|
href | 页面跳转或者获取本窗口的连接 ,可以后退 |
hash | 锚点 |
search | 传递参数 |
assign(跳转url) | 页面跳转,可以后退 |
replace(跳转url) | 页面跳转,不能后退 |
reload() | 重新加载页面,参数为boolean类型, true 强制从服务器重新获取页面, false 从本地缓存获取页面 |
url的组成
格式:
scheme://host:port/path?query#tragment
- scheme: 通信协议,常用的有 http,ftp,maito等
- host: 主机,服务器或域名或ip地址
- port:端口号
- path:路径
- query:传递参数,一般用&隔开
- targment:锚点
history
成员 | 作用 |
---|---|
forward() | 前进 |
back() | 后退 |
go() | 前进,后退,可以传递参数,-1 是后退,+1 是前进 |
navigator
成员 | 作用 |
---|---|
userAgent | 记录当前用户操作系统的相关信息,用来判断你是手机登录还是PC登录 |
三大与盒子大小相关的属性
offset系列属性
属性(只读) | 作用 |
---|---|
offsetLeft | 获取盒子的左边距 (是距离offsetParent的距离) |
offsetTop | 获取盒子的右边距(是距离offsetParent的距离) |
offsetWidth | 获取盒子的宽度(包括边框和padding) |
offsetHeighrt | 获取盒子的高度(包括边框和padding) |
offsetParent | 获取当前元素最近的定位父元素。如果没有定位父元素此时是 body |
client系列属性
属性(只读) | 作用 |
---|---|
clientLeft | 获取盒子的左边框的宽度 |
clientTop | 获取盒子的上边框的宽度 |
clientWidth | 获取盒子的宽度(包括padding不包括边框) |
clientHeighrt | 获取盒子的高度(包括padding不包括边框) |
scroll系列属性
属性(只读) | 作用 |
---|---|
scrollLeft | 获取盒子中内容水平滚动出去的距离 |
scrollTop | 获取盒子中内容垂直滚动出去的距离 |
scrollWidth | 获取盒子的内容宽度(包括padding不包括滚动条的宽度) |
scrollHeighrt | 获取盒子中内容的高度,(包括padding,包括没有显示出来的内容,不包括滚动条的宽度) |
拖拽案例
demo:拖拽盒子
思路: 当鼠标按下的时候,拖拽盒子移动,唯一不变的是鼠标在盒子中的位置
demo1
<head>
<style>
.d-box {
width: 300px;
height:300px;
position: absolute;
}
.bd {
width: 100%;
height: 250px;
background-color : pink;
}
.hd {
width: 100%;
height: 25px;
background-color: #7c9299;
border-bottom: 1px solid #369;
line-height: 25px;
color: white;
cursor: move; /*鼠标移动样式*/
}
#box_close{
float: right;
cursor: pointer; /*鼠标按下样式*/
}
</style>
</head>
<body>
<div class="d-box" id="d_box">
<div class="hd" id="drop">注册信息(可以拖拽)
<span id="box_close">【关闭】</span>
</div>
<div class="bd"></div>
</div>
<script>
//鼠标按下事件
drop.onmousedown = function(e) {
//当鼠标按下的时候,求鼠标在盒子中的位置
var x = e.pageX - d_box.offsetLeft;
var y = e.pageY - d_box.offsetTop;
//鼠标是在文档中移动的
document.onmousemove = function(e){
//鼠标移动的时候,求盒子的坐标
var boxX = e.pageX - x;
var boxY = e.pageY - y;
console.log(boxX);
console.log(boxY);
d_box.style.left = boxX + 'px';
d_box.style.top = boxY + 'px';
}
}
//当鼠标弹起的时候,移除鼠标移动事件
document.onmouseup = function(){
document.onmousemove = null;
}
</script>
</body>
demo2
<head lang="en">
<style>
.login-header {
width: 100%;
text-align: center;
height: 30px;
font-size: 24px;
line-height: 30px;
}
ul, li, ol, dl, dt, dd, div, p, span, h1, h2, h3, h4, h5, h6, a {
padding: 0px;
margin: 0px;
}
.login {
width: 512px;
position: absolute;
border: #ebebeb solid 1px;
height: 280px;
left: 50%;
right: 50%;
background: #ffffff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
margin-left: -256px;
margin-top: 140px;
display: none;
}
.login-title {
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
position: relative;
cursor: move;
-moz-user-select:none;/*火狐*/
-webkit-user-select:none;/*webkit浏览器*/
-ms-user-select:none;/*IE10*/
-khtml-user-select:none;/*早期浏览器*/
user-select:none;
}
.login-input-content {
margin-top: 20px;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #ebebeb 1px solid;
text-align: center;
}
/*遮盖层样式*/
.login-bg {
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: #000000;
filter: alpha(opacity=30);
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
opacity: 0.3;
display: none;
}
a {
text-decoration: none;
color: #000000;
}
.login-button a {
display: block;
}
.login-input input.list-input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ebebeb 1px solid;
text-indent: 5px;
}
.login-input {
overflow: hidden;
margin: 0px 0px 20px 0px;
}
.login-input label {
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 14px;
}
.login-title span {
position: absolute;
font-size: 12px;
right: -20px;
top: -30px;
background: #ffffff;
border: #ebebeb solid 1px;
width: 40px;
height: 40px;
border-radius: 20px;
}
</style>
</head>
<body>
<div class="login-header"><a id="link" href="javascript:void(0);">点击,弹出登录框</a></div>
<div id="login" class="login" >
<div id="title" class="login-title">登录会员
<span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
</div>
<div class="login-input">
<label>登录密码:</label>
<input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
</div>
</div>
<div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>
<!-- 遮盖层 -->
<div id="bg" class="login-bg" ></div>
<script>
//1.点击按钮弹出登录框和显示遮盖层
link.onclick = function(){
login.style.display = 'block';
bg.style.display = 'block';
}
//2.点击关闭按钮,关闭登录框和隐藏遮盖层
closeBtn.onclick = function(){
login.style.display = 'none';
bg.style.display = 'none';
}
title.onmousedown = function(e){
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
title.onmousemove = function(e){
var login_X = e.pageX - x;
var login_Y = e.pageY - y;
//如果有的移动目标样式里面有设置margin,需要清除margin
login.style.marginLeft = 0 + 'px';
login.style.marginTop = 0 + 'px';
login.style.left = login_X +'px';
login.style.top = login_Y + 'px';
}
}
title.onmouseup = function(){
title.onmousemove = null;
}
</script>
</body>
demo3(放大镜)
<head lang="en">
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 350px;
height: 350px;
margin: 100px;
border: 1px solid #ccc;
position: relative;
}
.big {
width: 400px;
height: 400px;
position: absolute;
top: 0;
left: 360px;
border: 1px solid #ccc;
overflow: hidden;
display: none;
}
.big img {
position: absolute;
}
.mask {
width: 175px;
height: 175px;
background: rgba(255, 255, 0, 0.4);
position: absolute;
top: 0px;
left: 0px;
cursor: move;
display: none;
}
.small {
position: relative;
}
</style>
</head>
<body>
<div class="box" id="box">
<div class="small">
<img src="img/small.webp" width="350" alt=""/>
<div class="mask"></div>
</div>
<div class="big">
<img src="img/big.jpg" width="800" alt=""/>
</div>
</div>
<script>
var smallBox = box.children[0];
var bigBox = box.children[1];
var smallIMG = smallBox.children[0];
var mask = smallBox.children[1];
var bigIMG = bigBox.children[0];
/*1. 当鼠标经过smallIMG的时候显示mask和bigIMG*/
box.onmouseenter = function(e) {
mask.style.display = 'block';
bigBox.style.display = 'block';
}
/*2. 当鼠标移开的时候隐藏mask和bigIMG*/
box.onmouseleave = function() {
mask.style.display = 'none';
bigBox.style.display = 'none';
}
/*3. 当鼠标移动的时候保证mask也跟鼠标一起移动,同时保证鼠标一直处于mask盒子的中心*/
box.onmousemove = function(e){
var mask_x = e.pageX - box.offsetLeft - mask.offsetWidth / 2;
var mask_y = e.pageY - box.offsetTop - mask.offsetHeight / 2;
//把mask限制在box盒子中
mask_x = mask_x < 0 ? 0 :mask_x;
mask_y = mask_y < 0 ? 0 :mask_y;
//mask可以移动的最大值为盒子的宽度 - mask的宽度
mask_x_max = box.offsetWidth - mask.offsetLeft;
mask_y_max = box.offsetHeight - mask.offsetHeight;
mask_x = mask_x > mask_x_max ? mask_x_max : mask_x;
mask_y = mask_y > mask_y_max ? mask_y_max : mask_y;
mask.style.left = mask_x + 'px';
mask.style.top = mask_y + 'px';
/*4. 当mask移动的时候,同时让大图片也移动*/
/*数学公式:mask移动的距离/mask最大能够移动的距离 = 大图片移动的距离/大图片最大能够移动的距离*/
var big_x = bigIMG.offsetWidth - bigBox.offsetWidth;
var big_y = bigIMG.offsetHeight - bigBox.offsetHeight;
var bigIMG_x = mask_x/mask_x_max*big_x;
var bigIMG_y = mask_y/mask_y_max*big_y;
bigIMG.style.left = - bigIMG_x + 'px';
bigIMG.style.top = - bigIMG_y + 'px';
}
</script>
</body>
模拟滚动条
思路:
- 根据内容的大小,计算滚动条的高度
- 让滚动条能够拖拽
- 当拖拽滚动条的时候,能够改变内容的位置
<head lang="en">
<style>
* {margin: 0;padding: 0;}
.box {
width: 300px;
height: 500px;
border: 1px solid red;
margin: 100px;
position: relative;
overflow: hidden;
/* 不让文字被选中 */
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
}
.content {
padding: 5px 18px 5px 5px;
position: absolute;
top: 0;
left: 0;
}
.scroll {
width: 18px;
height: 100%;
position: absolute;
top: 0;
right: 0;
background-color: #eee;
}
.bar {
height: 100px;
width: 100%;
position: absolute;
top: 0;
left: 0;
background-color: red;
border-radius: 10px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box" id="box">
<div class="content" id="content">
我是文字内容,我是文字内容,我是文字内容,
。。。(此处内容省略)
</div>
<div class="scroll" id="scroll1">
<div class="bar" id="bar"></div>
</div>
</div>
<script>
/*offsetHeight:元素大小 + padding + border
clientHeight:元素大小 + padding
scrollHeight:内容大小 + padding*/
/*计算滚动条的高度*/
/*当内容的高度大于box的高度,则计算滚动条的高度*/
/*公式:滚动条的高度/scroll的高度 = box的高度/content的高度*/
if(content.scrollHeight > box.clientHeight){
var barHeight = box.clientHeight / content.scrollHeight * scroll1.clientHeight;
bar.style.height = barHeight + 'px';
}else{
bar.style.height = '0px';
}
bar.onmousedown = function(e){
var y = e.pageY - bar.offsetTop - box.offsetTop;
bar.onmousemove = function(e){
var bar_y = e.pageY - y - box.offsetTop;
bar_y = bar_y < 0 ? 0: bar_y;
var bar_y_max = scroll1.clientHeight - bar.clientHeight;
bar_y = bar_y > bar_y_max ? bar_y_max : bar_y;
/*内容滚动的距离 / 内容可以滚动的最大距离 = 滚动条滚动的距离 / 滚动条可以滚动的最大距离*/
var content_max = content.scrollHeight - box.clientHeight;
var content_y = bar_y / bar_y_max * content_max;
content.style.top = - content_y + 'px';
bar.style.top = bar_y + 'px';
}
}
bar.onmouseup = function(){
bar.onmousemove = null;
}
</script>
</body>
模拟动画
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
* {
margin: 0px;
padding: 0px;
}
#box {
position: relative;
width: 100px;
height: 100px;
background-color: red;
}
</style>
</head>
<body>
<input type="button" id="btn" value="开始">
<div id="box">
</div>
<script>
//点击按钮,让盒子向右移动
btn.onclick = function(){
//使用定时器运行,将定时器id绑定到对应的元素上去
this.timerId = setInterval(function(){
var box_x = box.offsetLeft + 5 ;
if(box_x > 500) {
//停止定时器
clearInterval(this.timerId);
box.style.left = '500px';
//结束函数
return;
}
//box.style.left能够获取到标签的该属性的样式值,但是结果数据类型是字符串
box.style.left = box_x + 'px';
},30); //每隔30毫秒运行一次
}
</script>
</body>
轮播图
思路:
- 轮播图骨架
一个轮播图内容的盒子,里面包含轮播图的可视区域的盒子和轮播图的箭头,轮播图可视区域的盒子里面包含轮播图和序号 - 动态生成序号,并让第一个序号高亮显示
- 点击序号可以实现图片动画转化,并对应序号高亮显示
- 鼠标放上去显示箭头,离开隐藏箭头
- 实现点击箭头轮播
- 实现自动轮播
- 实现鼠标悬停轮播图停止,鼠标离开轮播图继续自动轮播
代码实现:
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
padding: 0;
margin: 0;
list-style: none;
border: 0;
}
.all {
width: 500px;
height: 200px;
padding: 7px;
border: 1px solid #ccc;
margin: 100px auto;
position: relative;
}
.screen {
width: 500px;
height: 200px;
overflow: hidden;
position: relative;
}
.screen li {
width: 500px;
height: 200px;
overflow: hidden;
float: left;
}
.screen ul {
position: absolute;
left: 0;
top: 0px;
width: 3000px;
}
.all ol {
position: absolute;
right: 10px;
bottom: 10px;
line-height: 20px;
text-align: center;
}
.all ol li {
float: left;
width: 20px;
height: 20px;
background: #fff;
border: 1px solid #ccc;
margin-left: 10px;
cursor: pointer;
}
.all ol li.current {
background: yellow;
}
#arr {
display: none;
z-index: 1000;
}
#arr span {
width: 40px;
height: 40px;
position: absolute;
left: 5px;
top: 50%;
margin-top: -20px;
background: #000;
cursor: pointer;
line-height: 40px;
text-align: center;
font-weight: bold;
font-family: '黑体';
font-size: 30px;
color: #fff;
opacity: 0.3;
border: 1px solid #fff;
}
#arr #right {
right: 5px;
left: auto;
}
</style>
</head>
<body>
<!--轮播图的盒子-->
<div class="all" id='box'>
<!--轮播图可视区域-->
<div class="screen">
<!--轮播图-->
<ul>
<li><img src="img/wf1.jpg" width="500" height="200"/></li>
<li><img src="img/wf2.jpg" width="500" height="200"/></li>
<li><img src="img/wf3.jpg" width="500" height="200"/></li>
<li><img src="img/wf4.jpg" width="500" height="200"/></li>
<li><img src="img/wf5.jpg" width="500" height="200"/></li>
</ul>
<!--序号-->
<ol>
</ol>
</div>
<!--箭头-->
<div id="arr"><span id="left"><</span><span id="right">></span></div>
</div>
<script>
//1.动态生成序号
var screen = box.children[0];
var ul = document.querySelector('.screen ul');
var ol = document.querySelector('.screen ol');
var ul_lis = ul.children;
//注意这边获取图片的宽度必须使用展示图片div的宽度
var imageWidth = screen.offsetWidth;
var ol_lis = ol.children;
//索引
var index = 0;
for(var i = 0; i < ul_lis.length;i++){
var li = document.createElement('li');
if(i == 0){
li.className = 'current';
}
li.innerText = i + 1;
li.onclick = liClick;
ol.appendChild(li);
}
//2.点击序号 动画方式 切换图片
function liClick(){
if(index == 5){
ul.style.left = '0px';
index = 0;
}
index = this.textContent - 1;
if(index == 0){
var currentLi = document.getElementsByClassName('current')[0];
var beforIndex = currentLi.textContent - 1;
if(beforIndex == 4){
index = 5;
changeImg();
}
}else{
changeImg();
}
//1. 取消其他li的高亮显示,让当前li高亮显示
clearGL();
this.className = 'current';
}
//3.鼠标放到盒子上显示箭头,并清除自动轮播
box.onmouseover = function(e){
arr.style.display = 'block';
if(timerId){
clearInterval(timerId);
timerId = null;
}
}
//4.鼠标离开盒子隐藏箭头,并开启自动轮播
box.onmouseout = function(){
arr.style.display = 'none';
if(timerId == null){
timerId = setInterval(function(){
right.onclick();
},2000);
}
}
var firstLi = ul.children[0];
//克隆li:cloneNode()复制节点
//参数:true:复制节点中的内容,false:只复制节点,不复制里面的内容
var cloneFirstLi = firstLi.cloneNode(true);
ul.appendChild(cloneFirstLi);
//5.实现上一张和下一张的功能
left.onclick = function(){
index -= 1;
clearGL();
if(index < 0){
ul.style.left = -imageWidth*(ul.children.length - 1) + 'px';
index = ul_lis.length - 2;
ol_lis[index].className = 'current';
}else{
ol_lis[index].className = 'current';
}
changeImg();
}
right.onclick = function(){
if(index == 5){
ul.style.left = '0px';
index = 0;
}
index += 1;
clearGL();
if(index >= 5){
index = 0;
ol_lis[index].className = 'current';
index = 5;
}else{
ol_lis[index].className = 'current';
}
changeImg();
}
//转换图片
function changeImg(){
var ul_now_x = ul.offsetLeft;
var step = 10;
var sum = - index * imageWidth;
if(ul_now_x > sum){
step = -step;
}
if(ul.timerId){
clearInterval(ul.timerId);
ul.timerId = null;
}
ul.timerId = setInterval(function(){
if(ul_now_x == sum){
clearInterval(ul.timerId);
ul.timerId = null;
return;
}
ul_now_x = ul_now_x + step;
ul.style.left = ul_now_x + 'px';
},30);
}
//清除高亮
function clearGL(){
for(var i = 0; i < ol_lis.length;i++){
ol_lis[i].className = '';
}
}
//6.自动切换图片
var timerId = setInterval(function(){
right.onclick();
},2000);
</script>
</body>
运行结果:
回到顶部
思路:
- 当拖动滚动条的时候,当内容滚动出去10px的时候,改变top导航栏的高度,并且显示回到顶部按钮
- 当点击回到顶部按钮的时候,动画方式,回到最上面,让滚动距离为0
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.header {
position: fixed;
z-index: 20;
left: 0;
top: 0;
height: 90px;
width: 100%;
background-color: #fff;
transition: height .3s;
}
.header.fixed {
height: 50px;
box-shadow: 0 0 1px 0 rgba(0,0,0,.3),0 0 6px 2px rgba(0,0,0,.15);
}
.to-top {
width: 50px;
height: 50px;
background-image: url(http://s.url.cn/qqun/xiaoqu/buluo/p/js/images/to_top.6a40e92f2a02f3945477ff9937f5cb20.png);
background-repeat: no-repeat;
background-position: 0 0;
background-size: 50px 50px;
cursor: pointer;
display: none;
position: fixed;
bottom: 150px;
left: 86%;
}
</style>
</head>
<body>
<div id="wrap">
<div id="top" class="header" data-reactid=".0.0">
此间内容与回到顶部无关,省略,为导航栏部分
</div>
<div class="cls" id="content">
此间内容与回到顶部无关,省略,为页面内容
</div>
</div>
<div class="to-top" id="totop"></div>
<script>
var top1 = document.getElementById('top');
/*滚动事件,因为滚动条是属于窗口的,所以对象是window*/
window.onscroll = function(){
//1. 当拖动滚动条的时候,当内容滚动出去10px的时候,改变top的高度,并且显示回到顶部按钮
///获取滚动距离,处理兼容性问题
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
if(scrollTop >= 10){
top1.className = 'header fixed';
totop.style.display = 'block';
}else{
top1.className = 'header';
totop.style.display = 'none';
}
}
//2.当点击回到顶部按钮的时候,动画方式,回到最上面,让滚动距离为0
totop.onclick = function(){
if(totop.timerId){
clearInterval(totop.timerId);
totop.timerId = null;
}
totop.timerId = setInterval(function(){
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
var step = 5;
if(scrollTop <= 0){
clearInterval(totop.timerId);
totop.timerId = null;
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
return;
}
scrollTop = scrollTop - step;
document.body.scrollTop = scrollTop;
document.documentElement.scrollTop = scrollTop;
},5)
}
</script>
</body>
模拟微信聊天案例
<head>
<meta charset="UTF-8">
<title>微信聊天窗口</title>
<style>
* {
margin: 0;
padding: 0;
list-style: none;
font-family: '微软雅黑'
}
#container {
width: 450px;
height: 600px;
background: #eee;
margin: 10px auto 0;
position: relative;
box-shadow: 0px 0px 16px #999;
}
.header {
background: #000;
height: 34px;
color: #fff;
height: 40px;
line-height: 40px;
font-size: 20px;
padding: 0 10px;
}
.footer {
width: 430px;
height: 40px;
background: #999;
position: absolute;
bottom: 0;
padding: 10px;
}
.footer input {
width: 300px;
height: 38px;
outline: none;
font-size: 16px;
text-indent: 10px;
position: absolute;
border-radius: 6px;
right: 80px;
}
.footer span {
display: inline-block;
width: 62px;
height: 38px;
background: #ccc;
font-weight: 900;
line-height: 38px;
cursor: pointer;
text-align: center;
position: absolute;
right: 10px;
top: 14px;
border-radius: 6px;
}
.footer span:hover {
color: #777;
background: #ddd;
}
.icon {
display: inline-block;
background: red;
width: 50px;
height: 50px;
border-radius: 30px;
position: absolute;
bottom: 3px;
left: 10px;
cursor: pointer;
overflow: hidden;
}
img {
width: 60px;
height: 60px;
border-radius: 8px;
}
.content {
font-size: 20px;
width: 435px;
height: 490px;
overflow: auto;
padding: 5px;
}
.content li {
margin-top: 10px;
padding-left: 10px;
width: 412px;
display: block;
clear: both;
overflow: hidden;
}
.content li img {
float: left;
}
.content li span {
background: #7cfc00;
padding: 10px;
border-radius: 10px;
float: left;
margin: 6px 10px 0 10px;
max-width: 310px;
border: 1px solid #ccc;
box-shadow: 0 0 3px #ccc;
}
.content li img.imgleft {
float: left;
}
.content li img.imgright {
float: right;
}
.content li span.spanleft {
float: left;
background: #fff;
}
.content li span.spanright {
float: right;
background: #7cfc00;
}
</style>
</head>
<body>
<div id="container">
<div class="header"> <span style="float: right;">20:30</span> <span style="float: left;">小泽老师</span> </div>
<ul class="content"></ul>
<div class="footer">
<div class="icon"> <img src="img/1.png" alt="" id="icon"> </div>
<input id="text" type="text" placeholder="说点什么吧..."> <span id="btn">发送</span> </div>
</div>
</body>
<script type="text/javascript">
/*思路分析:
1. 点击图标,实现用户切换功能
2. 点击发送按钮,把用户聊天内容展示在聊天区域*/
//切换用户
var path1 = "img/1.png";
var path2 = "img/2.png";
icon.onclick = function(){
var imagePath = icon.src;
if(imagePath.endsWith(path1)){
icon.src = path2;
}else{
icon.src = path1;
}
}
//发送消息
btn.onclick = function(){
//获取输入框的内容
var ltnr = text.value;
//判断输入框中是否有内容,没有不允许发送
if(ltnr == ""){
return;
}
//获取用户头像的路径
var imagePath = icon.src;
var li = document.createElement("li");
var img = document.createElement("img");
img.src = imagePath;
var span = document.createElement('span');
span.innerText = ltnr;
if(imagePath.endsWith(path1)){
//left
img.className = "imgleft";
span.className = "spanleft";
li.appendChild(img);
li.appendChild(span);
}else{
//right
img.className = "imgright";
span.className = "spanright";
li.appendChild(img);
li.appendChild(span);
}
//将聊天内容添加到ul中去
var ul = document.querySelector('.content');
ul.appendChild(li);
//清空输入框的内容
text.value = "";
//让滚动条在发送消息时一直处于底部
var sHeight = ul.scrollHeight;
ul.scrollTop = sHeight;
}
</script>