Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 Selectors [*|type="toc"]

I am working with EPUB.JS, which uses the following code to get some information from an ePub file:

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

This line of code fails in IE10, as the querySelector returns null. I've never seen an attribute selector in the format [*|attr="val"] before, but what I think they were trying to say was, "Select all nav elements with any attribute or an attribute named 'type' with value 'toc'."

I couldn't find any information on this star-pipe syntax, but I presume it is some sort of logical OR command that works in Webkit/Mozilla but not in IE.

Altering that line to read:

var navEl = navHtml.querySelector('nav')

works, but I still wanted to fully understand why they may have chose that other syntax when I feel like it meaningless, just in case it has an actual purpose that could lead to errors elsewhere.

Is there any explanation for this *|... and is it even necessary?

like image 205
Jeff Jenkins Avatar asked Dec 06 '13 16:12

Jeff Jenkins


People also ask

What are the css3 selectors?

A CSS selector is the first part of a CSS Rule. It is a pattern of elements and other terms that tell the browser which HTML elements should be selected to have the CSS property values inside the rule applied to them.


2 Answers

The namespace| syntax applies to type selectors as well as attribute selectors (and possibly others). This essentially says "match nav with type=toc where type is in any namespace (including no namespace)." It would match:

<nav foo:type="toc">

If the selector were just [type=toc], the above element would not be selected because it is in a namespace.

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

The fact that this doesn't work in IE10 is probably an error on IE's side. To be honest I've never even seen namespaces used in any HTML I've seen, although I'm sure it happens a lot. You can probably get away with just leaving off the *|, but it's important that you understand why it's there before you make that decision.

like image 154
Explosion Pills Avatar answered Oct 14 '22 12:10

Explosion Pills


So, I just wanted to post my workaround, in case anyone comes across something similar in the future.

I'm leaving the original querySelector in place:

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

However, if that results in a null value for navEl, I wrote a little loop to do a similar "any-namespace attribute selector" using more traditional logic that works in IE10 and presumably lower versions:

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;
         }
      }
   }
}

It's not super-pretty or clean, but it gets the point across. It would be fairly easy to convert this to a function so you can search any attribute/value, instead of hard-coding type and toc, but for my current purposes, this will suffice.

like image 20
Jeff Jenkins Avatar answered Oct 14 '22 11:10

Jeff Jenkins