脚本化CSS
css 脚本化基础
使用 style 对象
/*
1. cssText: 返回 style 的 css 样式字符串。
2. length: 返回 style 的声明 CSS 样式的数量。
3. parentRule: 返回 style 所属的 CSSRule 对象。
4. getPropertyCSSValue(): 返回包含指定属性的 CSSValue 对象。
5. getPropertyPriority(): 返回包含指定属性是否附加了 !important 命令。
6. item(): 返回指定下标位置的 CSS 属性名称。
7. getPropertyValue(): 返回指定属性的字符串值。
8. removeProperty(): 从样式中删除给定属性。
9. setProperty(): 为了指定属性设置值,也可以附加优先权标志
*/
getPropertyValue()
方法
// <div id="box" style="width: 300px;height: 200px;border:solid 1px red;">
window.onload = function() {
var box = document.getElementById('box');
var width = box.style.getPropertyValue('width');
box.innerHTML = "盒子宽度:" + width; // '300px'
}
setProperty()
方法
// <div id="box" style="border:solid 1px red;">
window.onload = function() {
var box = document.getElementById('box');
box.style.setProperty("width", "400px", "");
box.style.setProperty("height", "200px", "");
}
removeProperty()
方法
e.style.removeProperty(propertyName);
item()
方法:返回style
对象中指定索引位置的css
属性名称。
var name = e.style.item(index);
getPropertyPriority()
方法:获取指定 css 属性汇总是否附加了!important
优先级命令,如果存在则返回important
字符串,否则返回空字符串。
// <div id="box" style="width:100px;height:100px;background-color:red;border:solid 50px blue;">
window.onload = function() {
var box = document.getElementById('box');
box.onmouseover = function() {
box.style.setProperty("background-color", 'blue', '');
box.style.setProperty("border", 'solid 50px red', '')
}
box.onclick = function() {
box.innerHTML = (box.style.item(0) + ":" + box.style.getPropertyValue('width'));
box.innerHTML = box.innerHTML + "<br>" + (box.style.item(1) + ":" + box.style.getPropertyValue('height'));
}
box.onmouseout = function() {
box.style.setProperty("background-color", "red", "");
box.style.setProperty("border", "solid 50px blue", "");
}
}
使用 styleSheets 对象
在 DOM2
级别规范中,使用 styleSheets
对象可以访问页面中所有样式表,包括用 <style>
标签定义在内部样式表,以及使用<link>
标签或 @import
命令导入的外部样式表。
cssRules
对象中包含了指定样式表中的所有跪着,IE
支持 rules
对象表示样式表中的规则,可以使用下面的兼容写法:
var cssRules = document.styleSheets[0].cssRules || document.styleSheets[0].rules;
/*
通过 <style> 标签定义一个内部样式表,然后再脚本中使用 styleSheets 访问这个内部样式表,把样式表中的第一个样式的所有规则读取出来。
*/
/*
<div id="box"></div>
#box {
width: 400px;
height: 200px;
background-color: #BFFB8F;
border: solid 1px blue;
}
*/
window.onload = function() {
var box = document.getElementById('box');
// 需要在域名中才能访问
var cssRules = document.styleSheets[0].cssRules || document.styleSheets[0].rules;
console.log(cssRules);
box.innerHTML = "<h3>盒子样式</h3>";
box.innerHTML += "<br>边框:" + cssRules[0].style.border;
box.innerHTML += "<br>背景:" + cssRules[0].style.backgroundColor;
box.innerHTML += "<br>高度:" + cssRules[0].style.height;
box.innerHTML += "<br>宽度:" + cssRules[0].style.width;
}
使用 selectorText 对象
使用 selectorText
对象可以获取样式的选择器字符串表示。
/*
<style>
#box { color: green; }
.red { color: red; }
.blue { color: blue; }
</style>
*/
window.onload = function() {
var box = document.getElementById('box');
var cssRules = document.styleSheets[0].cssRules || document.styleSheets[0].rules;
console.log(cssRules[2].selectorText); // .blue
}
编辑样式
window.onload = function() {
var box = document.getElementById('box');
var cssRules = document.styleSheets[0].cssRules || document.styleSheets[0].rules;
cssRules[2].style.color = "#999";
}
添加样式
使用 addRule()
方法可以为样式表增加一个样式:
styleSheet.addRule(selecor, sytle, [index]);
/*
selecor: 样式选择符,以字符串形式传递。
style: 表示具体的声明,以字符串形式传递。
index: 表示一个索引号,表添加样式在样式表中索引位置,默认为 -1,表示位于样式表的末尾,可选。
*/
Firefox
支持使用 insertRule()
方式添加样式:
styleSheet.insertRule(rule, [index]);
/*
rule: 表示一个完整的样式字符串
index: 表示一个索引号,表添加样式在样式表中索引位置,默认为 0,表示位于样式表的末尾,可选。
*/
// 演示
window.onload = function() {
var styleSheets = document.styleSheets[0];
var index = styleSheets.length; // 获取样式表中包含样式的个数
if (styleSheets.insertRule) {
styleSheets.insertRule("p{background-color: red;color:#fff;padding:1em;}", index)
} else {
styleSheets.addRule("P", "background-color: red;color:#fff;padding:1em;", index)
}
}
读取显示样式
css
样式具有重叠特性,因此定义的样式与最终显示的样式并非完全相等。IE
和 DOM
之间标准不同。
IE
浏览器
IE
使用 currentStyle
对象读取元素的最终显示样式,是只读对象。currentStyle
对象包含元素的 style
属性,以及浏览器预定义的默认 style
属性。
/*
<style>
#box {
color: green;
}
.red {
color: red;
}
.blue {
color: blue;
background-color: #ffffff;
}
</style>
*/
window.onload = function() {
var styleSheets = document.styleSheets[0];
var index = styleSheets.length; // 获取样式表中包含样式的个数
if (styleSheets.insertRule) {
styleSheets.insertRule("p{background-color: red;color:#fff;padding:1em;}", index)
} else {
styleSheets.addRule("P", "background-color: red;color:#fff;padding:1em;", index)
}
// 只支持 IE
var p = document.getElementsByTagName('p')[0];
console.log(p.currentStyle);
console.log(p.currentStyle.backgroundColor); // #ffffff
console.log(p.currentStyle.color); // blue
}
- 非
IE
浏览器
DOM
使用 getComputedStyle()
获取目标对象的显示样式,但是它属于 document.defaultView
对象。
window.onload = function() {
var styleSheets = document.styleSheets[0];
var index = styleSheets.length; // 获取样式表中包含样式的个数
if (styleSheets.insertRule) {
styleSheets.insertRule("p{background-color: red;color:#fff;padding:1em;}", index)
} else {
styleSheets.addRule("P", "background-color: red;color:#fff;padding:1em;", index)
}
// 只支持 IE
var p = document.getElementsByTagName('p')[0];
if (document.defaultView && document.defaultView.getComputedStyle) {
console.log(document.defaultView.getComputedStyle(p, null));
console.log(document.defaultView.getComputedStyle(p, null).backgroundColor); // rgb(255, 255, 255)
console.log(document.defaultView.getComputedStyle(p, null).color); // rgb(0, 0, 255)
} else if (p.currentStyle) {
console.log(p.currentStyle);
console.log(p.currentStyle.backgroundColor); // #ffffff
console.log(p.currentStyle.color); // blue
}
}
读取媒体查询
使用 window.matchMedia()
可以访问 css
的 media query
语句。这个方法接收一个 mediaQuery
语句的字符串作为参数,返回一个 MediaQueryList
对象,该对象有两个参数:
media
: 返回所查询的mediaQuery
语句字符串。matches
: 返回一个布尔值,表示当前环境是否匹配查询语句。
var result = window.matchMedia('(min-width: 600px)');
result.media; // (min-width: 600px)
result.matches; // true,当前页面的宽度在 600px 以上,匹配要求
// 根据 mediaQuery 是否匹配当前环境,执行不同的 js 代码
var result = window.matchMedia("(max-width: 768px)");
if (result.matches) {
console.log('页面宽度小于等于 768px');
} else {
console.log('页面宽度大于 768px');
}
// 根据 mediaQuery 是否匹配当前环境,加载不同的 css 样式表
var result = window.matchMedia("(max-width: 768px)");
if (result.matches) {
var linkElm = document.createElement("link");
linkElm.setAttribute("rel", "stylesheet");
linkElm.setAttribute("type", "text/css");
linkElm.setAttribute("href", "small.css");
document.head.appendChild(linkElm);
}
如果 window.matchMedia
无法解析 mediaQuery
参数,返回的总是 false
,而不是报错,如:
window.matchMedia('bad string').matches; // false
window.matchMedia
方法返回的 MediaQueryList
对象有两个方法用来监听事件:addListener
方法和 removeListener
方法。如果 matchMedia
查询结果发生了变化,就调用指定的回调函数。
var mql = window.matchMedia("(max-width: 768px)");
// 执行回调函数
mql.addListener(mqCallback);
// mql.removeListener(mqCallback) // 取消监听
function mqCallback(mql) {
if (mql.matches) {
console.log('宽度小于等于768px');
} else {
console.log('宽度大于768px');
}
}
使用 css 事件
transitionEnd
事件
css
过渡结束后,触发该事件。
el.addEventListener('transitionend', onTransitionEnd, false);
function onTransitionEnd() {
console.log("Transition end");
}
/*
transitionEnd 的事件对象具有一下属性:
1. propertyName: 发生 transition 效果的 css 属性名。
2. elapsedTime: transition 效果持续的秒数,不含 transition-delay 的时间
3. pseudoElement: 如果 transition 效果发生在伪元素上,会返回该伪元素的名称,以 :: 开头,如果没有发生在伪元素上,则返回一个空字符串。
*/
// 实际使用 transitionend 事件时,可能需要添加浏览器前缀。
el.addEventListener('webkitTransitionEnd', function() {
e.style.transition = "none";
}, false);
animationstart
、animationend
、animationiteration
事件
css
动画有以下 3 个事件:
animationstart
: 动画开始时触发。animationend
:动画结束时触发。animationiteration
:开始新一轮动画循环时触发。如果animation-iteration-count = 1
,该事件不会触发。
/*
这 3 个事件的事件对象,都有 animationName 属性 和 elapsedTime 属性(动画已经运行的秒数),对于 animationstart 事件,elapsedTime 属性等于 0 ,除非 animation-deley 属性等于负值。
*/
var el = document.getElementById('animation');
el.addEventListener('animationstart', listener, false);
el.addEventListener('animationend', listener, false);
el.addEventListener('animationiteration', listener, false);
function listener(e) {
var li = document.createElement('li');
switch (e.type) {
case "animationstart":
li.innerHTML = "Started: elapsed time is " + e.elapsedTime;
break;
case "animationend":
li.innerHTML = "Ended: elapsed time is " + e.elapsedTime;
break;
case "animationiteration":
li.innerHTML = "New loop started at time " + e.elapsedTime;
break;
}
document.getElementById('output').appendChild(li);
}
animation-play-state
属性可以控制动画的状态(暂停/播放),该属性需要加上浏览器前缀。
element.style.webkitAnimationPlayState = "paused";
element.style.webkitAnimationPlayState = "running";
设计大小
使用 offsestWidth 和 offsetHeight
使用 offsestWidth 和 offsetHeight 属性可以获取元素的尺寸,其中 offsetWidth 表示元素在页面中所占的总宽度,offsetHeight 表示元素在页面中占的总高度。
/*
<div id="div" style="width:100px;height:100px;background-color:red;"></div>
*/
var div = document.getElementById("div");
var w = div.offsetWidth;
var h = div.offsetHeight;
console.log(w, h); // 100 100
/*
offsestWidth 和 offsetHeight 是获取元素尺寸最好的方式,但是无法获取被隐藏的元素的尺寸,返回的都是 0。
*/
使用 scrollLeft 和 scrollTop
它们可以读写出可视区域外面的宽度和高度。
/*
<div id="div" style="width: 200px;height: 200px;border: red 50px solid;padding: 50px;overflow: auto;">
<div id="info" style="width: 400px;height: 400px;border: 1px solid blue;"></div>
</div>
*/
var div = document.getElementById('div');
div.scrollLeft = 200; // 设置盒子左边滚动区域宽度为 200 像素
div.scrollTop = 200; // 设置盒子左边滚动区域宽度为 200 像素
div.onscroll = function() {
var log = "scrollLeft=" + div.scrollLeft + "\n" + "scrollTop=" + div.scrollTop + "\n" + "scrollWidth=" + div.scrollWidth + "\n" + "scrollHeight=" + div.scrollHeight;
console.log(log)
}
/*
scrollLeft=121
scrollTop=162
scrollWidth=452
scrollHeight=502
*/
获取元素大小
元素尺寸属性 | 说明 |
---|---|
clientWidth | 获取元素可视区域的宽度,即 CSS 的 width 和 padding 的属性之和,元素边框和滚动条不包括在内,也不包含任何可能的滚动区域。 |
clientHeight | 获取元素可视区域的高度,即 CSS 的 height 和 padding 的属性之和,元素边框和滚动条不包括在内,也不包含任何可能的滚动区域。 |
offsetWidth | 元素在页面中占据的宽度总和,包括 width、padding、border 以及滚动条的宽度。 |
offsetHeight | 元素在页面中占据的高度总和,包括 height、padding、border 以及滚动条的高度。 |
scrollWidth | 当元素设置了 overflow:visible 样式属性时,元素的总宽度,也称滚动宽度。在默认状态下,如果该属性值大于 clientWidth,则元素显示滚动条。 |
scrollHeight | 当元素设置了 overflow:visible 样式属性时,元素的总高度,也称滚动高度。在默认状态下,如果该属性值大于 clientHeight,则元素显示滚动条。 |
/*
<div id="div" style="width: 200px;height: 200px;border: red 50px solid;padding: 50px;overflow: auto;">
<div id="info" style="width: 400px;height: 400px;border: 1px solid blue;"></div>
</div>
*/
var div = document.getElementById('div');
var hc = div.clientHeight; // 可视区域高度为 283px
var ho = div.offsetHeight; // 占据页面总高度为 400px
var hs = div.scrollHeight; // 展开滚动内容总高度为 452px
console.log(hc, ho, hs);
计算公式:
clientHeight = padding-top + height + border-bottom-width - 滚动条的宽度;
offsetHeight = border-top-width + padding-top + height + padding-bottom + border-bottom-width;
scrollHeight = padding-top + 包含内容的完全高度 + padding-bottom;
获取窗口大小
获取 标签的 clientWidth 和 clientHeight 属性,就可以知道浏览器窗口的可视宽度和高度,而 标签在脚本中表示为 document.documentElement。
var w = document.documentElement.clientWidth; // 返回值不包含滚动条的宽度
var h = document.documentElement.clientHeight; // 返回值不包含滚动条的宽度
在怪异模式下,body 是最顶层的可视元素,而 html 元素保持隐藏,所有只有通过 body 标签的 clientWidth 和 clientHeight 属性才可以知道浏览器窗口的可视宽度和高度。
var w = document.body.clientWidth;
var h = document.body.clientHeight;
两种方法兼容起来:
var w = document.documentElement.clientWidth || document.body.clientWidth;
var h = document.documentElement.clientHeight || document.body.clientHeight;
如果窗口包含内容超出了窗口的可视区域,则应该使用 scrollWidth 和 scrollHeight 属性来获取窗口的实际宽度的和高度。
设计位置
- 使用 offsetLeft 和 offsetTop
offsetLeft 和 offsetTop 属性返回当前元素的偏移位置。IE 怪异模式以父元素为参照进行偏移位置,DOM标准模式以最近定位元素为参照进行偏移位置。
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>title</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<style>
div {
width: 200px;
height: 100px;
border: solid 1px red;
padding: 50px;
}
#wrap {
position: relative;
border-width: 20px;
}
</style>
</head>
<body>
<div id="wrap">
<div id="sub">
<div id="box"></div>
</div>
</div>
</body>
</html>
- 使用 offsetParent
offsetParent 属性表示最近的上级定义元素。要获取相对父级元素的位置,可以先判断 offsetParent 属性是否指向父元素,如果是,则直接使用 offsetLeft 和 offsetTop 属性获取元素相对于父元素的距离;否则分别获取当前元素和父元素距离窗口的坐标,然后求差即可。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
// 获取指定元素距离窗口左上角偏移坐标
// 参数:e表示获取位置的元素
// 返回值:返回对象直接量,其中属性x表示x轴偏移距离,属性y表示y轴偏移距离
function getPoint(e) {
var x = y = 0; // 初始化临时变量
while (e.offsetParent) {
// 如果存在offsetParent指代的元素,则获取它的偏移坐标
x += e.offsetLeft; // 累计总的x轴偏移距离
y += e.offsetTop; // 累计总的y轴偏移距离
e = e.offsetParent;
// 把当前元素的offsetParent属性值传递给循环条件表达式
}
return {
// 遍历到body元素后,将停止循环,把叠加的值赋值给对象直接量,并返回该对象
"x": x,
"y": y
};
}
// 获取指定元素距离父元素左上角的偏移坐标
// 参数:e表示获取位置的元素
// 返回值:返回对象直接量,其中属性x表示x轴偏移距离,属性y表示y轴偏移距离
function getP(e) {
if (e.parentNode == e.offsetParent) {
// 判断offsetParent属性是否指向父级元素
var x = e.offsetLeft; // 如果是,则直接读取offsetLeft属性值
var y = e.offsetTop; // 读取offsetTop属性值
} else {
// 否则调用getW()扩展函数获取当前元素和父元素的x轴坐标,并返回它们的差值
var o = getPoint(e);
var p = getPoint(e.parentNode);
var x = o.x - p.x;
var y = o.y - p.y;
}
return { // 返回对象直接量,对象包含当前元素距离父元素的坐标
"x": x,
"y": y
};
}
</script>
<style type="text/css">
div {
width: 200px;
height: 100px;
border: solid 1px red;
padding: 50px;
}
#wrap {
position: relative;
border-width: 20px;
}
</style>
</head>
<body>
<div id="wrap">
<div id="sub">
<div id="box"></div>
</div>
</div>
<script>
var box = document.getElementById("box");
var o = getP(box); // 调用扩展函数获取元素相对父元素的偏移坐标
console.log(o.x); // 读取x轴坐标偏移值
console.log(o.y); // 读取y轴坐标偏移值
</script>
</body>
</html>
- 获取指针的页面位置
使用事件对象的 pageX 和 pageY(兼容 Safari),或者 clientX 和 clientY (兼容 IE) 属性,同时还需要配合 scrollLeft 和 scrollYTop 属性,就可以计算出鼠标指针在页面的位置。
<!doctype html>
<html lang="en">
<head></head>
<body style="width: 2000px; height: 2000px;">
<!-- start -->
<textarea id="t" cols="15" rows="4" style="position:fixed;left: 50px;top: 50px;"></textarea>
<!-- end -->
<script>
// 获取指针在整个页面上的位置
function getMP(e) {
var e = e || window.event;
return {
x: e.pageX || e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft),
y: e.pageY || e.clientY + (document.documentElement.scrollTop || document.body.scrollTop)
}
}
var t = document.getElementById('t');
document.onmousemove = function(e) {
var m = getMP(e);
t.value = "mouseX=" + m.x + "\n" + "mouseY=" + m.y;
}
</script>
</body>
</html>
获取指针的相对位置
使用 offsetX 和 offsetY,或者 layerX 和 layerY 可以获取鼠标指针的相对定位包含框的偏移位置,如果使用 offsetLeft 和 offsetTop 属性获取元素在定位包含框中的偏移坐标,然后使用 layerX 属性值减去 offsetLeft 属性值,使用 layerY 属性值减去 offsetTop 属性值,即可得到鼠标指针在元素内部的位置。
// 获取数比哦啊指针在元素内的位置
// 参数:e 表示当前事件对象,o 表示当前元素,返回值:返回相对坐标对象
function getME(e, o) {
var e = e || window.event;
return {
x: e.offsetX || (e.layerX - o.offsetLeft),
y: e.offsetY || (e.layerY - o.offsetTop)
}
}
/*
上面的函数会存在两个问题:
1. Mozilla 类型和 Safari 浏览器以元素边框外壁的左上角为参考点;
2. 其他浏览器则是以元素边框内壁的左上角为坐标原点。
*/
完善上面的函数:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
// 获取指定元素的样式属性值
// 参数:e表示具体的元素,n表示要获取元素的脚本样式的属性名,如"width"、"borderColor"
// 返回值:返回该元素e的样式属性n的值
function getStyle(e, n) {
if (e.style[n]) {
// 如果在Style对象中存在,说明已显式定义,则返回这个值
return e.style[n];
} else if (e.currentStyle) {
// 否则,如果是IE浏览器,则利用它的私有方法读取当前值
return e.currentStyle[n];
}
// 如果是支持DOM标准的浏览器,则利用DOM定义的方法读取样式属性值
else if (document.defaultView && document.defaultView.getComputedStyle) {
n = n.replace(/([A-Z])/g, "-$1"); // 转换参数的属性名
n = n.toLowerCase();
var s = document.defaultView.getComputedStyle(e, null);
// 获取当前元素的样式属性对象
if (s) // 如果当前元素的样式属性对象存在
return s.getPropertyValue(n); // 则获取属性值
} else // 如果都不支持,则返回null
return null;
}
// 完善获取鼠标指针在元素内的位置
// 参数:e表示当前事件对象,o表示当前元素
// 返回值:返回鼠标相对元素的坐标对象,其中属性x表示x轴偏移距离,属性y表示y轴偏移距离
function getME(e, o) {
var e = e || window.event;
// 获取元素左侧边框的宽度
// 调用getStyle()扩展函数获取边框样式值,并尝试转换为数值,如果转换成功,则赋值。
// 否则判断是否定义了边框样式,如果定义边框样式,且值不为none,则说明边框宽度为默认值,即为3像素。
// 如果没有定义边框样式,且宽度值为auto,则说明边框宽度为0
var bl = parseInt(getStyle(o, "borderLeftWidth")) || ((o.style.borderLeftStyle && o.style.borderLeftStyle != "none") ? 3 : 0);
// 获取元素顶部边框的宽度,设计思路与获取左侧边框方法相同
var bt = parseInt(getStyle(o, "borderTopWidth")) || ((o.style.borderTopStyle && o.style.borderTopStyle !=
"none") ? 3 : 0);
var x = e.offsetX || // 一般浏览器下鼠标偏移值
(e.layerX - o.offsetLeft - bl);
// 兼容Mozilla类型浏览器,减去边框宽度
var y = e.offsetY || // 一般浏览器下鼠标偏移值
(e.layerY - o.offsetTop - bt);
// 兼容Mozilla类型浏览器,减去边框宽度
var u = navigator.userAgent; // 获取浏览器的用户数据
if ((u.indexOf("KHTML") > -1) ||
(u.indexOf("Konqueror") > -1) ||
(u.indexOf("AppleWebKit") > -1)
) { // 如果是Safari浏览器,则减去边框的影响
x -= bl;
y -= bt;
}
return { // 返回兼容不同浏览器的鼠标位置对象,以元素边框内壁左上角为定位原点
x: x,
y: y
}
}
</script>
</head>
<body>
<div id="box" style="width:200px;height:200px;border:solid 1px red;float:right;"></div>
<textarea id="t" cols="15" rows="4"></textarea>
<script type="text/javascript">
var t = document.getElementById("t");
var b = document.getElementById("box");
b.onmousemove = function(e) {
var m = getME(e, b);
t.value = "mouseX = " + m.x + "\n" + "mouseY = " + m.y
}
</script>
</body>
获取滚动条的位置
使用 scrollLeft 和 scrollTop 属性也可以获取窗口滚动条的位置。
function getPS() {
var h = document.documentElement;
var x = self.pageXOffset || //兼容早期浏览器 selt(window对象)
(h && h.scrollLeft) || //兼容标准浏览器
document.body.scrollLeft; // 兼容 IE 怪异模式
var y = self.pageYOffset || (h && h.scrollTop) || document.body.scrollTop;
return {
x: x,
y: y
}
}
window.onscroll = function() {
console.log(getPS()) // {x: 41.818180084228516, y: 1454.54541015625}
}
设置滚动条的位置
获取某个元素的位置,让滚动条滚动到这个元素的位置。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
// 获取指定元素距离窗口左上角偏移坐标
// 参数:e表示获取位置的元素
// 返回值:返回对象直接量,其中属性x表示x轴偏移距离,属性y表示y轴偏移距离
function getPoint(e) {
var x = y = 0; // 初始化临时变量
while (e.offsetParent) {
// 如果存在offsetParent指代的元素,则获取它的偏移坐标
x += e.offsetLeft; // 累计总的x轴偏移距离
y += e.offsetTop; // 累计总的y轴偏移距离
e = e.offsetParent;
// 把当前元素的offsetParent属性值传递给循环条件表达式
}
return {
// 遍历到body元素后,将停止循环,把叠加的值赋值给对象直接量,并返回该对象
"x": x,
"y": y
};
}
// 滚动到页面中指定的元素位置
// 参数:指定的对象
// 返回值:无
function setPS(e) {
window.scrollTo(getPoint(e).x, getPoint(e).y);
}
</script>
</head>
<body>
<div style="height:1000px;border:solid 20px red"></div>
<div style="height:1000px;border:solid 20px blue"></div>
<script type="text/javascript">
var d1 = document.getElementsByTagName("div")[0];
var d2 = document.getElementsByTagName("div")[1];
setPS(d2)
</script>
</body>
</html>
设计显隐
显示和隐藏
/*
设置或切换的显示或隐藏
参数:
e: 表示操作元素
b: true 将显示元素 e,false 将隐藏元素 e
如果省略参数 b,则根据元素 e 的状态进行切换
*/
// 获取指定元素的样式属性值
// 参数:e表示具体的元素,n表示要获取元素的脚本样式的属性名,如"width"、"borderColor"
// 返回值:返回该元素e的样式属性n的值
function getStyle(e, n) {
if (e.style[n]) {
// 如果在Style对象中存在,说明已显式定义,则返回这个值
return e.style[n];
} else if (e.currentStyle) {
// 否则,如果是IE浏览器,则利用它的私有方法读取当前值
return e.currentStyle[n];
}
// 如果是支持DOM标准的浏览器,则利用DOM定义的方法读取样式属性值
else if (document.defaultView && document.defaultView.getComputedStyle) {
n = n.replace(/([A-Z])/g, "-$1"); // 转换参数的属性名
n = n.toLowerCase();
var s = document.defaultView.getComputedStyle(e, null);
// 获取当前元素的样式属性对象
if (s) // 如果当前元素的样式属性对象存在
return s.getPropertyValue(n); // 则获取属性值
} else // 如果都不支持,则返回null
return null;
}
function display(e, b) {
// 监测第二个参数的类型。如果该参数存在且不为布尔值,则抛出异常
if (b && (typeof b != "boolean")) throw new Error("第二个参数应该是布尔值!");
var c = getStyle(e, "display"); // 获取当前元素的显示属性值
(c != "none") && (e._display = c);
// 记录元素的显示性质,并存储到元素的属性中
e._display = e._display || "";
// 如果没有定义显示性质,则赋值为空字符串
if (b || (c == "none")) { // 当第二个参数值为true,或者元素隐藏时
e.style.display = e._display;
// 则将调用元素的_display属性值恢复元素或显示元素
} else {
e.style.display = "none"; // 否则隐藏元素
}
}
函数应用:
// 切换显示和隐藏
var p = document.getElementsByTagName("p")[0];
display(p); // 切换隐藏
display(p); // 切换显示
display(p); // 切换隐藏
// 强制显示或隐藏
display(p , true); // 强制显示
半透明显示
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
// 设置元素的透明度
// 参数:e表示要预设置的元素,n表示一个数值,取值范围为0~100,如果省略,则默认为100,即不透明显示元素
// 返回值:无
function setOpacity(e, n) {
var n = parseFloat(n); // 把第二个参数转换为浮点数
if (n && (n > 100) || !n) n = 100;
// 如果第二个参数存在且值大于100,或者不存在该参数,则设置其为100
if (n && (n < 0)) n = 0; // 如果第二个参数存在且值小于0,则设置其为0
if (e.filters) { // 兼容IE浏览器
e.style.filter = "alpha(opacity=" + n + ")";
} else { // 兼容DOM标准
e.style.opacity = n / 100;
}
}
// 获取元素的透明度
// 参数:e表示要预设置的元素
// 返回值:元素的透明度值,范围在1~100之间
function getOpacity(e) {
var r;
if (!e.filters) {
if (e.style.opacity) return parseFloat(e.style.opacity) * 100;
}
try {
return e.filters.item('alpha').opacity
} catch (o) {
return 100;
}
}
</script>
</head>
<body>
<div id="box" style="background:red; width:300px; height:200px;"></div>
<script>
var box = document.getElementById("box");
setOpacity(box, 50);
var n = getOpacity(box);
alert(n);
</script>
</body>
</html>
设计动画
移动动画
移动动画主要通过动态修改元素的坐标来实现:
- 考虑元素的初始坐标、终点坐标,以及移动坐标等定位要素。
- 移动速度、频率等问题可以借助定时器来实现。但效果的模拟涉及算法问题,不同的算法,可能会设计出不同的移动效果,如匀速运动、加速和减速运动。
<!--
设计一个简单的元素移动效果,通过指向元素、移动的位置,以及移动的步数,可以设计按一定速度把元素从当前位置移动到指定的位置。
-->
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
// 获取指定元素的样式属性值
// 参数:e表示具体的元素,n表示要获取元素的脚本样式的属性名,如"width"、"borderColor"
// 返回值:返回该元素e的样式属性n的值
function getStyle(e, n) {
if (e.style[n]) {
// 如果在Style对象中存在,说明已显式定义,则返回这个值
return e.style[n];
} else if (e.currentStyle) {
// 否则,如果是IE浏览器,则利用它的私有方法读取当前值
return e.currentStyle[n];
}
// 如果是支持DOM标准的浏览器,则利用DOM定义的方法读取样式属性值
else if (document.defaultView && document.defaultView.getComputedStyle) {
n = n.replace(/([A-Z])/g, "-$1"); // 转换参数的属性名
n = n.toLowerCase();
var s = document.defaultView.getComputedStyle(e, null);
// 获取当前元素的样式属性对象
if (s) // 如果当前元素的样式属性对象存在
return s.getPropertyValue(n); // 则获取属性值
} else // 如果都不支持,则返回null
return null;
}
// 获取指定元素距离定位包含框元素左上角的偏移坐标
// 参数:e表示获取位置的元素
// 返回值:返回对象直接量,其中属性x表示x轴偏移距离,属性y表示y轴偏移距离
function getB(e) {
return {
"x": (parseInt(getStyle(e, "left")) || 0),
"y": (parseInt(getStyle(e, "top")) || 0)
};
}
// 简单的滑动函数
// 参数:e表示元素,x和y表示要移动的最后坐标位置(相对包含块,t表示元素移动的步数
function slide(e, x, y, t) {
var t = t || 100; // 初始化步数,步数越大,速度越慢,移动的过程越逼真,但是中间移动的误差就越明显
var o = getB(e); // 当前元素的绝对定位坐标值
var x0 = o.x;
var y0 = o.y;
var stepx = Math.round((x - x0) / t);
// 计算x轴每次移动的步长,由于像素点不可用小数,所以会存在一定的误差
var stepy = Math.round((y - y0) / t); // 计算y轴每次移动的步长
var out = setInterval(function() { // 设计定时器
var o = getB(e); // 获取每次移动后的绝对定位坐标值
var x0 = o.x;
var y0 = o.y;
e.style["left"] = (x0 + stepx) + 'px'; // 定位每次移动的位置
e.style["top"] = (y0 + stepy) + 'px'; // 定位每次移动的位置
if (Math.abs(x - x0) <= Math.abs(stepx) || Math.abs(y - y0) <=
Math.abs(stepy)) { // 如果距离终点坐标的距离小于步长,则停止循环执行,并校正元素的最终坐标位置
e.style["left"] = x + 'px';
e.style["top"] = y + 'px';
clearTimeout(out);
};
}, 2)
};
</script>
</head>
<body>
<style type="text/css">
.block {
width: 20px;
height: 20px;
position: absolute;
left: 200px;
top: 200px;
background-color: red;
}
</style>
<div class="block" id="block1"></div>
<script>
temp1 = document.getElementById('block1');
slide(temp1, 400, 400, 20);
</script>
</body>
</html>
渐隐渐现
主要通过修改元素的透明度来实现。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
// 设置元素的透明度
// 参数:e表示要预设置的元素,n表示一个数值,取值范围为0~100,如果省略,则默认为100,即不透明显示元素
// 返回值:无
function setOpacity(e, n) {
var n = parseFloat(n); // 把第二个参数转换为浮点数
if (n && (n > 100) || !n) n = 100;
// 如果第二个参数存在且值大于100,或者不存在该参数,则设置其为100
if (n && (n < 0)) n = 0; // 如果第二个参数存在且值小于0,则设置其为0
if (e.filters) { // 兼容IE浏览器
e.style.filter = "alpha(opacity=" + n + ")";
} else { // 兼容DOM标准
e.style.opacity = n / 100;
}
}
// 获取元素的透明度
// 参数:e表示要预设置的元素
// 返回值:元素的透明度值,范围在1~100之间
function getOpacity(e) {
var r;
if (!e.filters) {
if (e.style.opacity) return parseFloat(e.style.opacity) * 100;
}
try {
return e.filters.item('alpha').opacity
} catch (o) {
return 100;
}
}
// 渐隐渐显动画显示函数
// 参数:e表示渐隐渐显元素,t表示渐隐渐显的速度,值越大渐隐渐显速度越慢,io表示渐隐或渐显方式,取值true表示渐显,取值false表示渐隐
function fade(e, t, io) {
var t = t || 10; // 初始化渐隐渐显速度
if (io) { // 初始化渐隐渐显方式
var i = 0;
} else {
var i = 100;
}
var out = setInterval(function() { // 设计定时器
setOpacity(e, i); // 调用setOpacity()函数
if (io) { // 根据渐隐或渐显方式决定执行效果
i++;
if (i >= 100) clearTimeout(out);
} else {
i--;
if (i <= 0) clearTimeout(out);
}
}, t);
}
</script>
</head>
<body>
<style type="text/css">
.block {
width: 200px;
height: 200px;
background-color: red;
}
</style>
<div class="block" id="block1"></div>
<input type="submit" id="btn" value="渐隐渐显" />
<script>
e = document.getElementById('block1');
btn = document.getElementById('btn');
btn.onclick = function() {
fade(e, 100, true); // 应用渐隐渐显动画效果
}
</script>
</body>
</html>