微信搜索我吃你家米了关注公众号JavaScript Dom编程 ——2_mysql

这个还是接着这篇文章写的

那一篇写得太长了,编辑器有点吃不消,所以又新开了一篇

nodetype取值

图片参考自

JavaScript Dom编程 ——2_i++_02

使用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);

效果如下:

JavaScript Dom编程 ——2_时间间隔_03

可以看到我们对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,就变成了蓝底红字

JavaScript Dom编程 ——2_元素节点_04

对我们上面一篇中的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)

JavaScript Dom编程 ——2_i++_05

上面的代码我们只是做个演示,所以写的比较粗糙,很多东西都是直接硬编码到方法内部的,下面我们对上面的代码进行优化

我们将对以下内容进行参数化

  • 要移动的元素的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);
}

完整代码