【问题标题】:Why does jQuery fail to hide certain HTML?为什么 jQuery 无法隐藏某些 HTML?
【发布时间】:2010-02-19 20:15:56
【问题描述】:

我一直在努力解决这个问题。采用以下 HTML 正文:

<body>
<div id="project">
  <h1>Hi</h1>
  <h2>Hello</h2>
</div>
</body>

还有下面的 jQuery 代码:

$(function(){
  var h = $('#project').html();
  $('#project').remove();
  $(h).hide().appendTo('body');
  alert("Created HTML, hide, and appended!");
});

$(h).hide() 部分导致 jQuery 在 Safari 4 和 Firefox 3.5 中抛出异常。

Safari: TypeError: Result of expression 'this[a].style' [undefined] is not an object.
Firefox: uncaught exception: [Exception... "Could not convert JavaScript argument arg 0" nsresult: ...]

当我将 HTML 更改为仅包含两个标题之一时(如果您从 HTML 中删除 &lt;h1&gt;&lt;h2&gt;,脚本会成功运行。这是为什么呢?

要亲自尝试,请参阅http://jsbin.com/avisi/edit

编辑:我实际上并没有尝试从 DOM 中删除元素并通过复制 HTML 重新插入它。这只是我在更复杂的代码中遇到的错误的测试用例,我试图了解为什么会发生此错误。我同意,如果我想完成这里显示的内容,我会使用类似$('#project').remove().children().appendTo('body')

【问题讨论】:

    标签: javascript jquery html


    【解决方案1】:

    我无法在 Firefox 中复制您的错误。但是,您可能想尝试使用以下方法对其进行清理:

    $('#project').remove().children().appendTo('body').hide();
    

    崩溃了,这就是发生的事情

    // Get the `project` container
    $('#project')
        // Remove it from the page
        .remove()
        // Get its children (the h1, h2, etc)
        .children()
        // Append those nodes to the body
        .appendTo('body')
        // Hide those nodes
        .hide();
    

    其他人提出.hide() 正在引起问题,因为它所应用的节点不是主文档的一部分;然而,事实并非如此。只要您维护对任何节点的引用,就可以影响其样式属性(通过hideshow 等)。

    您可能要检查的一件事是确保$('#project') 实际上正在返回(如果有的话)预期节点。否则可能会出现问题。


    所以我在 Safari 中四处寻找,发现了您的问题。这是来自开发者控制台的转储。

    > var h = $('#project').html();
    undefined
    > var t = $(h);
    undefined
    

    到目前为止,一切都很好。 undefined 这里只是意味着该语句(var 语句)没有返回值(它没有)

    > t.hide()
    ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js:131TypeError: Result of expression 'this[a].style' [undefined] is not an object.
    

    这是您描述的错误。检查 jQuery 对象中的每个项目将显示以下错误

    > t[0]
    <h1 style=​"display:​ none;​ ">​Hi​</h1>
    

    很好……

    > t[1]
    (whitespace)
    

    该死。真的吗?这就是问题所在。空白节点没有style 属性,这是导致问题的原因。

    > t[2]
    <h2>​Hello​</h2>
    

    这就是为什么将一个节点的 HTML 复制到另一个节点只是为了移动这些节点是一种不好的技术。我建议你使用我上面提供的 sn-p。

    【讨论】:

    • 我同意这是删除和重新插入相关节点的一种更简洁的方法。我试图理解的是为什么(至少在我的 Firefox 3.5 和 Safari 4 副本中),上面的代码会导致错误。
    • 贾斯汀,感谢您对此进行调查。我确信我可以用它来解决我最初的问题,即试图隐藏和插入从服务器接收到的 HTML 片段(这就是为什么 .remove() ... .append() 不是一个选项 - 什么都没有删除)。
    【解决方案2】:

    在 $(h) 中选择了一个文本节点。不过,我们可以使用 filter 函数将其过滤掉。

    这应该可以(虽然我只在 FF 中测试过):

    $(function(){
      var h = $('#project').html();  
      $('#project').remove();
      $(h).filter("*").hide().appendTo('body');
    
     alert("Created HTML, hide, and appended!");
    });
    

    IMO 非常奇怪的行为。

    【讨论】:

    • 这是不幸但预期的行为。如果从 HTML 字符串创建 DOM 节点,则节点之间的空白将转换为文本节点。这通常会导致问题,这就是为什么有时最好避免使用该技术的原因,尤其是出于 OP 的目的。
    【解决方案3】:

    您之前从 DOM 中删除了内容,因此没有什么可隐藏的。如果你愿意

    $(h).appendTo('body').hide();
    

    它应该可以工作

    【讨论】:

    • 有些东西要隐藏。仅仅因为节点已从文档中删除并不意味着它不存在并且不能对其执行样式操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2021-11-26
    • 1970-01-01
    • 2022-01-20
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多