V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
SolidZORO
V2EX  ›  问与答

问一JS基本问题,关于nextSibling。

  •  
  •   SolidZORO · 2011-03-10 01:13:32 +08:00 · 5272 次点击
    这是一个创建于 5037 天前的主题,其中的信息可能已经有所发展或是发生改变。
    代码目的是改变<h1>下一个节点的颜色。
    由于IE/Fx对nextSibling有不同的判断就必需写function getNextElement 来做判断,随之而来的是一些我搞不明白的问题。


    // HTML代码片段
    ----------------------------------------------------------
    <h1> H1 </h1>
    <p> PPP </p>
    <p> PPP </p>
    ----------------------------------------------------------


    //Javascript代码片段
    ----------------------------------------------------------
    function h1Next() {
    if (!document.getElementsByTagName) return false;
    var h1s = document.getElementsByTagName("h1");
    for (var i=0; i<h1s.length; i++) {
    var ppp = getNextElement(h1s[i].nextSibling);
    ppp.style.color = "red";
    }
    }


    //书上这样写
    function getNextElement(node) {
    if (node.nodeType == 1) {
    return node;
    }
    //Q:这个代码我看得有点糊涂。
    if (node.nextSibling) {
    return getNextElement(node.nextSibling);
    }
    //Q: 为什么还要返回个null呢?
    return null;
    }


    //我这样写写
    function getNextElement(node) {
    //如果nodeType是1,就直接返回node(IE),否则继续找下一个节点。(FF)
    //Q:我想知道这样写的弊端是什么?
    if (node.nodeType == 1) {
    return node;
    } else {
    return node.nextSibling;
    }
    }

    ----------------------------------------------------------


    以上问题代码出自 《JavaScript DOM 编程艺术》。卡在这里不能理解了。所以求各位指点一下。
    12 条回复    1970-01-01 08:00:00 +08:00
    lovekunzi
        1
    lovekunzi  
       2011-03-10 01:17:03 +08:00
    知之为知之,不知为不知. 反正我是看不懂了.
    dismory
        2
    dismory  
       2011-03-10 01:37:28 +08:00 via iPhone
    递归直到找到元素节点或空后返回。
    gonghao
        3
    gonghao  
       2011-03-10 02:08:32 +08:00
    LZ 请注意,书上的写法实际是一种递归的写法,第二个IF后实际是调用自身getNextElement,实际这样完全可以改写成while循环的形式,我承认这种形式有点儿装B~
    https://gist.github.com/862657

    至于如果LZ明白了这里的意思,自然也就知道自己的写法为什么有缺陷了~

    至于这个问题的根本,为什么要做这个判断,LZ应该也是明白了,万恶的兼容性啊~~
    gonghao
        4
    gonghao  
       2011-03-10 02:09:25 +08:00
    <script src="https://gist.github.com/862657.js?file=getNextSibling"></script>

    貌似刚刚那样发不出去~
    gonghao
        5
    gonghao  
       2011-03-10 02:10:42 +08:00
    git://gist.github.com/862657.git

    不好意思,刷屏了~~
    benzhe
        6
    benzhe  
       2011-03-10 02:14:28 +08:00
    确定你写的那段能达到你预期的效果?原function是个循环,而你的只是一个判断,@dismory 的说法是对的。
    gonghao
        7
    gonghao  
       2011-03-10 02:16:13 +08:00
    https://gist.github.com/862657.js

    悲剧呀,为啥gist就是没办法贴出来啊?
    SolidZORO
        8
    SolidZORO  
    OP
       2011-03-10 02:24:41 +08:00
    @gonghao 了解了。原来是这样。也就是说,在IE下,如果一直有很多null或者空白节点都没关系。他会一直循环找到下一个type==1的节点为止对吧?

    我是看不大懂这样的嵌套。return getNextElement(node.nextSibling); 这个能更加详细的解释一下么?


    还有你在github上的;
    function getNextSibling(ele) {
    while (ele = ele.nextSibling) {
    if (1 === ele.nodeType) return ele;
    }
    }

    我也看不明白。。。。。1 === ele.nodeType 可以反过来写么? ele.nodeType === 1 这样。
    gonghao
        9
    gonghao  
       2011-03-10 02:48:03 +08:00
    @SolidZORO 空白节点这个问题是FF才有滴,主要是由于你的HTML中,两个节点间的换行符可能会导致一个空的TextNode~嗯,你理解了这里为什么要用递归,就是防止存在多个空的TextNode节点~

    return getNextElement(node.nextSibling); 这句是典型的递归调用,不清楚的话可以google一下,直观的说法就是,首先判断当前node是不是nodeType为1,否则的话则检查这个node的nextSibling,即当前node = node.nextSibling,由此反复开始判断~那么这个判断什么时候终止呢?乐观情况,找到了所需要的nextSibling,则直接返回(第一个if的return),极端情况就是找不到这样的节点,则返回null(最后的那个return null)

    至于我代码里面那个判断,逻辑判断左右操作数交换位置是不存在问题的,这样写的好处是防止误把逻辑判断写成了赋值,即 误将 foo == 1 写成了 foo = 1,如果你用我说的这种写法,1 == foo,误写的话就是1 = foo,这样在执行期间就会报语法错误,很容易排查~

    建议学习JS最好还是从语言根本开始,DOM、浏览器部分可以放放,把JS当成一门纯粹的语言来学会好很多~
    SolidZORO
        10
    SolidZORO  
    OP
       2011-03-10 02:56:57 +08:00
    @gonghao 嗯。空白节点的确是FF才有的,刚错打成IE了。谢谢你的耐心教导,我这人学程序类的东西没什么天分,逻辑不大好,很多东西一时间也看不明白。经过你一说,我就明白很多之前纠结的问题了。1 === foo 的方式很好,之后我写非赋值的语句也得这样。

    之前我还不敢碰JS。因为觉得有点乱七八糟的。现在碰碰,觉得蛮有意思的。 我没什么语言基础。实在是比较困难了。多谢指教。
    gonghao
        11
    gonghao  
       2011-03-10 03:05:53 +08:00
    @SolidZORO 呵呵,客气客气了~刚开始都是这样的,慢慢就会好起来的了,多给自己一些信心呢~

    反正跟着自己兴趣走嘛,感兴趣就多玩玩呢,呵呵~~
    lepture
        12
    lepture  
       2011-03-10 11:21:27 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3055 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 13:52 · PVG 21:52 · LAX 05:52 · JFK 08:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.