友心人 2017-11-30
说起这个问题,就不得不说一下在apicloud上面页面的组成部分。在使用apicloud开发移动App时,一个页面会由两个(或以上)html组成。
其中
一个window(win)页面
一个或多个frame(frm)页面
使用apicloud所提供的api.openframe或api.openframegroup来在window中加载frame。
今天我想要分享的就是怎样使用keyback方法监听手机返回键按下并且关闭指定的frame页面,而不是整个window。
话不多说我们开始:
今天在做项目的时候遇到一个页面,大概的样子就是在win中的一个frame中点击一个按钮,需要弹出一个新的frame(以下称弹窗),在弹窗打开以后,当我按下手机返回按钮时需要关闭这个新打开的弹窗,但是在默认情况下关闭的是整个window,在写好这个功能后心血来潮在这里分享一下(虽然技术含量不是很高!@。@)
在入手去写的时候,我首先想到了apicloud官方所提供的api接口-----keyback 这个api就是用来监听手机返回键的。
想到了用什么就该开始写代码
api.addEventListener({
name: 'keyback'
}, function(ret, err) {
api.closeFrame({
name: '弹窗'
});
});
开始的时候我只写了这一段,意思就是在win中按下了返回键,就关掉弹窗页面(为了阅读方便name中我使用的汉字)。
写好之后呢,第一个问题来了,指定的frame可以关掉,但是关掉frame之后再次按下返回键的时候没有反应,正常是该关掉win的,显然这样不行。
这回我想到通过判断来实现按下返回键时不同的需求。那该判断什么呢,当然是判断弹窗是否已打开,如果打开,返回键按下则关闭弹窗,否则关闭win。但是apicloud中并没有给我提供用来判断frame打开状态的方法,这里我们使用提供的数据存储 -- $api.setStorage和getStorage。
例如,在frame中有一个button 上有一个方法叫做 open(),点击button弹出弹窗
function open()}{
api.openframe({
name: '弹窗',
url: '弹窗.html',
bounces: false,
bgColor: 'widget://image/login_bg.png',
rect: {
x: 0,
y: 0,
w: 'auto',
h: 'auto'
}
})
$api.setStorage('flag',1);//标记
}
在点击按钮的同时,使用setStorage存储一个标记,值为1
在win中获取这个标记,var flag = getStorage('flag');
然后通过flag来判断弹窗是否打开
var flag = $api.getStorage('flag');
api.addEventListener({
name: 'keyback'
}, function(ret, err) {
if(flag == 1){
api.closeFrame({
name: '弹窗'
});
flag = 0;
}else if(flag == 0){
api.closeWin({
});
}
});
如果弹窗frame已经打开,我们之前设置的flag已经生效,值为1。
如果flag值为1,按下返回键关闭弹窗,并且将flag值设置为0,当我们关闭弹窗之后再次点击返回键时,flag已经为0,所以关闭win。
至此,我以为功能已经实现,正要欢呼雀跃(其实没这么严重啦)时,bug来了。。。以上方法表面上已经实现了功能,但是问题是只有在弹窗第一次打开时,功能是可以实现的,但是关掉弹窗之后再次打开弹窗,按下返回键又把整个window关掉了,也就是我设置的标记只有弹窗第一次打开生效,关掉弹窗之后标记就失效了。
再次思索中。。。有了
在apicloud中有一个方法 ----- api.execScript 在制定的win或者frame中执行js方法。
终级代码(中间又出现一个小bug,已解决,避免啰嗦就直接上成型的了)
win页面:
var flag;
function change(){
flag = 1;
}
apiready = function(){
flag = $api.getStorage('flag');
api.addEventListener({
name: 'keyback'
}, function(ret, err) {
if(flag == 1){
api.closeFrame({
name: '弹窗'
});
flag = 0;
}else if(flag == 0){
api.closeWin({
});
}
});
};
弹窗按钮所在的frame(不是弹窗frame):
apiready = function(){
api.parseTapmode();
};
var flag = $api.setStorage('flag', 0);
function open(){
api.openFrame({
name: '弹窗',
url: '弹窗.html',
rect: {
x: 0,
y: 0,
w: 'auto',
h: 'auto'
},
pageParam: {
name: 'test'
},
bounces: false,
vScrollBarEnabled: false,
hScrollBarEnabled: false
});
flag = 1;
api.execScript({
script: 'change();'
});
}