Chrome extension的manifest_version升级过程几个棘手问题的解决方法
来源:互联网 发布:混乱武林独孤求败软件 编辑:程序博客网 时间:2024/06/06 19:31
之前基于Jquery mobile做了一个Chrome app,就在要给客户做showcase的时候,chrome强制升级manifest_version到2(http://developer.chrome.com/extensions/manifestVersion.html),而这个version基于安全考虑做了一些限制,导致我的chrome app无法运行,具体限制可见:http://developer.chrome.com/extensions/contentSecurityPolicy.html。对于我的app主要有以下两个影响点:
- 限制dom元素上直接onclick
- 限制new Function
这两点对于我来说比较棘手。
1)去onclick
由于之前写js不规范,为了传参数方便,也由于存在动态创建dom的需求,所以就直接onclick,整个app有多达十几个onclick,比如:
var item = "<li data-theme=\"c\"><a data-transition=\"slide\" onclick=\"loadViewList('"+data.data[i]+"')\">"+data.data[i]+"</a></li>";$(item).insertAfter($("#projectListTitle"));
这里给我出的难题是这些dom是在某种场景下创建出来的dom,很难在统一的做事件侦听,再比如:
<li><a id='loadAssignToButton' onclick='loadAssignTo(${id})'>Assign CR</a></li>这里的难题是这段代码是模版里的,参数是在模版渲染时才能确定的,很难在js事件侦听里传参。并且以上问题在原有代码里存在很多,需要有个一劳永逸的方法来解决。
幸好,jquery很强大,一方面它提供了很好的selector,能让我很方便的一处监听所有需要处理的dom,另一方面,它有一个delegate的机制,也就是说除了能直接在dom上进行监听外,还能让这个dom监视它的子dom,能实现当子dom创建时再监听事件的功能,具体可见jquery.on api(http://api.jquery.com/on/)。于是,我给出了一个一劳永逸的方法:
$(document).ready(function() { $("div[data-role='page']").on("click", "a", function(event) { if($(this).attr("cf")){ var funName = $(this).attr("cf"); if(funName.indexOf(".") == -1){ window[funName]($(this).attr('cp1'),$(this).attr('cp2')); }else{ var funNames = funName.split("."); window[funNames[0]][funNames[1]]($(this).attr('cp1'),$(this).attr('cp2')); } } });});
然后,改写所有用到onclick的点,比如:
<li><a id='loadAssignToButton' cf='loadAssignTo' cp1='${id}'>Assign CR</a></li>
其中,cf,cp1和cp2分别对应着onclick监听处理函数名和参数名,是自定义属性,只是为了传参,当然也有更优雅的方式,不过这不是这里的重点。
2)去new Function
如果只是简单的使用new Function还好办,不过我这里不是直接使用了new Function,而是引用的jquery template里面用到了new Function,并且这是做模版的核心(通过动态function来渲染模版),具体用到的地方如下所示:
// Generate a reusable function that will serve to render a template against datafunction buildTmplFn( markup ) {return new Function("jQuery","$item",......)}解决这个问题要么是换模版方案,要么就是使用chrome提供的sandbox特性,由于应用模版的地方较多,换模版的成本太大,所以只好看看这个sandbox能否解决我的问题。使用方法可见:http://developer.chrome.com/trunk/apps/manifest.html#sandbox
于是乎,我照葫芦画瓢通过sandbox来改写使用了模版的地方。
1. 首先新建sandbox.html,把模版挪过来
2. 在sandbox.html,添加模版渲染的请求侦听:
<script> // Set up message event handler: window.addEventListener('message', function(event) { var data = event.data.data; var tmpl = event.data.tmpl; var dataRendered = $( "#"+tmpl ).tmpl( data ).wrap('<div>').parent().html(); var result = {'data':data,'dataRendered':dataRendered,'tmpl':tmpl}; event.source.postMessage({'result': result}, event.origin); }); </script>
其中$( "#"+tmpl ).tmpl( data ).wrap('<div>').parent().html()是由于$( "#"+tmpl ).tmpl( data )返回的是jquery的dom,sandbox是基于HTML5 web worker来做的,它并不是同享内存,所以不能传递dom,这里只好先把dom转为html,然后在主页面里通过html创建dom。
3. 在主页面里添加隐藏的iframe来向sandbox发请求
<iframe id="theFrame" src="sandbox.html" style="display: none;"></iframe>var message = {'data':data,'tmpl':'crFilterTemplate'};document.getElementById('theFrame').contentWindow.postMessage(message, '*');4. 在主页面监听message,取得模版渲染后html,并创建dom
window.addEventListener('message', function(event) { var data = event.data.result.data; var dataRendered = event.data.result.dataRendered; var tmpl = event.data.result.tmpl; window[tmpl+'Render'](data, dataRendered);});function crDetailTemplateRender(data, dataRendered) { $(dataRendered).appendTo(document.body); $("#crDetailPage").attr( "data-" + $.mobile.ns + "external-page", true ).one( 'pagecreate', $.mobile._bindPageRemove ); $.mobile.changePage( "#crDetailPage", { transition: "flip"} );}
升级manifest_version本来没在工作计划之内,是突然冒出的拦路虎,不过也给自己提了个醒,一旦基于某个平台上做事情,一定得多关注这个平台的游戏规则,不然陷阱重重啊
- Chrome extension的manifest_version升级过程几个棘手问题的解决方法
- 升级chrome出现SELinux问题的解决方法
- chrome extension 遇到的问题
- 学习中遇到的几个棘手的问题,很关键
- 棘手的问题
- 今天的棘手问题
- 四个棘手的IOCP编码问题和解决方法
- 爬虫过程中经常遇到的一些棘手问题
- Hot potato 棘手的问题
- 问一个棘手的问题!!
- 前端一些棘手的问题
- 编译过程中碰到的几个小问题和解决方法
- 软件测试的三个棘手问题
- j2me一个比较棘手的问题
- 遇到很棘手的问题呀!!!
- Xib的问题,很棘手(解决办法)
- jquery mobile最棘手的一个问题
- 最近做项目遇到的棘手问题
- 用Maven进行项目管理
- CDataExchange::PrepareCtrl(int nIDC)里出错 解决
- 命令行更新linux软件
- ubuntu开启SSH服务
- GNU风格 ARM汇编语法指南(非常详细)5
- Chrome extension的manifest_version升级过程几个棘手问题的解决方法
- Linux中buffer/cache,swap,虚拟内存和page ++
- tomcat指定时区
- 使用ViewFlipper实现图片左右滑动效果
- combox的四种扩展
- 对DataTable(或者DataSet)修改后,提交修改到数据库
- [Institution or Company] Fidessa
- js日期输入框
- gSoap