V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
isbase
V2EX  ›  JavaScript

遇到一个关于 JavaScript 的 for 循环问题

  •  
  •   isbase · 2015-11-10 17:53:19 +08:00 · 2507 次点击
    这是一个创建于 3097 天前的主题,其中的信息可能已经有所发展或是发生改变。

    屏幕快照_2015-11-10_17_40_59.png

    在 chrome 控制台执行 $('#main [class=github]') 就会重现问题,检查之后发现是上图里的问题

    JS Code

    function $(selector) {
        var str = selector.split(' '),
            temp,
            element = document;
        console.log(str[0]);
        for (var i = 0; i < str.length; i++) {//ID
            if (str[i].indexOf('#') === 0) {
                temp = str[i].replace('#', '');
                element = element.getElementById(temp);
            }
            else if (str[i].indexOf('.') === 0) {//Class
                temp = str[i].replace('.', '');
                element = element.getElementsByClassName(temp)[0];
            }
            else if (str[i].indexOf('#') === -1 && str[i].indexOf('.') === -1 && str[i].indexOf('[') === -1) {//Tag
                element = element.getElementsByTagName(str[i])[0];
            }
            else if (str[i].indexOf('[') === 0 && str[i].indexOf('=') === -1) {//属性
                temp = str[i].replace('[', '').replace(']', '');
                //console.log(temp)
                //console.log(element.length,element)
                //console.log(doc.length)
                for (var element = element.getElementsByTagName('*'), j = 0; j < element.length; j++) {
                    if (element[j].hasAttribute(temp) === true) {
                        element = element[j];
                    }
                }
            }
            else {//属性值
                temp = str[i].replace('[', '').replace(']', '');
                temp = temp.split('=');
                element = element.getElementsByTagName('*');
                for (var j = 0, l = element.length - 1; j < l; j++) {
                    console.log('j=' + j, 'element.length=' + l);
                    if (element[j].attributes.length != 0) {
                        //var xxx = element[j].attributes.length - 1;
                        console.log('j=' + j);
                        //for (var i = 0; i < xxx; i++) {
                        console.log('j=' + j);
                        if (console.log(j) && [j].attributes[temp[0]] != undefined && element[j].attributes[temp[0]].value === temp[1]) {
                            console.log('j=' + j);
                            element = element[j];
                        }
                        //}
                    }
    
                }
            }
        }
        return element;
    }
    

    HTML Code

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    </head>
    <body>
    <div id="main" class="main2">
        <h1 id="tit" class="title">JavaScript</h1>
    <!--comment-->
        <p class="test test1 test2">
            <span>
                <a href="baidu.com" class="baidu"></a>
                <a href="github.com" class="github"></a>
            </span>
        </p>
    </div>
    <div id="main2">
            <span>
                <a href="baidu.com" class="baidu">WEB</a>
                <a href="github.com" class="github">web</a>
            </span>
    </div>
    <ol></ol>
    <script src="util.js"></script>
    </body>
    </html>
    
    11 条回复    2015-11-11 17:06:34 +08:00
    domty
        1
    domty  
       2015-11-10 18:07:02 +08:00
    没细看,说错了当我没说
    难道不是 j=4,l=4 的时候中止循环
    所以 j=3 还在执行 j=4 不执行有错?
    isbase
        2
    isbase  
    OP
       2015-11-10 18:09:36 +08:00
    在 chrome 控制台执行 $('#main [class=github]') 后正确结果应该是返回
    <a href="baidu.com" class="baidu"></a>
    learnshare
        3
    learnshare  
       2015-11-10 18:09:46 +08:00
    没错啊,你自己这么写的
    isbase
        4
    isbase  
    OP
       2015-11-10 18:12:02 +08:00
    @domty 在 chrome 控制台查看日志 j 就没有循环到 4 ,到 3 就停止了
    isbase
        5
    isbase  
    OP
       2015-11-10 18:17:15 +08:00
    ```
    function $(selector) {
    var str = selector.split(' '),
    temp,
    element = document;
    console.log(str[0]);
    for (var i = 0; i < str.length; i++) {//ID
    if (str[i].indexOf('#') === 0) {
    temp = str[i].replace('#', '');
    element = element.getElementById(temp);
    }
    else if (str[i].indexOf('.') === 0) {//Class
    temp = str[i].replace('.', '');
    element = element.getElementsByClassName(temp)[0];
    }
    else if (str[i].indexOf('#') === -1 && str[i].indexOf('.') === -1 && str[i].indexOf('[') === -1) {//Tag
    element = element.getElementsByTagName(str[i])[0];
    }
    else if (str[i].indexOf('[') === 0 && str[i].indexOf('=') === -1) {//属性
    temp = str[i].replace('[', '').replace(']', '');
    //console.log(temp)
    //console.log(element.length,element)
    //console.log(doc.length)
    for (var element = element.getElementsByTagName('*'), j = 0; j < element.length; j++) {
    if (element[j].hasAttribute(temp) === true) {
    element = element[j];
    }
    }
    }
    else {//属性值
    temp = str[i].replace('[', '').replace(']', '');
    temp = temp.split('=');
    element = element.getElementsByTagName('*');
    for (var j = 0, l = element.length - 1; j < l; j++) {
    console.log('j=' + j, 'element.length=' + l);
    if (element[j].attributes.length != 0) {
    //var xxx = element[j].attributes.length - 1;
    console.log('j=' + j);
    //for (var i = 0; i < xxx; i++) {
    console.log('j=' + j);
    if (element[j].attributes[temp[0]] != undefined && element[j].attributes[temp[0]].value === temp[1]) {
    console.log('j=' + j);
    element = element[j];
    }
    //}
    }

    }
    }
    }
    return element;
    }
    ```
    Cloudee
        6
    Cloudee  
       2015-11-10 18:18:00 +08:00
    @isbase 循环条件是 j < l , l = 4 的时候 j 是 0 1 2 3 ,你要是遍历全部节点的话 l 不用-1
    nino
        7
    nino  
       2015-11-10 18:22:06 +08:00
    没理解,从 0 循环到 3 不就是四次吗
    isbase
        8
    isbase  
    OP
       2015-11-10 18:22:24 +08:00
    @Cloudee Thanks
    liuxiaoxiaochen
        9
    liuxiaoxiaochen  
       2015-11-10 18:46:19 +08:00
    理解一下 for 循环你就会明白为什么了 for 循环是倒着来的 从后往前判断 你 j=3 了 再来的话先执行 j++ 此时 j = 4 4< 4 吗? 所以就停止了
    isbase
        10
    isbase  
    OP
       2015-11-10 18:47:48 +08:00 via Android
    @liuxiaoxiaochen 蒙住了,多谢
    Heroy
        11
    Heroy  
       2015-11-11 17:06:34 +08:00
    下标从零开始~~~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2291 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 03:53 · PVG 11:53 · LAX 20:53 · JFK 23:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.