在IE浏览器中执行OpenFlashChart的reload方法时没法刷新的解决方法

  因为项目需求,须要在网页上利用图表展现相关数据的统计信息,采用了OpenFlashChart技术。OpenFlashChart是一款开源的以Flash和Javascript为技术基础的免费图表,用它能建立一些颇有效果的报表分析图表。最重要的是它是开源和免费的,支持多种语言。首先在官网上下载开发包,里面包含了所需的flash文件、js文件以及多种语言的demo,这些demo写的很是详细,能够进行参考开发。因为项目使用.net来开发,因此我学习了一下开发包中对应的dotnet代码,这个.net项目采用面向对象的方式对图表进行了合理的分析,建立了一些与OpenFlashChart相对应的类,用来描述图表信息,还编写了相应的用户控件,方便开发人员直接使用。php

  好了,废话很少说了,开始说问题了(想了解具体开发技术可参考官网教程和示例代码),因为须要多角度全方位的展现图标,那么就必需要根据不一样的要求动态刷新图表信息,根据官网上的方法,可利用如下代码:chrome

 1 function reload()
 2 {
 3   tmp = findSWF("chart");
 4   
 5   //
 6   // reload the data:
 7   //
 8   x = tmp.reload();
 9   
10   //
11   // to load from a specific URL:
12   // you may need to 'escape' (URL escape, i.e. percent escape) your URL if it has & in it
13   //
14   x = tmp.reload("gallery-data-32.php?beer=1");
15   
16   //
17   // do NOT show the 'loading...' message:
18   //
19   x = tmp.reload("gallery-data-32.php?beer=1", false);
20 }
21 
22 function findSWF(movieName) {
23   if (navigator.appName.indexOf("Microsoft")!= -1) {
24     return window["ie_" + movieName];
25   } else {
26     return document[movieName];
27   }
28 }

经过调用reload方法来实现图标刷新,按照这种方式写完代码后运行,在chrome中果真能够达到预想中的效果,然而,IE给我泼了一盆冷水,报出了错误:没法获取属性“reload”的值: 对象为 null 或未定义,甚至官网上点击“reload”时也会报错(以下图),这下我桑心了,估计很差解决了。json

 

没办法,问题总要处理。通过查看,发现错误的主要缘由在于findSWF方法返回的对象为null,也就是说在IE中经过 window["ie_" + movieName] 没法获得flash实例,这个方法是做者本人写的,目的就是为了兼容IE,由于官网上的描述是:IE中的图表ID跟firefox不一样,所以前面加上了"ie_",不知道为何很差使。而后我就在网上各类搜索,但愿能找到方法,这个问题也确实有不少人遇到,但都没有给出很好的解决方法,无奈之下,我只有进行变通处理,即:在刷新时销毁掉以前的flash对象,从新进行加载,并传入相应的json数据。这种方法也能够实现所需的功能,可是因为我销毁flash对象的手段仅仅是经过删除包含该flash对象的div元素,我总感受这种方法可能没有真正的将flash对象删除,由于我在网上看到有的人经过此方法删除外层div元素后,里面的flash仍然还在执行相应的操做,一旦状况确实如此,那么每刷新一次就会构造出一个新的flash对象,这样的话若是刷新频繁就会形成内存的消耗不断增加,显然,考虑到这个状况,这种实现方法是行不通的。这下我又陷入了麻烦中,若是这个问题解决不了的话可能就会换用其余技术来实现,那我以前话费时间研究OpenFlashChart就算是作了无用功了,再想一想吧,总感受有解决方法。忽然之间,我想到了以前作文件上传时用到了swfupload技术,这也是利用flash对象来实现相关功能的,我打开源码,看看该组件是怎么处理IE的兼容问题的,但愿能从中发现一些端倪,通过一番查看,终于在“SWFUpload.prototype.loadFlash”方法中发现了一段话:浏览器

// Fix IE Flash/Form bug
    if (window[this.movieName] == undefined) {
        window[this.movieName] = this.getMovieElement();
    }

从注释上看这段代码是为了处理IE bug的,而后继续查看this.getMovieElement()方法:app

// Public: get retrieves the DOM reference to the Flash element added by SWFUpload
// The element is cached after the first lookup
SWFUpload.prototype.getMovieElement = function () {
    if (this.movieElement == undefined) {
        this.movieElement = document.getElementById(this.movieName);
    }

    if (this.movieElement === null) {
        throw "Could not find Flash element";
    }
    
    return this.movieElement;
};

原来获取flash对象就是经过最经常使用的getElementById方法,这里的movieName就是flash对象的id值,看到这里,我赶忙将findSWF方法中的代码进行了以下修改:学习

function findSWF(movieName) {
    // Fix IE Flash/Form bug
    if (window[movieName] == undefined) {
         window[movieName] = document.getElementById(movieName);
    }
    return window[movieName];
}

修改后在chrome浏览器、IE浏览器(正常视图和兼容性视图)和360浏览器(极速模式和兼容模式)上运行,果真都达到了预期的效果,至此,问题解决!this

相关文章
相关标签/搜索