1. js文件(leaflet.js内容末尾追加以下代码)中定义类和函数,用于被调用测试
JavaScript ht.ui.TestClass = function() { console.log('here is ht.ui.TestClass'); } ht.Default.def('ht.ui.TestClass', ht.ui.DropDownTemplate, { initDropDownView: function(master, datas, value) { var self = this, htmlView = new ht.ui.HtmlView(), mapDiv = self._mapDiv = document.createElement("div"), map = self._map = L.map(mapDiv, { zoomAnimation: false, trackResize: false }).setView([39.9123, 116.3913], 15); mapDiv.style.width = '100%'; mapDiv.style.height = '100%'; // mapDiv.style.boxShadow = master.getBoxShadow(); L.tileLayer('http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}', { attribution: 'www.aiotos.net', maxZoom: 18, minZoom: 3 }).addTo(map); map.on('click', function(e) { var latlng = e.latlng; self._latlng = latlng.lat + "," + latlng.lng; self.stop(); }); htmlView.setContent(mapDiv); htmlView.setPreferredSize(400, 200); return htmlView; }, getDropDownValue: function() { return this._latlng; }, afterOpen: function(v) { var self = this, map = self._map; self.getDropDownView().validate(); self._map.invalidateSize(); if (v) { self._latlng = v; var latlng = v.split(","); map.setView([latlng[0], latlng[1]], 15); self._marker = new L.marker([latlng[0], latlng[1]]); self._marker.addTo(map).bindPopup('Here!').openPopup(); } } }); |
2. 编辑模式运行的.html启动页面中添加动态加载:
JavaScript importCssJs.js('custom/libs/leaflet/leaflet/leaflet.js', true, () => { mytest() //测试js文件中追加的自定义函数 console.log(new ht.ui.TestClass()); //测试js文件中追加的自定义类 console.log(L); //测试js本就是leaflet.js,有全局变量L,类似jquery的$ }); |
![](https://i-blog.csdnimg.cn/blog_migrate/31bb88d5d7c2325afe932ac4ecb93503.png)
运行时(并未执行到渲染元素的代码)能正常访问到自定义函数、自定义类和该js类的对象:
![](https://i-blog.csdnimg.cn/blog_migrate/b5d0d0ace7005e01545c271f91bd2580.png)
3. 仅在渲染元素中动态加载添加2中的代码:
![](https://i-blog.csdnimg.cn/blog_migrate/5ca30fc10f25391e15a2b54b331deb1c.png)
编辑状态下运行,不论是刷新页面还是只在编辑器中刷新加载图纸(已移除html中加入的测试代码防止干扰)结果能正常访问到自定义函数、自定义类,但是对该js的leaflet内置的全局对象L,提示未定义无法访问!
![](https://i-blog.csdnimg.cn/blog_migrate/b2acb42d44f60ef4b5596be250bd8984.png)
4. 在3的基础上其他都不动,只是图纸预览运行,并非编辑器状态:
![](https://i-blog.csdnimg.cn/blog_migrate/66e5d32574bb5ea51a04a6e25b04d424.png)
结果跟2一样,能正常访问到自定义函数、自定义类和该js类的对象!
问题
以及揪出问题在编辑状态下编辑器动态加载leaflet.js,在加载完毕后调用其定义的变量L,竟然发现是undefined!!渲染元素代码任何不动,直接运行模式一切正常!
分析
查看leaflet.js代码(不需看源码,看目前正在加载的编译后的执行js即可)!
js中(function(){}()),(function(){})(),$(function(){});之间的区别;js闭包库
多处打印,对比编辑状态刷新加载图纸和运行状态页面刷新,发现问题出在function(t,i)函数体内的那一串条件判断上,一层层的?:表达式,对比编辑状态和运行状态,哪个条件判断不一致。
![](https://i-blog.csdnimg.cn/blog_migrate/c7a5f1ea2f32a1dc77b1a2777c97cb62.png)
从左到右依次判断,发现问题出现在typeof define上!编辑状态有此定义,但是运行状态没有,且编辑状态下的定义在vs/loader.js中:
![](https://i-blog.csdnimg.cn/blog_migrate/0a7f2f5dcf2bd30864482949ebc1ec73.png)
![](https://i-blog.csdnimg.cn/blog_migrate/30c7378e4a5ff77e4bf58e3625c6e26c.png)
这就好理解,为什么编辑状态下和运行状态下不一样,因为全局命名定义发生了污染!!!
解决方案,渲染元素中加一句代码即可
JavaScript if(!runningMode()) define = null; |
完整的渲染元素代码:
JavaScript if (!cache.obj) { function init() { function updateMarker(coordString){ if(coordString && coordString.split(',') && coordString.split(',').length >= 2){ cache.inputControl && cache.inputControl.ca('value',coordString) && cache.inputControl.iv() if(cache.marker) cache.map.removeLayer(cache.marker); cache.marker = L.marker(coordString.split(',')); cache.marker.addTo(cache.map); } }
/*这句极为重要,编辑状态下define在vs/loader.js中有定义造成在leaflet.js中命名冲突,但是运行状态下不存在,所以需要渲染元素中设置define为null即可!*/ if(!runningMode()) define = null; let obj = cache.obj = document.createElement('div'); importCssJs.css('custom/libs/leaflet/leaflet/leaflet.css'); importCssJs.loadArr('js',[//importCssJs对于逐个.js()加载,以及.loadArr()传入数组加载,对于script之间保持同步一个个顺次加载而不是并行加载!此外.loadArr()的回调函数参数,就是让列表中最后一个js加载完毕来回调! 'custom/libs/leaflet/leaflet/leaflet.js', 'custom/libs/leaflet/leaflet-plugins/leaflet-tilelayer-colorizr.js' ],true,()=>{/*第二个参数这里一定要为true或者false,效果有区别:传入true时在渲染元素重入(尤其是编辑状态重新加载图纸)时,新创建的div dom元素,能经过对应新加载对应的js去操作处理, 每次重新加载图纸都会提示报错Can only have one anonymous define call per script file,但是运行正常;传入false时,不会重新加载js,利用此前浏览器缓存的对象,在回调函数中同样会调用 到L.map传入div dom元素的对象,虽然不报错,但是效果显示不正常,地图尺寸区域不会铺满div!*/ if(!cache.map){ cache.inputControl = d(data.dm(),data.ca('inputControl'));
//leaflet实例化 let map = cache.map = L.map(obj, { center: data.ca('coord').split(','), renderer: L.svg(), zoom: data.ca('zoom'), zoomControl: false, // + -号放大缩小 attributionControl: false // 右下角leaflet.js图标 });
//地图瓦片地图图层地址 /*L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution:'© OpenStreetMap contributors' //添加可选参数 }).addTo(map)*/ //关联地图并且背景染色样式(L.tileLayer.colorizr是重写后的) let titleLayer = cache.titleLayer = L.tileLayer.colorizr(data.ca('mapurl'), { maxZoom: 18, minZoom: 3, // /*这个方法用来调整所有的图片上的rgb值,pixel是图片原有的rgb值*/ // colorize: function(pixel) { // pixel.r += 13; // pixel.g += 17; // pixel.b += 25; // return pixel; // } }); titleLayer.addTo(map);
updateMarker(data.ca('coord'));
//标定点鼠标事件点击弹出显示内容 function onMapClick(e) { data.ca('coord', e.latlng.lat + ',' + e.latlng.lng); // L.marker(data.ca('coord').split(',')).addTo(map); // L.popup().setLatLng(e.latlng) // .setContent("You clicked the map at " + e.latlng.toString()) // .openOn(map); } map.on('click', onMapClick); } }); data.dm().md(e => { if(e.data == data){ // //event格式: // { // property: 'name',//发生变化的属性 // oldValue: 'oldValue',//旧值 // newValue: 'newValue',''新值 // data: data//发生变化的data // } switch(e.property){ case 'a:zoom': cache.map && cache.map.setZoom(data.ca('zoom')); break; case 'a:coord': let coordtmp = e.newValue; coordtmp && cache.map.flyTo(coordtmp.split(','));
updateMarker(coordtmp); break; case 'a:mapurl': cache.titleLayer.setUrl(data.ca('mapurl')); break; } }else if(cache.inputControl && e.data == cache.inputControl){ switch(e.property){ case 'a:value': data.ca('coord',e.newValue); break; } } })
return obj; }
var obj = cache.obj = init() obj.layoutHTML = function () { gv.layoutHTML(data, obj, runningMode()); } }
return cache.obj; |