7

我正在使用 EPUB.JS,它使用以下代码从 ePub 文件中获取一些信息:

var navEl = navHtml.querySelector('nav[*|type="toc"]')

这行代码在 IE10 中失败,因为 querySelector 返回 null。我以前从未见过格式中的属性选择器[*|attr="val"],但我认为他们想说的是,“选择所有具有任何属性或名为 'type' 且值为 'toc' 的属性的导航元素。”

我找不到有关此星形管道语法的任何信息,但我认为它是某种逻辑 OR 命令,适用于 Webkit/Mozilla 但不适用于 IE。

将该行更改为:

var navEl = navHtml.querySelector('nav')

有效,但我仍然想完全理解为什么当我觉得它没有意义时他们可能会选择其他语法,以防万一它有一个可能导致其他地方错误的实际目的。

对此有什么解释*|...吗?甚至有必要吗?

4

2 回答 2

6

namespace|语法适用于类型选择器以及属性选择器(可能还有其他)。这实质上是说“与nav任何命名空间(包括无命名空间)中的位置匹配” type=toctype它会匹配:

<nav foo:type="toc">

如果选择器只是[type=toc],则不会选择上述元素,因为它位于命名空间中。

http://www.w3.org/TR/css3-selectors/#attrnmsp

这在 IE10 中不起作用的事实可能是 IE 方面的错误。老实说,我什至从未见过在我见过的任何 HTML 中使用命名空间,尽管我确信这种情况经常发生。您可能可以不使用*|.

于 2013-12-06T16:11:32.673 回答
1

所以,我只是想发布我的解决方法,以防将来有人遇到类似的事情。

我将原始 querySelector 留在原处:

var navEl = navHtml.querySelector('nav[*|type="toc"]')

但是,如果这导致 navEl 的值为空,我编写了一个小循环来使用更传统的逻辑来执行类似的“任何名称空间属性选择器”,该逻辑适用于 IE10 和可能的较低版本:

if( !navEl )
{
   var navs = navHtml.getElementsByTagName( 'nav' );
   for( var i = 0; i < navs.length; i++ )
   {
      for( var j = 0; j < navs[i].attributes.length; j++ )
      {
         if(
            navs[i].attributes[j].nodeName.match( 'type$' ) == 'type' &&
            navs[i].attributes[j].value == 'toc'
         ) {
            navEl = navs[i];
            break;
         }
      }
   }
}

它不是超级漂亮或干净,但它明白了这一点。将其转换为函数相当容易,因此您可以搜索任何属性/值,而不是硬编码typeand toc,但就我目前的目的而言,这就足够了。

于 2013-12-06T17:47:41.573 回答