我正在写一些学术性的东西,我有命名空间的html元素,如:
<ns:LinkList id="sitesuteis" cssClass="classone">
<ns:LinkItem id="LI1" href="http://www.ibt.pt/" target="_blank">IBT</ns:LinkItem>
<ns:LinkItem id="LI2" href="http://http://html5demos.com/t/" target="_blank">HTML5 Demos</ns:LinkItem>
<ns:LinkItem id="LI3" href="http://diveintohtml5.ep.io/" target="_blank">Dive into HTML5</ns:LinkItem>
<ns:LinkItem id="LI4" href="http://html5boilerplate.com/" target="_blank">HTML5 Boilerplate</ns:LinkItem>
</ns:LinkList>
现在,在javascript中我正在尝试:
var elements = document.getElementsByTagName('ns:LinkItem');
element = elements[0];
console.log(element.getAttribute('id'));
//I get a correct value in all browsers
尝试在我的元素[0]中获取所有ChildNodes。它适用于所有浏览器,但-IE lt 9 -
除外我试过了:
var children = element.getElementsByTagName('ns:LinkItem');
console.log(children.length);
和
var children = Array();
for (i=0; i<element.childNodes.length; i++){
alert(element.childNodes[i].nodeName);
if (element.childNodes[i].nodeName=="NS:LINKITEM"){
children.push(element.childNodes[i]);
}
}
console.log(children.length);
在两个console.logs中,除IE8或更低版本外,我在每个浏览器中得到正确的长度(4),我得到0。
根据@Shadow向导在IE8及以下版本中,元素的canHaveChildren属性为false,这意味着死胡同 - 浏览器根本不支持为此标记设置子节点,这与例如,有子节点。我试过了,这是真的。如果我尝试:
element.parentNode
在IE 8或更低版本中,我得到包含我的标记的div,而在其他浏览器中,我得到了我的父母
我真的需要一个黑客,我似乎找不到一个。
答案 0 :(得分:1)
在IE8及更低版本中,元素的canHaveChildren
属性为false
,这意味着死胡同 - 浏览器根本不支持为此标记设置子节点,与{{1}相同例如,不能有子节点。
虽然在IE9中已经修复了这个问题。
答案 1 :(得分:1)
在非IE浏览器中,我建议使用 getElementsByTagNameNS 来获取特定命名空间中的元素
在IE中,您可以使用 XPath 代替
编辑:JQuery还提供了一种使用命名空间的方法;它似乎被涵盖here。
答案 2 :(得分:1)
我相信以下功能应该可行 - 我在以前的项目中使用过它,我相信它在IE6,IE7和IE8中有效。我没有一个好的方法在IE9中测试,但我猜它应该正常工作,如IE9 supports getElementsByTagNameNS
。它非常简单,依赖于核心浏览器方法。
/**
* Cross-browser implementation for namespaced tags
* @param {DOM Node} n Parent node
* @param {String} tag Tag name you're trying to retrieve
* @param {String} [ns] Namespace prefix
*/
getElementsByTagName = function(n, tag, ns) {
// map the namespace prefix to the full namespace URIs
var nsMap = {
'svg': 'http://www.w3.org/2000/svg'
// etc - whatever's relevant for your page
};
if (!ns) {
// no namespace - use the standard method
return n.getElementsByTagName(tag);
}
if (n.getElementsByTagNameNS && nsMap[ns]) {
// function and namespace both exist
return n.getElementsByTagNameNS(nsMap[ns], tag);
}
// no function, get with the colon tag name
return n.getElementsByTagName(ns + ':' + tag);
};
// get a list of svg:circle elements
getElementsByTagName(document, 'circle', 'svg');
这里唯一的痛点是需要定义从名称空间前缀到完整名称空间URI的映射。如果你想让它成为一个更加可移植的函数,你可以将nsMap
作为函数参数,而不是函数体中定义的函数;或者您可以在全局上下文中引用命名空间映射对象。
这是一个完全模块化的版本,版本稍微紧张getElementsByTagName
:
var namespaces = (function() {
var nsMap = {};
/**
* Add a new XML namespace with prefix
* @param {String} prefix Prefix for new namespace
* @param {String} uri Full URI of new namespace
*/
function addNamespace(prefix, uri) {
nsMap[prefix] = uri;
}
/**
* Cross-browser implementation for namespaced tags
* @param {DOM Node} [n] Parent node
* @param {String} tag Tag name you're trying to retrieve
* @param {String} [ns] Namespace prefix
*/
function getElementsByTagName(n, tag, ns) {
return !ns ?
n.getElementsByTagName(tag) :
(n.getElementsByTagNameNS && nsMap[ns]) ?
n.getElementsByTagNameNS(nsMap[ns], tag) :
n.getElementsByTagName(ns + ':' + tag);
}
return {
addNamespace: addNamespace,
getElementsByTagName: getElementsByTagName
};
}());
// set the svg namespace
namespaces.addNamespace('svg', 'http://www.w3.org/2000/svg');
// get a list of svg:circle elements
namespaces.getElementsByTagName(document, 'circle', 'svg');
答案 3 :(得分:0)
从来没有像headhache那样得到这个问题..所以这只是一个建议或提示。
EDIT1:删除了之前关于原型getElementsByTag的建议,因为它只是在主题之外。
EDIT2:在btwn中,我发现this confirmation用于MSIE名称空间“限制”。
EDIT3:我终于找到了确认Xpath使用的点here:
默认情况下,Internet Explorer的XPath引擎无法使用 名称空间(与DOM Level 3 XPath实现相同)。 必须提前指定命名空间信息作为属性 XML DOM文档对象本身。请考虑以下XML代码:
专业JavaScript
为了在本文档中使用XPath查询,您首先需要 定义wrox和默认名称空间的名称空间信息。您 可以通过setProperty()方法执行此操作,传入 “SelectionNamespaces”和空格分隔的命名空间字符串 声明。例如:
xmldoc.setProperty( “SelectionNamespaces”, “xmlns:wrox ='http://www.wrox.com/'xmlns ='http://www.amazon.com/'”); var book = xmldoc.documentElement.selectSingleNode( “Wrox的:书”);
请注意,名称空间声明的格式与它们的格式相同 出现在XML中。不幸的是,没有自动提取方法 文档中的命名空间信息,用于XPath 查询。结论
Internet Explorer确实有XPath支持,但它有几个 注意事项。首先,XPath查询仅适用于XML文档,而不是 在HTML文档上,因此无法在文档上使用以帮助查找 页面上的元素。其次,XPath实现非常基础 并且只允许基本的返回类型(节点和NodeSet对象)。仍然, 如果你正在处理XML数据,XPath仍然是一个快速和方便的 找不到特定元素而无需手动遍历DOM的方法。
答案 4 :(得分:0)
这样的黑客,但可能足够强大,你需要的东西:
function getElementsByTagName(parent, tagName)
{
if(typeof parent.canHaveChildren === 'undefined' || parent.canHaveChildren)
{
return parent.getElementsByTagName(tagName);
}
var elements = [];
var cursor = parent;
while(cursor.nextSibling && cursor.nextSibling.tagName !== ('/' + parent.tagName))
{
if(cursor.tagName === tagName.toUpperCase())
{
elements.push(cursor);
}
cursor = cursor.nextSibling;
}
return elements;
}
function getText(parent)
{
return parent.innerHTML || parent.nextSibling.data;
}
E.g:
var element = document.getElementById('sitesuteis');
var children = getElementsByTagName(element, 'ns:LinkItem');
console.log(children.length);
for(var i = 0; i < children.length; i++)
{
console.log([getText(children[i]), children[i].getAttribute('href')]);
}