2010-02-19 78 views
15

我用一些非常基本的Javascript编写了一个选项卡系统,它在IE 8中像冠军一样运行,但在FireFox 3中, 。该pertitent HTML如下:element.firstChild正在返回'<TextNode ...'而不是FF中的Object

  <div id="tabs"> 
       <ul class="tabs"> 
        <li class="current"><a><span>News</span></a></li> 
        <li><a><span>Videos</span></a></li> 
        <li><a><span>Photos</span></a></li> 
        <li><a><span>Twitter</span></a></li> 
       </ul> 
      </div> 

然后,在页面加载时,我得到投进这个方法:

function processTabs(TabContainer, PageContainer, Index) { 
var tabContainer = document.getElementById(TabContainer); 
var tabs = tabContainer.firstChild; 

var tab = tabs.firstChild; 
var i = 0; 
.... more code } 

代码在这一点无关紧要的休息,因为它永远不会被调用。 tabContainer已正确设置为使用ID选项卡引用div。现在,在我调用tabContainer.firstChild的Internet Explorer中,变量“tabs”引用我的UL,然后调用var tab = tabs.firstChild;引用我的第一个LI。问题是,当我打电话给tabContainer.firstChild Venkman告诉我它正在返回。所以Firefox正在阅读我的换行符,作为div内的实际儿童!我的UL实际上是childNodes集合中的第二个孩子!

有什么办法解决这个问题吗?

谢谢!

回答

24

您应该跳过TextNodes,一个简单的功能,可以帮助您:

function getFirstChild(el){ 
    var firstChild = el.firstChild; 
    while(firstChild != null && firstChild.nodeType == 3){ // skip TextNodes 
    firstChild = firstChild.nextSibling; 
    } 
    return firstChild; 
} 

用法:

var tabContainer = document.getElementById(TabContainer); 
var tabs = getFirstChild(tabContainer); 
+1

做得很好,像魅力一样工作! – dparsons 2010-02-20 01:33:08

+3

在函数'getFirstChild'中,我会检查'firstChild.nodeType!= 1'而不是'firstChild.nodeType == 3',以便跳过其他节点类型,如注释。 – Cito 2012-12-03 22:15:08

+0

这个答案应该更新为建议的@Cito更改,我刚刚遇到了一个复制了此确切代码的开发人员,并且确实在正搜索的第一个元素节点之前存在HTML注释。并因此失败。 – scunliffe 2017-04-05 19:19:31

11

您可以使用node.firstElementChild忽略前导文本,或者使用类似jQuery的库来处理此问题。

+2

node.firstElementChild仅支持在FF 3.5,所以我还是风与在旧版本中的问题。在我的情况下,jQuery不是一个选项。上面的CMS的帖子解决了这个问题。 – dparsons 2010-02-22 12:31:51

0

我会建议任何人试图在JavaScript中的DOM工作使用像图书馆jquery。它会让你的生活更轻松。

然后,您可以重写JS功能休耕:

function processTabs(TabContainer, PageContainer, Index) { 
    var tabContainer = document.getElementById(TabContainer); 

    // jquery used to find all the <li> elements 
    var tabs = $(tabContainer).filter('li'); 

    // use the jquery get(index) function to retrieve the first tab 
    var tab = tabs.get(0); 
    var i = 0; 
    .... more code 
} 
+3

虽然框架很好,但它们并不是我目前使用的luxuary。感谢解决方案! – dparsons 2010-02-20 01:33:38

+1

虽然我喜欢jQuery,但很难将其纳入书签! – scraimer 2012-11-27 06:01:39

2

随着也对效率产生的眼睛,这个函数返回EL

function firstChildElement(el) 
{ 
    el = el.firstChild; 
    while (el && el.nodeType !== 1) 
     el = el.nextSibling; 
    return el; 
} 
+0

@yckart:谢谢你的解决,这是完全错误的。 – 2013-06-05 17:50:03

5

使用element.querySelector("*")拿到第一的则firstChild元素节点子元素。

演示:

var container = document.getElementById("container") 
 

 
console.log(container.querySelector("*")) // <div>This is a test</div> 
 
console.log(container.firstChild) // #text 
 
console.log(container.childNodes[0]) // #text
<div id="container"> 
 
    <div>This is a test</div> 
 
</div>

+0

没有对此投票,任何理由,这不是解决方案? – Joel 2016-03-30 16:43:59

+3

@Joel 6年后我添加了答案,也许多数民众赞成在为什么:) – CoderPi 2016-03-31 18:46:14

0

您可以尝试

document.getElementById(TabContainer).firstElementChild; 

,而不是firstChild

相关问题