javascript - getElementsByTagName().length 在 Firefox/Internet Explorer 中不起作用

标签 javascript html xml internet-explorer firefox

这与另一个问题 ( Chart is rendered in Chrome, but not in FF and IE ) 有关,但是,我认为这本身就是一个有效的问题,希望这有助于更深入地描述问题。

当我偶然用 Firefox 打开我的网页并注意到我的 amChart 图表不再工作时,我意识到了这种行为,我追溯到代码中的这些行:

xmlData = xmlHttp.responseXML;
var x=xmlData.getElementsByTagName("row");
xmlRowCount = x.length;

显然,Firefox 和 Internet Explorer 引擎执行“xmlData.getElementsByTagName”的方式与 Google Chrome(它运行良好)不同,这反过来会导致错误的返回值,从而彻底破坏所有后续代码。

问题是为什么 FF 和 IE 这样做,以及如何防止他们这样做并像 Chrome 一样返回正确的结果。

我很感激任何建议,希望你们中的一些人能帮助我,并且可能知道这种奇怪行为的原因。

最好的问候,

达扎

编辑:为了完成浏览器测试,我还下载并测试了Opera。它在那里工作得很好,这让整个事情变得更加陌生。 IE/FF 与 Chrome/Opera 之间有什么区别?

EDIT2: 这个发现看起来很有希望...我尝试添加第二条 console.log 消息,它打印出相同的内容,但使用 XML 标记的“非 namespace 名称”,在此case z:row 而不是row(row是命名空间名称,z:row是xml文件中的硬标签)。

我发现,Firefox/IE 在非命名空间名称上返回 417 和这个新的 console.log。 Chrome/Opera 返回 0。反之亦然,因此 Chrome 使用命名空间返回 417,而 FF/IE 返回 0。

这让我相信,FF/IE 有一个损坏的 XML DOM,无法利用/使用/检测/... XML 文件中的命名空间。

我想在这种情况下唯一的解决方法是使用不带 namespace 的 XML,以便它适用于所有浏览器?

这是 XML 文件的一个简短示例(取自 Sharepoint API):

 <xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'
 xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'
 xmlns:rs='urn:schemas-microsoft-com:rowset'
 xmlns:z='#RowsetSchema'>
 <s:Schema id='RowsetSchema'>
 <s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'>
  <s:AttributeType name='blub' rs:name='blah' rs:number='1'>
     <s:datatype dt:type='string' dt:maxLength='512' />
  </s:AttributeType>
 </s:ElementType>
 </s:Schema>
 <rs:data>
 <z:row blub="blahblah" />
 </rs:data>  
 </xml>

PS:以下是一些可能与问题相关的代码片段:

HTML header 底部的 JS 部分(这是发生错误的地方):

var xmlRowCount;

var arrArt = new Array();
var arrPriority = new Array();
var arrTermin = new Array();
var arrResult = new Array();

var arrCalcPrio = new Array();
var avgCalcPrio = new Array();

var terminCounter = 0;
var avgCounter = 0;

 // button_bereichand button_unterbereich are the values from two dropdown boxes. --> Shouldn't have relevance for the problem at hand. The xmlFile parameter is an well formed and validated XML file within the same domain.

function loadXML(xmlFile, button_bereich, button_unterbereich)
{

    var xmlHttp = null;
    var xmlData;
    var sum = 0;
    var bereich = button_bereich;
    var unterbereich = button_unterbereich;
    var spUnterbereich = "";

    console.log("Bereich: " + bereich);
    console.log("Unterbereich: " + unterbereich);

    arrArt.length = 0;
    arrPriority.length = 0;
    arrCalcPrio.length = 0;

    if (typeof XMLHttpRequest != 'undefined')
    {
        xmlHttp = new XMLHttpRequest();
    }

    if (!xmlHttp)
    {
        try
        {
            xmlHttp = new ActiveXObject("Msxm12.XMLHTTP");

        } 
        catch(e)
        {
            try
            {
                xmlHttp = new ActiveXObject("Mircosoft.XMLHTTP")

            } 
            catch(e)
            {
                xmlHttp = null;
            }
        }
    }

    if (xmlHttp)
    {
        var url = xmlFile;
        xmlHttp.open("GET", url, true);
        xmlHttp.onreadystatechange = function() 
        {
            if (xmlHttp.readyState == 4)
            {
                var txt="";
                xmlData = xmlHttp.responseXML;
                var x=xmlData.getElementsByTagName("row");

                xmlRowCount = x.length;

                // Chrome: 417 | Firefox: 0 | Internet Explorer: 0
                console.log("Rowcount: " + xmlRowCount);

                for (i=0;i<xmlRowCount;i++)
                {
                    // do something with each row
                }

                for (j=0;j<xmlRowCount-1;)
                {   
                    // do something
                }

            }   
            }
        }
        xmlHttp.send();
    }

    return xmlData;
}


