有个Javascript的问题问问大家 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
chiang
V2EX    问与答

有个Javascript的问题问问大家

  •  
  •   chiang 2012-05-29 16:03:22 +08:00 4366 次点击
    这是一个创建于 4959 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想写一个js功能通过点击不同的单词改变网页背景颜色,无奈无论点击哪个单词网页的背景都是红色。
    HTML片段和JS文件如下:




    效果图



    希望会的人解释一下原因,因为我实在想不出这里面哪里出错了,谢谢了。
    23 条回复    1970-01-01 08:00:00 +08:00
    sogood
        1
    sogood  
       2012-05-29 16:07:04 +08:00
    把 color 的赋值 移到 onclick 里面去。
    chiang
        2
    chiang  
    OP
       2012-05-29 16:12:26 +08:00

    这样的话,单击单词链接,背景色不会改变了。只是白色。
    allenm
        3
    allenm  
       2012-05-29 16:16:06 +08:00   1
    var color = this.getAttribute("title");
    试试看
    allenm
        4
    allenm  
       2012-05-29 16:16:32 +08:00
    放在 onclick 里边
    zythum
        5
    zythum  
       2012-05-29 16:19:01 +08:00   1
    @chiang 这个涉及到作用域的问题。
    尝试
    for(var i=0;i<links.length;i++){
    (function(i){
    links[i].Onclick= ...
    })(i)
    }
    zzxworld
        6
    zzxworld  
       2012-05-29 16:19:10 +08:00   1
    粗略一看你的代码,就发现了问题所在,如果你把red链接移到blue上面去,点哪个都会是蓝色。Javascript中变量是引用传递的,问题就在 var color=links[i].getAttribute('title');
    bit
        7
    bit  
       2012-05-29 16:21:12 +08:00   1
    5楼 @zythum 正解。闭包。推荐楼主看 Javascript the Good Parts.
    zythum
        8
    zythum  
       2012-05-29 16:23:41 +08:00   1
    这个问题貌似js刚上手的童鞋都犯过这个错误。 没事没事。平常心。

    @bit @zzxworld 对把
    013231
        9
    013231  
       2012-05-29 16:24:30 +08:00   1
    bearice
        10
    bearice  
       2012-05-29 16:24:56 +08:00   1
    refs https://developer.mozilla.org/en/Javascript/Reference/Statements/var#section_5

    我以前遇到这种问题都是吧for里面的代码放进一个匿名函数里执行,这样每次循环才会真正申明一个新的变量出来。
    chiang
        11
    chiang  
    OP
       2012-05-29 16:25:49 +08:00
    恩,谢谢各位。由于自己的js,也就刚刚吧 javascrip DOM编程艺术看完,就小小写一个,结果又是涉及到了一个书籍没有涉及的地方,下面一本书打算是 js权威指南,完全自学状态,所以有时候就会凭空想一些功能,然后自己来写。可是问题真是不少呢。
    maikcn
        12
    maikcn  
       2012-05-29 16:26:12 +08:00   1
    参数的作用域问题,将color转变成this就可以了,触发的对象可以直接this获取得到
    for(var i=0; i< links.length; i++) {
    links[i].Onclick= function() {
    document.body.style.backgroundColor = this.getAttribute("title");
    }
    }
    Chris_Ys
        13
    Chris_Ys  
       2012-05-29 16:26:31 +08:00   1
    @zythum 说的作用域是问题所在,但是用闭包来处理就不够优雅了,个人推荐用事件代理:

    document.addEventListener('click', function(e){
    var el = e.target;
    if (el.tagName === "A") {
    // change color by title
    // if (el.getAttribute("title") === "blah blah") { ... }
    // switch (title) { case a: ... case b: ... }
    }
    }, false);
    chiang
        14
    chiang  
    OP
       2012-05-29 16:37:10 +08:00
    @013231 @mailkcn 的貌似在代码上来是挺整洁的。用现在学到的知识也能很好的理解。
    @zythum @bearice @Chtid_Yd 让我看到了更多
    ThanX ,还是第一次问这个问题,自己都拖自己好多时间没解决。
    Chris_Ys
        15
    Chris_Ys  
       2012-05-29 16:52:38 +08:00
    另外,如果有用 ES5 shim 或者只兼容 Chrome/Firefox/IE9+/... 或基于 V8 引擎(Node.js, PHP V8 ext, etc.) 的话,做循环建议用这样的方式:

    [].forEach.call(document.getElementsByTagName('a'), function(item, index){
    item.Onclick= function(){
    document.body.style.backgroundColor = item.getAttribute("title");
    };
    });

    这是 100% 能避开作用域陷阱又保证代码优美的。

    建议 @chiang 了解一下 forEach、map 等函数。
    chiang
        16
    chiang  
    OP
       2012-05-29 17:05:33 +08:00
    @Chris_Ys 一切都在慢慢的进行中,谢谢你的指示,我都开始贪心要前辈多点指引了。虽然是一个web前端自学者,但是兴趣浓烈,做梦都会做到(汗 ,常常搞得早上很早就醒了。但是对整个前端的工作流程不是很了解,然后工具,测试,这些也还只是听过,没有了解。我喜欢做自己的东西,同时希望自己在各个方面都能学的踏实,能胜任工作。但不希望真的才在这个阶段就去去赶一些工程,变成纯码字的。如果能给我一些这方面建议,就感激不尽了。
    chiang
        17
    chiang  
    OP
       2012-05-29 17:07:45 +08:00
    对了各位,我是一名大三的学生,学习时间是相当充裕的,因为我很早的时候就决定把我自己的时间献给我喜爱的东西了。
    Chris_Ys
        18
    Chris_Ys  
       2012-05-29 17:34:20 +08:00   1
    @chiang 我个人的学习路线:

    - 无视 IE 等兼容性问题,一切走标准路线
    - 找一个开源的非 Ajax(每个链接都会刷新页面)、页面 UI 和交互非常简单的项目,todo 类是最容易找的
    - 看 Javascriptkit.com、MDN 的文档,用 jQuery 往里堆功能
    - 能堆什么功能呢?以 todo 为例,打字的时候验证、改变 todo 的显示状态、插入 todo 时的效果、提交的 ajax、ajax 获取数据、对 todos 的遍历、todos 的全文检索、排序、添加 due date、添加 timer……
    - 能用 jQuery 搞定上面的功能,这时候差不多就会碰到新的问题:性能、代码是否乱七八糟
    - 尝试重构代码,尝试用原生语法和函数去解决性能问题,etc.

    选择 jQuery 的理由是语法简单,初学者不太深究运行机制的话,很快能做出一些东西。

    然后就是分水岭。

    停留在用库的地步,那也就到此为止。

    如果这时候你开始有用原生函数去解决一些题的想法或提出疑问,比如 $(el).attr("id") 和 el.id 的区别在哪,这时候你就是真正踏足这个领域。

    再之后,就是 backbone、templating、requirejs、module 等。
    chiang
        19
    chiang  
    OP
       2012-05-29 17:46:26 +08:00
    @Chris_Ys 谢谢你。现阶段会把原生的js弄熟悉,然后在开始使用jQuery这些框架。刚刚上面应该改成学的“扎实”。(泪奔中...
    clowwindy
        20
    clowwindy  
       2012-05-29 23:35:30 +08:00
    imcotton
        21
    imcotton  
       2012-05-30 03:50:40 +08:00
    每到这种时候,我就忍不住要写 CoffeeScript
    http://gist.github.com/6bd4781bc7528a65c148
    imcotton
        22
    imcotton  
       2012-05-30 03:52:39 +08:00
    chiang
        23
    chiang  
    OP
       2012-05-30 07:41:03 +08:00
    @clowwindy @imcotton 问题已经解决了,谢谢你们
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3593 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude div class="sep20">
    VERSION: 3.9.8.5 26ms UTC 00:13 PVG 08:13 LAX 16:13 JFK 19:13
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86