写 JS 为去除特定 class 下的第一个 p 元素,浏览器没报错,但无效果 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
islujw
V2EX    Javascript

写 JS 为去除特定 class 下的第一个 p 元素,浏览器没报错,但无效果

  •  
  •   islujw 2017 年 8 月 9 日 4230 次点击
    这是一个创建于 3100 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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> 

    问题在哪儿?要怎么解决这个问题呢?

    29 条回复    2017-08-28 11:53:30 +08:00
    ferrum
        1
    ferrum  
       2017 年 8 月 9 日
    你的函数执行了吗?

    另外 getElementById 返回单个 Node 节点,不是数组。没有具体的 HTML,其实也不好看出真正的问题……
    piku
        2
    piku  
       2017 年 8 月 9 日 via Android
    你的 for 里定义了一个 function,但是这个 function 在什么时候执行呢?
    leeg810312
        3
    leeg810312  
       2017 年 8 月 9 日 via Android
    function 不是闭包,根本没有执行
    orcusfox
        4
    orcusfox  
       2017 年 8 月 9 日
    (function(i){}) (i)
    Sanko
        5
    Sanko  
       2017 年 8 月 9 日 via Android
    没执行吧
    qiayue
        6
    qiayue  
    PRO
       2017 年 8 月 9 日
    一个函数定义了其次
    blackywkl
        7
    blackywkl  
       2017 年 8 月 9 日
    getElementById 返回的是 Dom 对象吧,为什么 x[i] ?
    chinvo
        8
    chinvo  
       2017 年 8 月 9 日
    函数没执行
    islujw
        9
    islujw  
    OP
       2017 年 8 月 10 日
    @blackywkl 赋给 y,document.getElementById("clean1") 用后面的方法。
    Lax
        10
    Lax  
       2017 年 8 月 10 日
    一个 function 声明了 6 遍 ;->
    msg7086
        11
    msg7086  
       2017 年 8 月 10 日
    你定义了一个函数六次,并且一次都不去执行……?
    autoxbc
        12
    autoxbc  
       2017 年 8 月 10 日   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' 标记,也可以这么写
    [].lice.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 给人一种上手就能写的感觉,不过如果已经写了几千行代码,最好找本书系统看一下,完全自己摸索会很快达到瓶颈。
    b0x
        13
    b0x  
       2017 年 8 月 10 日
    楼主已经从入门到放弃了
    mingl0280
        14
    mingl0280  
       2017 年 8 月 10 日   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>
    fox0001
        15
    fox0001  
       2017 年 8 月 10 日 via Android
    都说得很清楚了,我就不 BB 了
    ZhLTE
        16
    ZhLTE  
       2017 年 8 月 10 日
    楼主加油-。- 该好好学习了
    Anshi
        17
    Anshi  
       2017 年 8 月 10 日
    学会 debug 断点调试。
    ahonn
        18
    ahonn  
       2017 年 8 月 10 日
    12 楼已经讲得很清楚了。建议你还是先去看书吧..
    /table>
    SourceMan
        19
    SourceMan  
       2017 年 8 月 10 日
    你定义了 6 次 cleanTag function 缺没有执行它
    uvw
        20
    uvw  
       2017 年 8 月 10 日
    这应该是个找错及代码优化的问题
    stillsilly
        21
    stillsilly  
       2017 年 8 月 10 日
    ……
    autoxbc
        22
    autoxbc  
       2017 年 8 月 10 日   1
    很多人说楼主定义了 6 次 cleanTag 函数,我的回答也说这样有性能问题
    刚测试了一下,这个说法需要修正

    循环或者任何语句中的函数声明,并不像函数表达式一样被实际执行,即函数声明不参与流程控制。
    函数表达式作为语句,参与流程控制,有性能开销;函数声明完全没有,哪怕其在一个循环中,使其形式上类似重复多次。或者在一个根本不会执行的流程分支中。

    看这个代码

    console.log( fun.toString() )
    if(0)
    {
    function fun(){return 1}
    }

    // function fun(){return 1}

    函数声明的实际流程是,在代码预解析时(词法分析,语法分析,AST 生成),由引擎将函数声明抽出,放入对应的作用域;在程序执行时,声明语句会被完全略过。

    进一步猜测,只要作用域关系正确,函数声明可以写在代码的任何位置,而不产生副作用。
    daisyxdx
        23
    daisyxdx  
       2017 年 8 月 10 日
    好瞎的代码。。。
    winglight2016
        24
    winglight2016  
       2017 年 8 月 10 日
    你的标签只有定义 class,寻找的时候又是 byId,这能找到正确的 tag 吗?
    islujw
        25
    islujw  
    OP
       2017 年 8 月 10 日
    第一次接触 js,谢谢大家的提醒。确实是一个比较低级的错误。
    islujw
        26
    islujw  
    OP
       2017 年 8 月 10 日
    @winglight2016 我已经写了:在「正文」的 p 元素标签内加了 id="cleanX"。
    islujw
        27
    islujw  
    OP
       2017 年 8 月 10 日
    @autoxbc 谢谢,非常详细。函数位置的问题是个疏忽,放在循环外面,逻辑上更好。主要是内部的方法,感谢指点。
    mingyun
        28
    mingyun  
       2017 年 8 月 12 日
    12 楼厉害了
    flowfire
        29
    flowfire  
       2017 年 8 月 28 日
    removeChild 使用方法
    dom.parentNode.removeChild(dom)
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4111 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 05:40 PVG 13:40 LAX 21:40 JFK 00:40
    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