有个javascript的问题问问大家

2012-05-29 16:03:22 +08:00
 chiang
想写一个js功能通过点击不同的单词改变网页背景颜色,无奈无论点击哪个单词网页的背景都是红色。
HTML片段和JS文件如下:




效果图



希望会的人解释一下原因,因为我实在想不出这里面哪里出错了,谢谢了。
3735 次点击
所在节点    问与答
23 条回复
sogood
2012-05-29 16:07:04 +08:00
把 color 的赋值 移到 onclick 里面去。
chiang
2012-05-29 16:12:26 +08:00

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

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

我以前遇到这种问题都是吧for里面的代码放进一个匿名函数里执行,这样每次循环才会真正申明一个新的变量出来。
chiang
2012-05-29 16:25:49 +08:00
恩,谢谢各位。由于自己的js,也就刚刚吧 javascrip DOM编程艺术看完,就小小写一个,结果又是涉及到了一个书籍没有涉及的地方,下面一本书打算是 js权威指南,完全自学状态,所以有时候就会凭空想一些功能,然后自己来写。可是问题真是不少呢。
maikcn
2012-05-29 16:26:12 +08:00
参数的作用域问题,将color转变成this就可以了,触发的对象可以直接this获取得到
for(var i=0; i< links.length; i++) {
links[i].onclick = function() {
document.body.style.backgroundColor = this.getAttribute("title");
}
}
Chris_Ys
2012-05-29 16:26:31 +08:00
@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
2012-05-29 16:37:10 +08:00
@013231 @mailkcn 的貌似在代码上来是挺整洁的。用现在学到的知识也能很好的理解。
@zythum @bearice @Chtid_Yd 让我看到了更多
ThanX ,还是第一次问这个问题,自己都拖自己好多时间没解决。
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
2012-05-29 17:05:33 +08:00
@Chris_Ys 一切都在慢慢的进行中,谢谢你的指示,我都开始贪心要前辈多点指引了。虽然是一个web前端自学者,但是兴趣浓烈,做梦都会做到(汗 ,常常搞得早上很早就醒了。但是对整个前端的工作流程不是很了解,然后工具,测试,这些也还只是听过,没有了解。我喜欢做自己的东西,同时希望自己在各个方面都能学的踏实,能胜任工作。但不希望真的才在这个阶段就去去赶一些工程,变成纯码字的。如果能给我一些这方面建议,就感激不尽了。
chiang
2012-05-29 17:07:45 +08:00
对了各位,我是一名大三的学生,学习时间是相当充裕的,因为我很早的时候就决定把我自己的时间献给我喜爱的东西了。
Chris_Ys
2012-05-29 17:34:20 +08:00
@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
2012-05-29 17:46:26 +08:00
@Chris_Ys 谢谢你。现阶段会把原生的js弄熟悉,然后在开始使用jQuery这些框架。刚刚上面应该改成学的“扎实”。(泪奔中...
clowwindy
2012-05-29 23:35:30 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/37745

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX