200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > echarts3 地图只显示南沙群岛 刷新页面显示正常

echarts3 地图只显示南沙群岛 刷新页面显示正常

时间:2019-11-23 16:45:01

相关推荐

echarts3 地图只显示南沙群岛 刷新页面显示正常

最近在使用echarts3 地图时遇到一个奇怪的问题,进入页面只显示南沙群岛部分,再次刷新页面显示正常,搜索无果后进行了摸索式探索,最终找到了问题的解决方案,现记录于此希望帮到遇到同样问题的朋友。

ECharts 3 中因为地图精度的提高,不再内置地图数据增大代码体积,使用地图时有两种方式:

JavaScript 引入示例<script src="echarts.js"></script><script src="map/js/china.js"></script><script>var chart = echarts.init(document.getElementById('main'));chart.setOption({series: [{type: 'map',map: 'china'}]});</script>

JSON 引入示例$.get('map/json/china.json', function (chinaJson) {echarts.registerMap('china', chinaJson);var chart = echarts.init(document.getElementById('main'));chart.setOption({series: [{type: 'map',map: 'china'}]});});

我采用的是第一种方式,如果只加载echarts.js文件而不加载china.js,也会出现只显示南沙群岛的问题,但是这种情况无论怎么刷新都是只显示南沙群岛。我遇到的问题则是第一次进入该页面显示不正常,再次刷新后显示正常。

下面具体说下问题出现的应用场景:

1.基于ace admin的管理后台

2.在index.html文件中引入echarts.js以及china.js一切正常,如果放在子页面则不正常,具体有两种:如果把echart.js放在index.html,把china.js放在子页面里面就会出现本文所述的现象;把两个js文件都放在子页面html文件里面,则出现echarts没有定义的错误

经过上述分析,相信小伙伴已经知道如何解决这个问题了:把echarts.js以及china.js文件都放在顶层index.html文件里面即可。

下面说说产生这个问题的原因:

图1

上面这张图截自chrome浏览器调试界面,相信大伙对这个界面一定也不陌生,这里只分析两栏:XHR与JS,这是产生本文问题的最终原因。

前端开发人员最先接触的引入js脚本文件的方式就是通过<script src="xxx.js"></script>这种方式引入,这也就是图1中Type列所示的script方式,这是一种阻塞方式,遇到这种script标签后浏览器就会执行“下载该脚本,然后执行该脚本”的流程;这种方式的缺点也很明显,特别是当js文件过多时,就会导致浏览器渲染整个页面的过程加长。

实际应用中有以下几种方式,可以用于解决上述问题:

1.通过标准 DOM 函数创建<script>元素,这也是引入百度统计hm.js脚本文件的方式

var script = document.createElement ("script");script.type = "text/javascript";script.src = "script1.js";document.getElementsByTagName("head")[0].appendChild(script);

新的<script>元素加载 script1.js 源文件。此文件当元素添加到页面之后立刻开始下载。此技术的重点在于:无论在何处启动下载,文件的下载和运行都不会阻塞其他页面处理过程--异步。您甚至可以将这些代码放在<head>部分而不会对其余部分的页面代码造成影响(除了用于下载文件的 HTTP 连接)。

当文件使用动态脚本节点下载时,返回的代码通常立即执行(除了 Firefox 和 Opera,他们将等待此前的所有动态脚本节点执行完毕)。当脚本是“自运行”类型时,这一机制运行正常,但是如果脚本只包含供页面其他脚本调用调用的接口,则会带来问题。这种情况下,您需要跟踪脚本下载完成并是否准备妥善。可以使用动态 <script> 节点发出事件得到相关信息。

Firefox、Opera, Chorme 和 Safari 3+会在<script>节点接收完成之后发出一个 onload 事件。您可以监听这一事件,以得到脚本准备好的通知。

2.使用类似ace_ajax等一些异步加载js脚本框架来加载js文件

3.使用 XMLHttpRequest(XHR)对象,此技术首先创建一个 XHR 对象,然后下载 JavaScript 文件,接着用一个动态 <script> 元素将 JavaScript 代码注入页面。

var xhr = new XMLHttpRequest();xhr.open("get", "script1.js", true);xhr.onreadystatechange = function(){if (xhr.readyState == 4){if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){var script = document.createElement ("script");script.type = "text/javascript";script.text = xhr.responseText;document.body.appendChild(script);}}};xhr.send(null);

此代码向服务器发送一个获取 script1.js 文件的 GET 请求。onreadystatechange 事件处理函数检查 readyState 是不是 4,然后检查 HTTP 状态码是不是有效(2XX 表示有效的回应,304 表示一个缓存响应)。如果收到了一个有效的响应,那么就创建一个新的<script>元素,将它的文本属性设置为从服务器接收到的 responseText 字符串。这样做实际上会创建一个带有内联代码的<script>元素。一旦新<script>元素被添加到文档,代码将被执行,并准备使用。

这种方法的主要优点是,您可以下载不立即执行的 JavaScript 代码。由于代码返回在<script>标签之外(换句话说不受<script>标签约束),它下载后不会自动执行,这使得您可以推迟执行,直到一切都准备好了。另一个优点是,同样的代码在所有现代浏览器中都不会引发异常。

此方法最主要的限制是:JavaScript 文件必须与页面放置在同一个域内,不能从 CDN 下载(CDN 指"内容投递网络(Content Delivery Network)",所以大型网页通常不采用 XHR 脚本注入技术。

图2 图2中这些通过xhr方式加载的js文件就是放置在ace子页面的文件,先看下china.js文件相关内容: if (typeof define === 'function' && define.amd) {

// AMD. Register as an anonymous module.

define(['exports', 'echarts'], factory);

} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {

// CommonJS

factory(exports, require('echarts'));

} else {

// Browser globals

factory({}, root.echarts);

}

由于在引入china.js文件之前引入了echarts.js文件,echarts文件里面定义了define为一个函数,这就会导致浏览器加载完china.js文件并执行时没有进入china.js默认函数--初始化部分,所以导致中国地图没有初始化。

这里涉及到amd---异步模块定义规范,后期会写这方面相关的文章

PS:echarts地图数据下载网址:/download-map.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。