> 盒子模型常用的属性
元素操作相关 <div id='box'> ... </div>
查看控制台
odiv.attributes
.getNamedItem(‘id’) 回车 得到 id的值
id="box"
odiv.classList
.add(‘test100’) 回车 给元素添加了一个 test100 的类
undefined
odiv.classList
.remove(‘test100’) 回车 删除 类 test100
undefined
box.className
= ‘cur red’ 回车 设置元素的类
“cur red”
odiv.contentEditable = true 回车 可以直接在浏览器上更改内容
\1 client 系列
clientWidth / clientHeight
content + padding
clientLeft
左边框的宽度 clientTop
上边框的高度 ( 即各边框宽度 borderWidth )
\2 offset 系列
offsetWidth
/ offsetHeight
: content + padding + border
offsetParent
: 当前元素的父级参照物
offsetLeft
/offsetTop
当前元素的外边框距离父级参照物的内边框的偏移量
\3 scroll 系列
scrollWidth
/ scrollHeight
在没有内容溢出的情况下,等于 clientWidth
有溢出时: scrollHeight 值 为:真实的高度(包含溢出)+ 上 padding
这个值是约等于的,设置 overflow: hidden; 对结果有影响,不同浏览器处理的结果不同
scrollTop
/ scrollLeft
滚动条卷去的宽 / 高度
ps: 关于 JS 盒子模型取值的问题
通过以上属性获取的结果永远不可能出现小数,都是整数,浏览器在获取结果的时候,进行了四舍五入
关于操作浏览器本身的盒子模型信息
clientWidth / clientHeight 是当前浏览器可视窗口的宽 / 高度(一屏)
scrollWidth / scrollHeight 是当前页面的真实宽 / 高度(所有屏相加的结果) , 是一个约等于的值
不管哪些属性,也不管是什么浏览器,想要兼容的话,设置和取值都要写两套
document.documentElement[attr] || document.body[attr]
document.documentElement[attr] 必须在前
var len = document.documentElement.clientWidth || document.body.clientWidth;
编写一个有关于操作浏览器盒子模型的方法
如果只传递了 attr,该方法为获取值
如果两个参数都传递了,该方法为设置属性值
这就是 JS 中的类似 类的重载,同一个方法,通过传递参数的不同实现不同的功能
function myAttr( attr, value){
if( typeof value === 'undefined'){ // []
return document.documentElement[attr] || document.body[attr];
}
// 设置 属性值
document.documentElement[attr] = value;
document.body[attr] = value;
}
获取元素的某一个具体的样式的属性值
\1 元素.style.属性名
需要把样式写在行内样式上才可以得到,(写在样式表中的是不能获取的)
在真实项目中,这种方式不常用 (无法实现 css 和 html 的分离)
\2 使用 window.getComputedStyle 这个方法获取所有经过浏览器计算过的样式(没写的样式,也可以获取)
window.getComputedStyle( 要操作的元素对象,null )
第二个参数是当前要操作元素的伪类,一般写成 null
该方法获取的结果是 CSSStyleDeclaration 这个类的一个实例 ,包含了当前元素的所有样式属性和值
取值:
var cssVal = window.getComputedStyle( box, null);
cssVal.height 或者
cssVal['height']
注意: 这个方法在 IE6-8 下是不兼容的,在 IE6-8 下使用 currentStyle 来获取所有经过浏览器计算过的样式 box.currentStyle.height
处理兼容
\1 用 try catch 来处理(只有在不得已的情况下才使用它)
前提:必须保证 try 中的代码在不兼容的浏览器中执行的时候报错,这们才可以用 catch 捕获到异常的信息,进行其他处理 ( 消耗性能 )
function getCssVal( cur, attr){
var val = null;
try {
val = document.getComputedStyle(cur,null)[attr];
} catch(e){
val = cur.currentStyle[attr];
}
return val;
}
console.log( getCssVal(box, 'fontFamily')); // 'height'
\2 判断浏览器是否存在这属性,存在就兼容,不存在就不兼容(最常用 )
if( 'getComputedStyle' in window )
或者 if( window.getComputedStyle )
\3 通过检测浏览器版本和类型来处理兼容
window.navigator.userAgent
if(/MSIE (6|7|8)/.test(navigator.userAgent))
处理兼容后,用兼容后的方法获取值,标准浏览器和 IE 获取的结果,部分样式还是不一样的,主要是由于两个方法的不一样
第一次升级:将获取到的值去掉单位(parseFloat)
第二次升级 :有些样式在不同浏览器中是不兼容的 例如 opacity
opacity: 0.1;
透明度,在 IE 6-8 下不兼容
filter: alphpa(opacity=10);
用滤镜来处理
if( attr === "opacity" ) { val = cur.currentStyle["filter"]; } else { ... }
ps: 写 CSS 时先初始化默认样式,避免浏览器之间的差异,对 JS 获取到的结果一致也是有帮助的
第二个参数传入 after before 可以得到伪类的样式
伪类:在一个元素标签的前面或者后面,创建一个新的虚拟的标签(可以给这个标签增加样式,内容等…)
.clearfix { /*伪元素清浮动*/
zoom: 1;
}
.clearfix {
content: "";
width: 0;
height: 0;
display: block;
overflow: hidden;
clear: both;
}
null / undefined
两者都代表没有,但是 null 是属性存在,但是值不存在
undefined 是连这个属性都不存在
document.parentNode
(浏览器天生自带的一个属性,父亲节点,HTML 结构层级关系中的上一级元素),值为 null, 因为页面中 document 已经是最顶级的元素了
document.parentnode 值为 undefined 因为没有这个属性
offsetParent
父级参照物,默认最外层的元素是里面所有元素的父级参照物
可以通过修改父级 position 的值( relative / absolute / fixed )来修改父级参照物
offsetTop
/ offsetLeft
当前元素外边框距离父级参照物内边框的距离
思考 :求出页面任意一个元素距离 body 的偏移量
\1 先获取自身的左偏移
\2 获取父级参照物 P,加上 P 的偏移量和边框
\3 基于当前 P,再找父级参照物,加上其偏移量和边框,再往上找父级参照物,加上其偏移量和边框,再往上找进行相加操作,直到父级参考物为 null
function getEleToBody(curEle){ // 父级参照物
var totalLeft = null,totalTop=null, par = curEle.offsetParent;
totalLeft += curEle.offsetLeft;
totalTop += curEle.offsetTop;
while(par){ // 循环的条件
// 加上父级的 偏移和边框
totalLeft = totalLeft + par.offsetLeft + par.clientLeft;
totalTop = totalTop + par.offsetTop + par.clientTop;
par = par.offsetParent; // 重赋值
}
return { "totalLeft":totalLeft, "totalTop": totalTop };
}
console.log(getEleToBody(box));
> 浏览器卷去的宽度 / 高度
前面的 client 系列 / offset 系列 / scrollWidth / scrollHeight 都是只读属性
scrollTop / scrollLeft 滚动条卷去的高度 / 宽度 , 这两个是唯一可读写属性
scrollTop 存在边界值,超出边界值无效
最小 0
最大 元素.scrollHeight - 元素.clientHeight
box.scrollTop = -1000; // 超出边界范围,回到顶部
console.log(box.scrollTop); // 结果为 0
ps:
a 标签的 hover 样式是兼容的,其它的可能不兼容
a 标签
\ href = “” 为空,刷新本页面
\ href = “#idname
” 页面跳转到 id 为 idname 处
\ href = “javascript:;
” 取消页面默认行为
css 选择器
\ p ~ div
选择 p 标签后面的兄弟元素 div
\ p + div
选择 p 标签后面相邻的一个 div 元素
a 标签实现 tab 选项卡
设置 body 高度为可视区域的 5 倍高:
html,
body { height: 500%} html 也要写上
设置每屏 li 为可视区域大小:
html > body > ul > li
html, body, ul, li 都设置了 height: 100%;查看高度是一样的
定时器:
var timer = window.setTimeout(function(){ },1000); // 1 秒后执行,执行后定时器清除
window.setInterval(function(){},1000); // 每秒执行一次,直到手动清除定时器
设置定时器是有返回值的,值为 数字,代表当前是第几个定时器
清除定时器
window.clearTimeout(1); // 清除第一个定时器(定时器是从1开始计数的)
window.clearInterval(timer); // 可清除 setTimeout 开启的定时器
setTimeout 模拟 setInterval ( 递归思想 )
function fn(){
// 优化:每次执行前,先把前面的定时器清除
clearTimeout(timer);
n++;
console.log( n + 'js 代码');
if( 5 === n ){ return; }
timer = setTimeout(fn,1000);
}
fn();
缓步动画
var duration = 500; // 总时间 500ms 回到顶部
var interval = 10; // 频率 多长时间走一次 10ms 一次
var target = document.documentElement.scrollTop || document.body.scrollTop; // 总距离
var step = target / duration * interval; // 每一次走的距离 步长
再开定时器, setInterval( function(){...}, interval );
回顶部的按钮条件出现 ( 距离超过一屏出现,少于一屏消失 )
window.onscroll = function(){
// 页面卷去的距离
var curTop = document.documentElement.scrollTop || document.body.scrollTop;
// 当前屏幕高度
var het = document.documentElement.clientHeight || document.body.clientHeight;
backTop.style.display = curTop > het ? 'block' : 'none';
}
点击回顶部按钮时也消失,只事件中添加 this.style.display = "none"
没用,因为 window.onscroll
一直在监听
所以,在点击后,要把 window.onscroll
事件置空,在最后关闭定时器的时候再开启这个事件 (处理:window.onscroll
= 函数名; )
文字左右跑马灯:
鼠标滑上时停止移动,移开鼠标继续移动
onmouseover
onmouseout
white-space: nowrap; 强制文字不换行
原理: 复制一份文字到后面,当前一份完全走完的时候,重置 scrollLeft 为 0;
文字向左走,到最大值的时候自动停止移动,但定时器还没有消失
判断代码相加前后值相等,
让块级元素同行显示
\ display: block;
\ display: inline-block;
注意空格的问题
JS 中的两种编程思想: 同步 、异步
同步:上一件事情没有完成,继续处理上一件事件,只有上一件完成了,才会做下一件事件(JS 中大部分都是同步编程的)
异步: 规划要做一件事情,但是不是当前立马去执行,需要等一段时间,这样,继续执行下面的操作,只有后面的事情都处理完成了,才会返回处理之前的事情 ,如果下面的事情并没有处理完成,不管之前的事情有没有到时间,都只能等着
JS 中异步编程只有四种情况:
定时器
所有的事件绑定
Ajax 读取数据的时候,一般设置为异步
回调函数
var n = 0;
window.setTimeout(function(){
n++;
console.log(n); // 1 第 2 个输出
},0);
console.log(n); // 0 第 1 个输出
\1 每一个浏览器对于定时器的等待时间都有一个最小的值,谷歌:5-6 ms, IE: 10-13 ms ,如果设置的等待时间小于这个值,也不起作用,还是要等到最小时间后才执行
\2 在上面代码的最后面加 while( 1 ) { ..}
代码死循环,while 后面的代码不执行,定时器中的代码也不执行(定时器中设置的等待时间,时间到了,代码也不一定执行)
\3 定义一个变量 n ;
a 再设置两个定时器,前一个定时器等待的时间要长一些 ;
b 打印变量 n ;
c 空的 for 循环, i 到 100000;
d 再打印变量 n;
> 图片延迟加载 (优化)
网站性能优化:
\ 尽量减少向服务器请求的次数 “减少 HTTP 请求”
css / js 文件进行合并
ICON 图片也进行合并 -》 雪碧图 css spite
图片的延迟加载
数据的异步加载
在移动端,如果做的是一个简单的宣传页,尽量把 CSS / JS 写成内嵌式
图片延迟加载 ,作用:保证页面打开的速度
原理:
\1 对于首屏内容中的图片,首先给对应的区域一张默认图片占着位置(默认图非常小,一般可以维持在 5kb 以内),当首屏加载完成后(或者给一个个延迟的时间),再开始加载真实的图片
\2 对于其它屏的图片,也是一张默认图占位置,当滚动条滚动到对应区域的时候,再开始加载真实的图片
扩展: 数据的异步加载,开始只把前两屏的数据进行绑定,后面的数据不进行处理,当页面滚动到对应区域的时候再重新请求数据,然后绑定渲染数据
相关代码: div.box > img
开始时,img 标签 没有设置 src 属性,元素设置 display: none; 因为没有 src 属性,页面会显示一张碎图,不美观,将元素隐藏,当真实的图片加载时再显示
给图片父级 div.box 设置背景: background: url("img/default.gif") no-repeat center center #e1e1e1;
用默认图占位,告诉用户此处图片正在加载中
图片标签: <img src="" trueImg="img/jd.jpg"/>
考虑:获取到自定义属性上的 真实图片地址就直接赋值给图片的 src 属性是不严谨的,地址可能出错,控制台也会报错,这样显示的页面还是出错碎图
得到地址后,验证地址的有效性,才进行赋值操作
window.setTimeout(function(){
var tempImg = new Image; // 创建一个临时的 img 对象
tempImg.src = oImag.getAttribute('trueImg');
tempImg.onload = function(){ // 当图片能够正常加载才执行
console.log("图片加载完成!")
oImag.style.display = 'block';
oImag.src = oImag.getAttribute('trueImg');
tempImg = null;
var nowDate = new Date;
console.log(nowDate - newDate); // 图片加载用时
}
console.log("图片正在加载中...");
var newDate = new Date; // 计算图片加载时间
},500);
其它屏图片的加载 :
window.onscroll 事件中:
当 ( 图片的容器高度 + 图片距离页面的高度 )< (一屏的高度 + 页面卷去的高度度)图片加载
当条件成立时,加载真实的图片,第一次加载完成后,页面继续滚动,条件一直成立,又重新加载了图片,影响网站性能
可以在条件成立后,给元素加一自定义属性 banner.isload = true; 表示加载真实图片的操作已经处理过了,不管是否正确加载了图片,都不再处理图片加载了
条件判断中 if( banner.isload ) { return ; }
实例: 移动端多张图上延迟加载
做移动端响应布局必须加 meta 标签name = viewport :快捷键 meta:vp 按 tab
右侧文字自适应
图片 img 样式 display: block; border: none;