vue动态加载SVG文件并修改节点数据的操作代码
先上一个马赛克图片叭。
接领导需求,动态实现电路图,并附带放大、缩小功能、以及不同的回路点击能弹窗显示相关节点的更多信息,
通俗一点讲:随着用户点击放大和缩小,点击位置保持不变,而且能实现点击交互。
初接触的时候,觉得根本没法下手呀,说说自己的思路叭,
- 从随着用户点击放大缩小位置不变,想到了SVG但是需要动态加载进来呀,而且还需要需求不同节点的电流值,
- 从放大缩小来看,首先想到的是D3
- 在集合领导给的部分相关资料
- 综上:进行了可行性的方案试探,也完成了整个功能的开发。
且听我细细道来开发遇到的问题,以及怎处理叭
- SVG在谷歌,以及微软中国,拼命的搜索,搜索出来有2个适合的组件,大多数搜索出来的都是SVG图标,但是我这个需求是很大的图片呀,那继续换思路,
- 那试着把关键字换成‘动态加载SVG图片',这样又查出来引入SVG图片可以通过image、Object、embed等等。但是这个插入仅限于插入,并不能动态修改值,那继续换思路
- 动态加载SVG,发现可以通过XMLHttpRequest请求然后添加事件、以及重新渲染DOM元素。
那先上一段代码
```javascript constxhr=newXMLHttpRequest(); xhr.open('GET',this.svgUrl,true); xhr.send(); /*监听xhr对象*/ xhr.onreadystatechange=function(){ if(xhr.readyState==4&&xhr.status==200){ console.log(xhr.responseXML,'xhr.responseXML---------') } }; xhr.addEventListener('load',()=>{ //console.log('load'); //console.log(xhr.response,'---svg4703') ///*获取dom*/ //console.log(xhr,xhr.responseXML,'xhr.responseXML') constresXML=stringToXml(xhr.response); this.svgDom=resXML.documentElement.cloneNode(true); //this.svgDom=resXML /*添加事件(点击事件,鼠标滚轮事件,全屏事件)*/ this.addEvents(); /*dom重置*/ this.resetDom(); /*将svgDom对象转换成vue的虚拟dom*/ varoSerializer=newXMLSerializer(); varsXML=oSerializer.serializeToString(this.svgDom); varProfile=Vue.extend({ template:""+sXML+'
好,我们继续。
既然是要根据不同的用户方,显示出来不同的模板,那么肯定是需要远程动态加载,于是自己丢了一个模板到前端静态服务器上,就开始对XMLHTTP的load事件之后对代码进行解析。
4.加载之后,发现又遇到一个问题了,跨域
跨域是老生常谈的问题了,但是普通的请求我可以找z后端设置CORS的允许投,那一个SVG我表示根本没法下手呀,于是我换了个思路,我们先跨域跨域,本地装个插件如何,最后把文件放在前端的服务器不就解决了,
然后我就真的傻傻的这样完成了,开发以及跟后端讨论的过程。
5.项目经理在继续和我沟通,这个SVG模板需要客户进去上传,也就是说,svg文件需要专门上传到OSS的文件服务器上,那么我想到的第一个问题是,肯定会跨域呀,这可咋办呢,急死我了,5555555…
6.当我把不同域名的SVG文件通过XMLHTTP引入的时候,发现SVG图片根本显示不了,我不停的去切换2个文件地址。我尝试着百度、google发现都没找到合适的解决方案咋办呢,又不能告诉项目经理说,你花了1星期的预演,之前说可以的,现在突然不行了。
7.于是我看下浏览器报错在从2个方面出发。试着打印了xhr.response
- 对比不显示的代码跟显示的代码的差异点在哪里,我谷歌xml转为html
- 打印xhr.response的时候,发现咦其实
xhr.response
其实是有值返回的,也就是说其实是返回了值,不显示是因为
xhr.responseXML这个值为null,
然后`
resXML.documentElement.cloneNode(true);
`
没办法显示,抛错了。后续所有的操作都获取不到任何节点。
8.然后我开始试着找怎么从XML转为HTML.并且还发现真的有方法耶
//将字符串转化成dom对象;string转换为xml functionstringToXml(xmlString){ varxmlDoc; if(typeofxmlString=="string"){ //FF if(document.implementation.createDocument){ varparser=newDOMParser(); xmlDoc=parser.parseFromString(xmlString,"text/xml"); }elseif(window.ActiveXObject){ xmlDoc=newActiveXObject("Microsoft.XMLDOM"); xmlDoc.async=false; xmlDoc.loadXML(xmlString); } } else{ xmlDoc=xmlString; } returnxmlDoc; } addEvents(){ console.log('这里自己写处理代码哈') }, resetDom(){ console.log('这里写需要改变的节点的id对应的值喽') },
整体SVG动态加载的方案就这样了,
参考:https://www.nhooo.com/article/193416.htm
我们在来看D3,D3的话,
就简单粗暴一点直接搜索vueD3引用,
这就不详细说明了,需求还是蛮多的。
还有遇到一个问题,就是全屏弹窗,结合elementUI使用的,操作的时候发现点击事件触发了,但是弹窗并不现实,
我刚开始以为是因为z-index的层级不够高,然后我尝试着浏览器动态调试,z-index:99999999.写了一大串的9都不显示。
原来是需要全屏显示的时候,都需要包含在全屏的那个DIV。
总结
到此这篇关于vue动态加载SVG文件并修改节点数据的文章就介绍到这了,更多相关vue动态加载SVG文件内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。