// bereichElement and bereichText are the values from two dropdown boxes. --> Shouldn't have relevance for the problem at hand
function getGraph()
{
    chartData.length = 0;
    validateData();

    var bereichElement = document.getElementById("bereich");
    var bereichText = bereichElement.options[bereichElement.selectedIndex].text;
    var unterbereichElement = document.getElementById("unterbereich");
    var unterbereichText = unterbereichElement.options[unterbereichElement.selectedIndex].text;

    var xmlDoc=loadXML("sp_xml.xml", bereichText, unterbereichText);
}

HTML Body 中的 JS(Body 有 body onload="getGraph();"> 参数):

// Actual chart creation (amCharts lib)
 var chart;
        var chartData = [];
        var chartCursor;

        AmCharts.ready(function() {

            // SERIAL CHART
            chart = new AmCharts.AmSerialChart();
            chart.pathToImages = "amcharts/images/";
            chart.dataProvider = chartData;
            chart.categoryField = "date";
            chart.dataDateFormat = "YYYY-MM-DD";
            chart.baseHref = true;

            // listen for "dataUpdated" event (fired when chart is rendered) and call zoomChart method when it happens
            chart.addListener("dataUpdated", zoomChart);

            // AXES
            // category
            var categoryAxis = chart.categoryAxis;
            categoryAxis.parseDates = true; 
            categoryAxis.minPeriod = "DD"; 
            categoryAxis.dashLength = 1;
            categoryAxis.gridAlpha = 0.15;
            categoryAxis.minorGridEnabled = true;
            categoryAxis.axisColor = "#DADADA";

            // value
            var valueAxis = new AmCharts.ValueAxis();
            valueAxis.axisAlpha = 0.2;
            valueAxis.dashLength = 1;
            chart.addValueAxis(valueAxis);

            // GRAPH
            var graph = new AmCharts.AmGraph();
            graph.title = "red line";
            graph.valueField = "visits";
            graph.bullet = "round";
            graph.bulletBorderColor = "#FFFFFF";
            graph.bulletBorderThickness = 2;
            graph.bulletBorderAlpha = 1;
            graph.lineThickness = 2;
            graph.lineColor = "#0db503";
            graph.negativeLineColor = "#b5030d";
            graph.balloonText = "[[category]]<br><b><span style='font-size:14px;'>value: [[value]]</span></b>";
            graph.hideBulletsCount = 50; 
            chart.addGraph(graph);

            // CURSOR
            chartCursor = new AmCharts.ChartCursor();
            chartCursor.cursorPosition = "mouse";
            chart.addChartCursor(chartCursor);

            // SCROLLBAR
            var chartScrollbar = new AmCharts.ChartScrollbar();
            chartScrollbar.graph = graph;
            chartScrollbar.scrollbarHeight = 40;
            chartScrollbar.color = "#FFFFFF";
            chartScrollbar.autoGridCount = true;
            chart.addChartScrollbar(chartScrollbar);

            // WRITE
            chart.write("charts_container");

        });




         // this method is called when chart is first inited as we listen for "dataUpdated" event
        function zoomChart() {
            // different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
            chart.zoomToIndexes(chartData.length - 40, chartData.length - 1);
        }

         // changes cursor mode from pan to select
        function setPanSelect() {
            if (document.getElementById("rb1").checked) {
                chartCursor.pan = false;
                chartCursor.zoomable = true;

            } else {
                chartCursor.pan = true;
            }
            chart.validateNow();
        }

        function validateData()
        {
            chart.validateData();
            console.log("Data validated");

        }

最佳答案

您的问题是在 http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-A6C9094 中指定的 getElementsByTagName在“tagname”而非本地名称上指定匹配,并且标签名称包含前缀(请参阅 http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-104682815,其中明确说明 tagName 是限定名称)。

这就是 Firefox 和 IE 实现的行为。

据我所知,WebKit 从未正确实现该规范,而是仅匹配 localName。

您可以使用 getElementsByTagNameNS 来解决这个问题,它允许您在所有现代浏览器中仅在本地名称上显式匹配。您可以传入实际的命名空间,如果您不关心命名空间部分,也可以只传入 "*"

关于javascript - getElementsByTagName().length 在 Firefox/Internet Explorer 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23493557/

相关文章:

jquery - 插入后如何让 jquery 将行为附加到元素

javascript - 在 Firefox 扩展中托管 ContentWindow 或 HTMLDocument 的 XULDocument?

javascript - $.ajax() 调用,仅在更新时

javascript - Adobe Edge 运行时中的时间线事件错误停止 JavaScript 执行

html - 将选择标签的背景设置为与父 div 的背景相同

.net - 从现有的 XDocument 创建新的 XDocument

javascript - 如何在 jquery 裁剪器中设置裁剪框

javascript - SummerNote ContentEditable 属性 Make False

java - 去除 xml 标签开头和结尾之间的空格

sql-server - XML 到 SQL 表查询