HTML 是这样的:
<div class="accordion">
<div class="spoiler">
<div class="content">
<p></p>
<p>正文</p>
</div>
</div>
</div>
因为正文外的 div 元素是插件生成的,总是会出现第一个多余的 p 元素,希望在后面加个 js 来去除。
上面的 HTML 段落从 .spoiler 开始的部分共 6 个排比,都在 .accordion 内。我在「正文」的 p 元素标签内加了 id="cleanX",X 是从 1 ~ 6 的数字,按顺序分布在 6 个排比的结构里面。
接着按如下写的 js,浏览器无报错,但没有效果:
<script>
for (var i=1;i<7;i++) {
function cleanTag(i) {
var x = document.getElementById("clean"+i);
var y = x[i];
y.parentNode.removeChild(1);
}
}
</script>
问题在哪儿?要怎么解决这个问题呢?
1
ferrum 2017-08-09 21:43:51 +08:00
你的函数执行了吗?
另外 getElementById 返回单个 Node 节点,不是数组。没有具体的 HTML,其实也不好看出真正的问题…… |
2
piku 2017-08-09 21:46:57 +08:00 via Android
你的 for 里定义了一个 function,但是这个 function 在什么时候执行呢?
|
3
leeg810312 2017-08-09 21:54:12 +08:00 via Android
function 不是闭包,根本没有执行
|
4
napsterwu 2017-08-09 22:01:38 +08:00
(function(i){}) (i)
|
5
Sanko 2017-08-09 22:02:58 +08:00 via Android
没执行吧
|
6
qiayue 2017-08-09 22:08:35 +08:00
一个函数定义了其次
|
7
blackywkl 2017-08-09 23:00:07 +08:00
getElementById 返回的是 Dom 对象吧,为什么 x[i] ?
|
8
chinvo 2017-08-09 23:02:09 +08:00
函数没执行
|
10
Lax 2017-08-10 02:06:44 +08:00
一个 function 声明了 6 遍 ;->
|
11
msg7086 2017-08-10 02:25:17 +08:00
你定义了一个函数六次,并且一次都不去执行……?
|
12
autoxbc 2017-08-10 03:01:39 +08:00 2
我觉得一句话提示可能不够说明问题
1. 不应该在循环内部定义函数,效率很差,要这么写 var cleanTag = function(i) { // doSomething }; for(var i=1 ; i<7 ; i++ ) { cleanTag(i); } 2. 定义的函数并没有实际执行,没有传递参数 3. 如果希望函数获取外部的变量值(i),或者传递参数(实参),或者不定义形参,让函数内部代码在作用域链里查找 传递实参 (function(i){ // doSomething })(i); 从作用域链中查找 var i; (function(){ // doSomething with i })(); 4. 变量 x 存储的是 getElementById 的返回值,这是一个元素节点,就是你需要删除的节点,后面再赋值给 y 没有意义 5. removeChild 的参数是一个节点,不是数字或者索引值 删除 x 这么写 x.parentNode.removeChild(x); 需要达到题目中的目的,一般不用题目的做法,而是这样 [].slice.call( document.querySelectorAll('.content p') ).forEach(function(e){ if( e.textContent.trim() == '' ) e.parentNode.removeChild(e); }); 如果确实已经完成了添加 'clean' 标记,也可以这么写 [].slice.call( document.querySelectorAll('.content p[id^="clean"]') ).forEach(function(e){ e.parentNode.removeChild(e); }); 最后,楼主可能对自己的代码更亲切,按你的风格可以这样改 for(var i=1 ; i<7 ; i++ ) { (function(i){ var x = document.getElementById("clean"+i); if(x) x.parentNode.removeChild(x); })(i); } P.S. 虽然 js 给人一种上手就能写的感觉,不过如果已经写了几千行代码,最好找本书系统看一下,完全自己摸索会很快达到瓶颈。 |
13
b0x 2017-08-10 03:01:48 +08:00
楼主已经从入门到放弃了
|
14
mingl0280 2017-08-10 05:22:14 +08:00 1
强行在 for 里定义一个函数六次却不执行 233333 当然没报错
removeChild 用法也是错的。 而且完全看不出来这个函数干啥的。 正确做法: <script> for (var i=1;i<7;i++) { function cleanTag(i) { var x = document.getElementById("clean"+i); x.parentNode.removeChild(x); }(i); } </script> 或者 <script> for (var i=1;i<7;i++) { var x = document.getElementById("clean"+i); x.parentNode.removeChild(x); } </script> |
15
fox0001 2017-08-10 06:25:26 +08:00 via Android
都说得很清楚了,我就不 BB 了
|
16
ZhLTE 2017-08-10 09:17:56 +08:00
楼主加油-。- 该好好学习了
|
17
Anshi 2017-08-10 09:27:43 +08:00
学会 debug 断点调试。
|
18
ahonn 2017-08-10 09:33:34 +08:00
12 楼已经讲得很清楚了。建议你还是先去看书吧..
|
19
SourceMan 2017-08-10 09:59:01 +08:00
你定义了 6 次 cleanTag function 缺没有执行它
|
20
uvw 2017-08-10 10:02:00 +08:00
这应该是个找错及代码优化的问题
|
21
stillsilly 2017-08-10 10:06:36 +08:00
……
|
22
autoxbc 2017-08-10 10:41:21 +08:00 1
很多人说楼主定义了 6 次 cleanTag 函数,我的回答也说这样有性能问题
刚测试了一下,这个说法需要修正 循环或者任何语句中的函数声明,并不像函数表达式一样被实际执行,即函数声明不参与流程控制。 函数表达式作为语句,参与流程控制,有性能开销;函数声明完全没有,哪怕其在一个循环中,使其形式上类似重复多次。或者在一个根本不会执行的流程分支中。 看这个代码 console.log( fun.toString() ) if(0) { function fun(){return 1} } // function fun(){return 1} 函数声明的实际流程是,在代码预解析时(词法分析,语法分析,AST 生成),由引擎将函数声明抽出,放入对应的作用域;在程序执行时,声明语句会被完全略过。 进一步猜测,只要作用域关系正确,函数声明可以写在代码的任何位置,而不产生副作用。 |
23
daisyxdx 2017-08-10 10:52:48 +08:00
好瞎的代码。。。
|
24
winglight2016 2017-08-10 11:17:40 +08:00
你的标签只有定义 class,寻找的时候又是 byId,这能找到正确的 tag 吗?
|
25
islujw OP 第一次接触 js,谢谢大家的提醒。确实是一个比较低级的错误。
|
26
islujw OP @winglight2016 我已经写了:在「正文」的 p 元素标签内加了 id="cleanX"。
|
28
mingyun 2017-08-12 10:24:25 +08:00
12 楼厉害了
|
29
flowfire 2017-08-28 11:53:30 +08:00
removeChild 使用方法
dom.parentNode.removeChild(dom) |