nodetype取值
使用js实现在对特定的节点之后的节点进行样式的修改
<head>
<title>Man bites dog</title>
<script type="text/javascript" src="Untitled-1.txt.js">
</script>
</head>
<body>
<h1>Hold the front page</h1>
<p>This first paragraph leads you in.</p>
<p>Now you get the nitty-gritty of the story</p>
<p>The most import information is delivered first.</p>
<h1>Extra! Extra!</h1>
<p>Future developments are unfolding.</p>
<p>You can read all about it here.</p>
</body>
//该方法用于获取下一个元素节点
//判断nodeType是否为1,1代表元素节点,直接返回,否则获取下一个节点
//然后获取该节点的下一个元素节点
function getNextElement(node) {
if(node.nodeType == 1) {
return node;
}
if(node.nextSibling) {
return getNextElement(node.nextSibling);
}
return null;
}
function styleHeaderSiblings() {
if(!document.getElementsByTagName) return false;
var headers = document.getElementsByTagName("h1");
for (let i = 0; i < headers.length; i++) {
var element = getNextElement(headers[i].nextSibling);
element.style.fontWeight = "bold";
element.style.fontSize = "1.2em";
element.style.color = "red";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if(typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
addLoadEvent(styleHeaderSiblings);
效果如下:
可以看到我们对h1
标签后的节点进行了修饰,将字体改为了加粗红色
在上面的js代码中,值得注意的是getNextElement
方法
function getNextElement(node) {
if(node.nodeType == 1) {
return node;
}
if(node.nextSibling) {
return getNextElement(node.nextSibling);
}
return null;
}
该方法用于获取下一个元素节点,注意这里是元素节点,不是节点,这两者是有区别的
这里需要稍微说一下元素节点和节点的区别,节点涵盖的范围比较广泛,文本节点、注释节点等等,都属于节点的范畴,但是元素节点就比较精确了,以我的理解,它专指html标签,就我们这个getNextElement
函数来讲,我们传给它一个h1
节点,那么他就会返回p
节点,而不是返回h1
标签的文本节点
但是上面那种函数的写法是有问题的,如果我们想更改为其他的样式,就需要直接修改getNextElement
方法中的内容,这与编程规范是相违背的,一个好的解决方案是把样式表以class作为选择器单独写出来,当我们想要修饰某个元素节点时,直接将其class设置为外部样式表的class即可
比如:
.example {
font-weight: bold;
font-size: 1.2em;
}
到时候我们只需要编写如下代码即可实现修饰效果:element.className = example
,当然我们也可以使用setAttribute
方法来达到此目的,但是显然使用className
属性来得更简单方便一些
但是直接使用className
存在一点小瑕疵,就是它会把元素节点原来的class属性值替换掉,而我们想达到的目的是追加,其实解决方法也很简单:
element.className += " intro"
这样就行了,两个class以空格分开
演示效果:
.test {
background-color: blue;
}
.intro {
font-weight: bold;
font-size: 1.2em;
color: red;
}
//该方法用于获取下一个元素节点
//判断nodeType是否为1,1代表元素节点,直接返回,否则获取下一个节点
//然后获取该节点的下一个元素节点
function getNextElement(node) {
if(node.nodeType == 1) {
return node;
}
if(node.nextSibling) {
return getNextElement(node.nextSibling);
}
return null;
}
function styleHeaderSiblings() {
if(!document.getElementsByTagName) return false;
var headers = document.getElementsByTagName("h1");
for (let i = 0; i < headers.length; i++) {
var element = getNextElement(headers[i].nextSibling);
element.className += " intro";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if(typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
addLoadEvent(styleHeaderSiblings);
<head>
<title>Man bites dog</title>
<link rel="stylesheet" href="Untitled-1.txt.css" type="text/css" media="screen" />
<script type="text/javascript" src="Untitled-1.txt.js">
</script>
</head>
<body>
<h1>Hold the front page</h1>
<p class="test">This first paragraph leads you in.</p>
<p>Now you get the nitty-gritty of the story</p>
<p>The most import information is delivered first.</p>
<h1>Extra! Extra!</h1>
<p class="test">Future developments are unfolding.</p>
<p>You can read all about it here.</p>
</body>
本来是蓝底的,然后我们执行了js之后,追加了一个class,就变成了蓝底红字
对我们上面一篇中的stripeTables
函数进行优化,之前我们是直接设置style属性值的,现在我们更改为使用class的方式
function stripeTables() {
if(!document.getElementsByTagName)
return false;
var tables = document.getElementsByTagName("table");
for (let index = 0; index < tables.length; index++) {
var odd = false;
var rows = tables[index].getElementsByTagName("tr");
for (let i = 0; i < rows.length; i++) {
if(odd == true) {
rows[i].className += " some_style";
odd = false;
} else {
odd = true;
}
}
}
}
我们可以对函数进一步地进行抽象,将添加class的操作抽象出一个函数:
function addClass(element, value) {
element.className += " ";
element.className += value;
}
而且我们呢进一步地审查styleHeaderSiblings
函数会发现,它只适用于h1
标签,因为我们把h1
标签硬编码到了函数中,这时候我们可以通过传参来使得该函数更加通用:
//该方法用于获取下一个元素节点
//判断nodeType是否为1,1代表元素节点,直接返回,否则获取下一个节点
//然后获取该节点的下一个元素节点
function getNextElement(node) {
if(node.nodeType == 1) {
return node;
}
if(node.nextSibling) {
return getNextElement(node.nextSibling);
}
return null;
}
function styleHeaderSiblings(tag, className) {
if(!document.getElementsByTagName) return false;
var headers = document.getElementsByTagName("h1");
for (let i = 0; i < headers.length; i++) {
var element = getNextElement(headers[i].nextSibling);
addClass(element, className);
}
}
function addClass(element, value) {
element.className += " ";
element.className += value;
}
function addLoadEvent(func) {
var oldonload = window.onload;
if(typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
function beginRender() {
styleHeaderSiblings("h1", "intro");
}
addLoadEvent(beginRender);
使用javascript实现动画效果
所谓js动画,就是让元素随着时间进行进行位置的切换
setTimeout函数设置时间间隔
setTimeout("function", interval)
设置函数的执行时间间隔
代码如下:
function positionMessage() {
if(!document.getElementById) return false;
if(!document.getElementById("message")) return false;
var elem = document.getElementById("message");
elem.style.position = "absolute";
elem.style.left = "50px";
elem.style.top = "100px";
var movement = setTimeout("moveMessage()", 5000);
}
function moveMessage() {
if(!document.getElementById) return false;
if(!document.getElementById("message")) return false;
var elem = document.getElementById("message");
elem.style.left = "200px";
}
function addLoadEvent(func) {
var oldonload = window.onload;
if(typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
addLoadEvent(positionMessage)
上面的代码达到的效果就是,在5秒后,message元素将会右移100个像素
这样做的效果是很突兀的,所以我们下面改进为渐变式的
function positionMessage() {
if(!document.getElementById) return false;
if(!document.getElementById("message")) return false;
var elem = document.getElementById("message");
elem.style.position = "absolute";
elem.style.left = "50px";
elem.style.top = "100px";
//直接调用moveMessage,不设置时间间隔,时间间隔在moveMessage递归调用时设置
var movement = setTimeout("moveMessage()");
}
function moveMessage() {
if(!document.getElementById) return false;
if(!document.getElementById("message")) return false;
var elem = document.getElementById("message");
//使用parseInt将像素值转换为int型
var xpos = parseInt(elem.style.left);
if(xpos == 200 && ypos == 100) return true;
if(xpos < 200) xpos++;
elem.style.left = xpos + "px";
var movement = setTimeout("moveMessage()", 10);
}
function addLoadEvent(func) {
var oldonload = window.onload;
if(typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
oldonload();
func();
}
}
}
addLoadEvent(positionMessage)
上面的代码我们只是做个演示,所以写的比较粗糙,很多东西都是直接硬编码到方法内部的,下面我们对上面的代码进行优化
我们将对以下内容进行参数化
- 要移动的元素的ID
- elementID
- 元素的目的x坐标
- final_x
- 元素的目的y坐标
- final_y
- 移动位置时的时间间隔
- interval
抽象完毕的moveElement
函数
function moveElement(elementId, final_x, final_y, interval) {
if(!document.getElementById) return false;
if(!document.getElementById(elementId)) return false;
var elem = document.getElementById(elementId);
//使用parseInt将像素值转换为int型
var xpos = parseInt(elem.style.left);
var ypos = parseInt(elem.style.top);
if(xpos == final_x && ypos == final_y) return true;
if(xpos < final_x) xpos++;
if(xpos > final_x) xpos--;
if(ypos < final_y) ypos++;
if(ypos > final_y) ypos--;
elem.style.left = xpos + "px";
elem.style.top = ypos + "px";
var repeat = 'moveElement("' + elementId + '", ' + final_x + ', ' + final_y + ', ' + interval + ')';
var movement = setTimeout(repeat, interval);
}