珠峰JS笔记3.1(盒子模型、偏移量)

> 盒子模型常用的属性

元素操作相关 <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;

猜你喜欢

转载自blog.csdn.net/asjean/article/details/84436560
今日推荐