AppCan JSSDK模块扩展


1.     
从源码开始:

我们先看源码的8188行到9525行:

window.appcan && appcan.define('window',function($,exports,module){
   
    var subscribeGlobslQueue = [];//订阅队列
   
var bounceCallQueue = [];//
   
var multiPopoverQueue = {};
    var currentOS = '';
    var keyFuncMapper = {};//映射
   
   
/*
       
捕获android实体键
        @param String id
实体键的id
        @param Function callback
当点击时出发的回调函数
   
   
    */
   
function monitorKey(id,callback){
        keyFuncMapper[id] = callback;
        uexWindow.setReportKey(id);
        uexWindow.onKeyPressed = function(keyCode){
            keyFuncMapper[keyCode] && keyFuncMapper[keyCode](keyCode);   
        }
    }
   
    /*
   
打开一个新窗口
    @param String name
新窗口的名字 如果该window已经存在则直接打开
    @param String dataType
数据类型:0url 1html 数据 2html and url
    @param String data
载入的数据
    @param Int aniId
动画id
        0
:无动画
        1:
从左向右推入
        2:
从右向左推入
        3:
从上向下推入
        4:
从下向上推入
        5:
淡入淡出
        6:
左翻页
        7:
右翻页
        8:
水波纹
        9:
由左向右切入
        10:
由右向左切入
        11:
由上先下切入
        12:
由下向上切入

13:由左向右切出
        14:
由右向左切出
        15:
由上向下切出
        16:
由下向上切出
    @param int width
窗口宽度
    @param int height
窗口的高度
    @param int tpye
窗口的类型
        0:
普通窗口
        1:OAuth
窗口
        2:
加密页面窗口
        4:
强制刷新
        8:url
用系统浏览器打开
        16:view
不透明
        32:
隐藏的winwdow
        64:
等待popOver加载完毕后显示
        128:
支持手势
        256:
标记opnwindow上一个window不隐藏
        512:
标记呗open的浮动窗口用友打开wabapp
    @param animDuration
动画时长

*/
    function open(name,data,aniId,type,dataType,width,height,animDuration,extraInfo){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            argObj = name;
            name = argObj['name'];
            dataType = argObj['dataType'] || 0;
            aniId = argObj['aniId'] || 0;
            width = argObj['width'];
            height = argObj['height'];
            type = argObj['type'] || 0;
            animDuration = argObj['animDuration'];
         extraInfo = argObj['extraInfo'];
            data = argObj['data'];
        }
        dataType = dataType || 0;
        aniId = aniId || 0;
        type = type || 0;
        animDuration = animDuration || 300;
     
      try{
         extraInfo = appcan.isString(extraInfo) ? extraInfo : JSON.stringify(extraInfo);
         extraInfo = JSON.parse(extraInfo);
         if(!extraInfo.extraInfo){
            extraInfo = {extraInfo:extraInfo};
         }
         extraInfo = JSON.stringify(extraInfo);
      }catch(e){
         extraInfo = extraInfo || '';
      }
     
        //打开新窗口
       
uexWindow.open(name,dataType,data,aniId,width,height,type,animDuration,extraInfo);
    }

/*
   
关闭窗口
    @param String animateId
窗口关闭动画
    @param Int animDuration
动画持续时间

*/
    function close(animId,animDuration){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(animId)){
            argObj = animId;
            animId = argObj['animId'];
            animDuration = argObj['animDuration'];
        }
        if(animId){
            animId = parseInt(animId,10);
            if(isNaN(animId) || animId > 16 || animId < 0){
                animId = -1;
            }
        }
        if(animDuration){
            animDuration = parseInt(animDuration,10);
            animDuration = isNaN(animDuration)?'':animDuration;
        }
        animDuration = animDuration || 300;
        uexWindow.close(animId,animDuration);
    }

/*
   
在指定的窗口执行js脚本

@param string name 窗口的名字
    @param string type
窗口类型
    @param string inscript
窗口内容

*/
    function evaluateScript(name,scriptContent,type){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            argObj = name;
            name = argObj['name'];
            type = argObj['type'] || 0;
            scriptContent = argObj['scriptContent'];
        }
        type = type || 0;
        uexWindow.evaluateScript(name,type,scriptContent);
    }
    /*
   
在指定的浮动窗口中执行脚本
    @param String name
执行的窗口名字
    @param String popName
浮动窗口名
    @param String scriptContent
脚本内容

*/
    function evaluatePopoverScript(name,popName,scriptContent){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            argObj = name;
            name = argObj['name'];
            popName = argObj['popName'] || 0;
            scriptContent = argObj['scriptContent'];
        }
        name = name || '';
        if(!appcan.isString(popName) || !popName){
            return;          
        }
        uexWindow.evaluatePopoverScript(name,popName,scriptContent);
    }

/*
   
设置窗口的上拉,下拉效果
    @param String bounceType
弹动效果类型
        0:
无任何效果
        1:
颜色弹动效果
        2:
设置图片弹动
    @param Function downEndCall
下拉到底的回调
    @param Function upEndCall
上拉到底的回调
    @param String color
设置下拉视图的颜色
    @param String imgSettings
设置显示内容
   
   
todo:该方法需要重写,

*/

function setBounce(bounceType,startPullCall,downEndCall,upEndCall,color,imgSettings){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(bounceType)){
            argObj = bounceType;
            bounceType = argObj['bounceType'] || 1;
            startPullCall = argObj['startPullCall'];
            downEndCall = argObj['downEndCall'];
            upEndCall = argObj['upEndCall'];
            color = argObj['color'] || 'rgba(255,255,255,0)';
            imgSettings = argObj['imgSettings'] || '{"imagePath":"res://reload.png",'+
            '"textColor":"#530606","pullToReloadText":"拖动刷新",'+
            '"releaseToReloadText":"释放刷新",'+
            '"loadingText":"加载中,请稍等"}';
       
        }
        color = color || 'rgba(255,255,255,0)';
        imgSettings = imgSettings || '{"imagePath":"res://reload.png",'+
        '"textColor":"#530606","pullToReloadText":"拖动刷新",'+
        '"releaseToReloadText":"释放刷新",'+
        '"loadingText":"加载中,请稍等"}';

// if(!bounceType){
            // return;
        // }
       
var startBounce = 1;
        //绑定回弹通知函数
       
uexWindow.onBounceStateChange = function (type,status){
            if(status == 0){
                startPullCall
&& startPullCall(type);
            }
            if(status == 1) {
                downEndCall &&
downEndCall(type);
            }
            if(status == 2) {
                upEndCall &&
upEndCall(type);
            }
        };
        uexWindow.setBounce(startBounce);
        //设置颜色
       
/*if(bounceType == 1){
           
uexWindow.showBounceView('0',color,'1');
        }
        if(bounceType == 2){
           
uexWindow.setBounceParams('0',imgSettings);
           
uexWindow.showBounceView('0',color,1);
        }*/
        //
绑定下拉回调
       
if(startPullCall || downEndCall ||
upEndCall){
            if(!appcan.isArray(bounceType)){
               
bounceType=[bounceType];
            }
            for(var i=0;i<bounceType.length;i++){
               
uexWindow.notifyBounceEvent(bounceType[i],'1');

setBounceParams(bounceType[i],imgSettings);
               
uexWindow.showBounceView(bounceType[i],color,'1');
               
               
            }
           
        }
    }
  
  
   var bounceStateQueue =[];
            /*
       
处理回调获取弹动状态
        @param string msg
传递过来的消息
   
    */
   
function processGetBounceStateQueue(data,dataType,opId){
        if(bounceStateQueue.length > 0){
            $.each(bounceStateQueue,function(i,v){
                if(v && appcan.isFunction(v)){
                    if(dataType == 2){
                       
v(data,dataType,opId);
                    }
                   
                }
            });
        }
        bounceStateQueue=[];
        return;
    }

/*
       
获取当前的弹动状态
       
       
    */
   
function getBounceStatus(callback){
        if(arguments.length === 1 && appcan.isPlainObject(callback)){
            callback = callback['callback'];
        }
        if(!appcan.isFunction(callback)){
            return;
        }
        bounceStateQueue.push(callback);
        uexWindow.cbBounceState = function(opId, dataType, data){
            processGetBounceStateQueue(data,dataType,opId);
        };

uexWindow.getBounce();
    }
   
    /*
       
开启上下滑动回弹
       
       
    */
   
function enableBounce(){
        //1:开启回弹效果
       
uexWindow.setBounce(1);
    }
   
    /*
       
关闭回弹效果
   
    */
   
function disableBounce(){
        //0:禁用回弹效果
       
uexWindow.setBounce(0);
    }
   
    /*
       
设置回弹类
        @param String type
设置回弹的类型
        @param String color
设置回弹显示的颜色
        @param Int flag
设置是否添加回弹回调
        @param Function callback
回弹的回调函数
       
   
    */
   
function setBounceType(type,color,flag,callback){
        if(arguments.length ===1 && appcan.isPlainObject(type)){
            flag = type.flag;
            color = type.color;
            callback = type.callback;
            type = type.type;
        }
        flag = (flag === void 0 ? 1 : flag);
        flag = parseInt(flag,10);
        color = color || 'rgba(0,0,0,0)';
        type = (type === void 0 ? 0 : type);
        callback = callback || function(){};
        //强制开启页面弹动效果
       
enableBounce();
       
       
uexWindow.showBounceView(type,color,flag);
        if(flag){
            bounceCallQueue.push({type:type,callback:callback});
            uexWindow.onBounceStateChange || (uexWindow.onBounceStateChange = function(backType,status){
                var currCallObj = null;
                for(var i=0,len=bounceCallQueue.length;i<len;i++){
                    currCallObj = bounceCallQueue[i];
                    if(currCallObj){
                        if(backType === currCallObj.type){
                            if(appcan.isFunction(currCallObj.callback)){
                                currCallObj.callback(status,type);
                            }
                        }
                    }
                }
            });
            //1:接收回调函数
           
uexWindow.notifyBounceEvent(type,1);
        }
    }
   
    /*
       
给上下回弹添加参数
        @param String position
设置回弹的类型
        @param Object data
要设置回弹显示出来内容的json参数
        {
            imagePath:'
回弹显示的图片路径',
            textColor:'
设置回弹内容的字体颜色',
            levelText:'
设置文字的级别',
            pullToReloadText:'
下拉超过边界显示出的内容',
            releaseToReloadText:'
拖动超过刷新边界后显示的内容',
            loadingText:'
拖动超过刷新临界线并且释放,并且拖动'
        }
   
    */
   
function setBounceParams(position,data){
        if(arguments.length ===1 && appcan.isPlainObject(position)){
            data = position.data;
            position = position.position;
        }
        if(appcan.isPlainObject(data)){
            data = JSON.stringify(data);
        }
        uexWindow.setBounceParams(position,data);
    }

/*
   
展示弹动结束后显示的网页
    @param String position 0
为顶端恢复弹动,1为底部恢复弹动

*/

function resetBounceView(position){
        if(appcan.isPlainObject(position)){
            position = position['position'];
        }
        position = parseInt(position,10);
        if(isNaN(position)){
            position = 0;
        }else{
            position = position;
        }
        position = position || 0;
        uexWindow.resetBounceView(position);
    }

/*
   
弹出一个非模态的提示框
    @param String type
消息提示框显示的模式
        0:
没有进度条
        1:
有进度条
    @param String position
提示在手机上的位置
        1:left_top
        2:top
        3:right_top
        4:left
        5:middle
        6:right
        7:bottom_left
        8:bottom
        9:right_bottom
    @param String msg
提示内容
    @param String duration
提示框存在时间,小于0不会自动关闭

*/

function openToast(msg,duration,position,type){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(msg)){
            argObj = msg;
            msg = argObj['msg'];
            duration = argObj['duration'];
            position = argObj['position'] || 5;
            type = argObj['type'];
        }
        type = type || (duration?0:1);
        duration = duration || 0;
        position = position || 5;
        //执行跳转
       
uexWindow.toast(type,position,msg,duration);
    }

/*
   
关闭提示框

*/
    function closeToast(){
        uexWindow.closeToast();
    }

/*
   
移动浮动窗口位置动画
    @param String left
距离左边界的位置
    @param String top
距离上边界的位置
    @param Function callback
动画完成的回调函数
    @param Int duration
动画的移动时间

*/

function moveAnim(left,top,callback,duration){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(left)){
            argObj = left;
            left = argObj['left'] || 0;
            top = argObj['top'] || 0;
            callback = argObj['callback'];
            duration = argObj['duration'] || 250;
        }
        left = left || 0;
        top = top || 0;
        duration = duration || 250;
        uexWindow.beginAnimition();
       
uexWindow.setAnimitionDuration(duration);
       
uexWindow.setAnimitionRepeatCount('0');
       
uexWindow.setAnimitionAutoReverse('0');
       
uexWindow.makeTranslation(left,top,'0');
        uexWindow.commitAnimition();
        if(appcan.isFunction(callback)) {
            uexWindow.onAnimationFinish = callback;
        }
    }
   
    /*
       
   
    */
       
   
function setWindowFrame(dx,dy,duration,callback){
        if(arguments.length === 1 && appcan.isPlainObject(dx)){
            argObj = dx;
            dx = argObj['dx'] || 0;
            dy = argObj['dy'] || 0;
            duration = argObj['duration'] || 250;
            callback = argObj['callback'] || function(){};
        }
        uexWindow.onSetWindowFrameFinish = callback;
        uexWindow.setWindowFrame(dx,dy,duration);
    }
   
   
    /*
   
依指定的样式弹出一个提示框
    @param String selector css
选择器
    @param String url
加载的数据内容
    @param String left
居左距离
    @param String top
居上距离
    @param String name
弹窗名称

*/

function popoverElement(id,url,left,top,name,extraInfo){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(id)){
            argObj = id;
            id = argObj['id'] || 0;
            url = argObj['url'];
            top = argObj['top'];
            left = argObj['left'];
         extraInfo = argObj['extraInfo'];
            name = argObj['name'];
        }
        top = top || 0;
        left = left || 0;
        var ele = $('#'+id);
        var width = ele.width();
        var height = ele.height();
        var fontSize = ele.css('font-size');
        top = parseInt(top,10);
        top = isNaN(top)?ele.offset().top:top;//默认使用元素本身的top
       
left = parseInt(left,10);
        left = isNaN(left)?ele.offset().left:left;//默认使用元素本身的left
       
name = name?name:id;
       
      extraInfo = extraInfo || '';
     
        //fixed xiaomi 2s bug
       
fontSize = parseInt(fontSize,10);
        fontSize = isNaN(fontSize)? 0 : fontSize;
       
        openPopover(name,0,url,'',left,top,width,height,fontSize,0,0,extraInfo);
    }

/*
   
打开一个浮动窗口
    @param String name
浮动窗口名
    @param String dataType
数据类型0:url 1:html 2:url html
    @param String url  url
地址
    @param String data
数据
    @param Int left
居左距离
    @param Int top
居上距离
    @param Int width

    @param Int height

    @param Int fontSize
默认字体
    @param Int tpye
窗口的类型
        0:
普通窗口
        1:OAuth
窗口
        2:
加密页面窗口
        4:
强制刷新
        8:url
用系统浏览器打开
        16:view
不透明
        32:
隐藏的winwdow
        64:
等待popOver加载完毕后显示
        128:
支持手势
        256:
标记opnwindow上一个window不隐藏
        512:
标记呗open的浮动窗口用友打开wabapp
   
    @param Int bottomMargin
浮动窗口相对父窗口底部的距离。为空或0时,默认为0。当值不等于0时,inHeight参数无效

*/
    function openPopover(name,dataType,url,data,left,top,width,height,fontSize,type,bottomMargin,extraInfo){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            argObj = name;
            name = argObj['name'];
            dataType = argObj['dataType'];
            url = argObj['url'];
            data = argObj['data'];
            left = argObj['left'];
            top = argObj['top'];
            width = argObj['width'];
            height = argObj['height'];
            fontSize = argObj['fontSize'];
            type = argObj['type'];
            bottomMargin = argObj['bottomMargin'];
         extraInfo = argObj['extraInfo'];
        }
        dataType = dataType || 0;
        left = left || 0;
        top = top || 0;
        height = height || 0;
        width = width || 0;
        type = type || 0;
        bottomMargin = bottomMargin || 0;
        fontSize = fontSize || 0;
        data = data || '';
        //fixed xiaomi 2s bug
       
fontSize = parseInt(fontSize,10);
        fontSize = isNaN(fontSize)?0:fontSize;
     
      try{
         extraInfo = appcan.isString(extraInfo) ? extraInfo : JSON.stringify(extraInfo);
         extraInfo = JSON.parse(extraInfo);
         if(!extraInfo.extraInfo){
            extraInfo = {extraInfo:extraInfo};
         }
         extraInfo = JSON.stringify(extraInfo);
      }catch(e){
         extraInfo = extraInfo || '';
      }
     
        //fixed ios bug
       
if(uexWidgetOne.platformName && uexWidgetOne.platformName.toLowerCase().indexOf('ios') > -1){
            var args = ['"'+name+'"',dataType,'"'+url+'"','"'+data+'"',left,top,width,height,fontSize,type,bottomMargin,"'"+extraInfo+"'"];
            var scriptContent = 'uexWindow.openPopover(' + args.join(',') +')';
            evaluateScript('',scriptContent);
            return;
        }
        uexWindow.openPopover(name,dataType,url,data,left,top,width,height,fontSize,type,bottomMargin,extraInfo);
    }

/*
   
关闭浮动按钮
    @param String name
浮动窗口的名字

*/

function closePopover(name){
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            name = name['name'];
        }
        uexWindow.closePopover(name);
    }

/*
   
根据制定元素重置提示框的位置大小
    @param String id
元素id
    @param String left
距左边距离
    @param String top
距上边的距离
    @param String name
名称,默认为id
    */

function resizePopoverByEle(id,left,top,name){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(id)){
            argObj = id;
            id = argObj['id'];
            left = argObj['left'];
            top = argObj['top'];
            name = argObj['name'];
        }
        left = left || 0;
        top = top || 0;
        var ele = $('#'+id);
        var width = ele.width();
        var height = ele.height();
        left = parseInt(left,10);
        left = isNaN(left)?0:left;
        top = parseInt(top,10);
        top = isNaN(top)?0:top;
        name = name?name:id;
       
uexWindow.setPopoverFrame(name,left,top,width,height);
    }

/*
   
重置提示框的位置大小
    @param String name popover

    @param String left
距左边距离
    @param String top
距上边的距离
    @param String width
窗口的宽
    @param String height
窗口的高

*/

function resizePopover(name,left,top,width,height){
        var argObj = null;
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            argObj = name;
            name = argObj['name'];
            left = argObj['left'];
            top = argObj['top'];
            width = argObj['width'];
            height = argObj['height'];
        }
        left = left || 0;
        top = top || 0;
        width = width || 0;
        height = height || 0;

left = parseInt(left,10);
        left = isNaN(left)?0:left;

top = parseInt(top,10);
        top = isNaN(top)?0:top;

width = parseInt(width,10);
        width = isNaN(width)?0:width;

height = parseInt(height,10);
        height = isNaN(height)?0:height;

uexWindow.setPopoverFrame(name,left,top,width,height);
    }

/*
   
弹出一个确认框
    @param String title
对话框的标题
    @param String content
对话框的内容
    @param Array buttons
按钮文字

*/
    function windowConfirm(title,content,buttons,callback){
        if(arguments.length === 1 && appcan.isPlainObject(title)){
            callback = title['callback'];
            buttons = title['buttons'];
            content = title['content'];
            title = title['title'];
        }
        title = title || '提示';
        buttons = buttons || ['确定'];
        buttons = appcan.isArray(buttons)?buttons:[buttons];
        popConfirm(title,content,buttons,callback);
    }
   
    /*
   
弹出一个警告框
    @param String title
对话框的标题
    @param String content
对话框的内容
    @param Array buttons
按钮文字

*/
    function popAlert(title,content,buttons){
        if(arguments.length === 1 && appcan.isPlainObject(title)){
            buttons = title['buttons'];
            content = title['content'];
            title = title['title'];
        }
        buttons = appcan.isArray(buttons)?buttons:[buttons];
        uexWindow.alert(title,content,buttons[0]);
    }
   
    /*
       
弹出一个提示框
        @param String title
对话框的标题
        @param String content
对话框的内容
        @param Array buttons
按钮文字
       
       
       
    */
   
function popConfirm(title,content,buttons,callback){
        if(arguments.length === 1 && appcan.isPlainObject(title)){
            callback = title['callback'];
            buttons = title['buttons'];
            content = title['content'];
            title = title['title'];
        }
        buttons = appcan.isArray(buttons)?buttons:[buttons];
        if(appcan.isFunction(callback)){
            uexWindow.cbConfirm = function(optId,dataType,data){
                if(dataType != 2){
                    return callback(new Error('confirm error'));
                }
                callback(null,data,dataType,optId);
            };
        }
       
        uexWindow.confirm(title,content,buttons);
    }
   
    /*
       
弹出一个可提示用户输入的对话框
        @param String title
对话框的标题
        @param String content
对话框显示的内容
        @param String defaultValue
输入框默认文字
        @param Array  buttons
显示在按钮上的文字集合
        @param Function callback 
对话框关闭的回调
       
       
    */
   
function popPrompt(title, content, defaultValue,
buttons,callback){
        if(arguments.length === 1 && appcan.isPlainObject(title)){
            callback = title['callback'];
            buttons = title['buttons'];
            content = title['content'];
            defaultValue = title['defaultValue'];
            title = title['title'];
        }
        buttons = appcan.isArray(buttons)?buttons:[buttons];
        if(appcan.isFunction(callback)){
            uexWindow.cbPrompt = function(optId,dataType,data){
                try{
                    var data=JSON.parse(data);
                    callback(null,data,dataType,optId);
                }
                catch(e){
                    callback(e);
                }
            };
        }
       
        uexWindow.prompt(title,content,defaultValue,buttons);
    }
   
    /*
   
把指定的浮动窗口排在所有浮动窗口最上面
    @param String name
浮动窗口的名字

*/

function bringPopoverToFront(name){
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            name = name['name'];
        }
        uexWindow.bringPopoverToFront(name);
    }
   
    /*
   
把指定的浮动窗口排在所有浮动窗口最下面
    @param String name
浮动窗口的名字

*/
   
    function sendPopoverToBack(name){
        if(arguments.length === 1 && appcan.isPlainObject(name)){
            name = name['name'];
        }
        uexWindow.sendPopoverToBack(name);
    }
   
    /*
       
订阅一个频道消息,当有消息发布的时候该该回调将会调用该回调
        @param Int channelId
频道id
        @param Function callback
回调函数
       
    */
   
function subscribe(channelId,callback){
        if(arguments.length === 1 && appcan.isPlainObject(channelId)){
            callback = channelId['callback'];
            channelId = channelId['channelId'];
        }
        if(!appcan.isFunction(callback)){
            return;
        }
        var funName = 'notify_callback_' + appcan.getUID();
        uexWindow[funName] = callback;
       
uexWindow.subscribeChannelNotification(channelId,funName);
    }
   
    /*
       
发布一个消息
        @param Int channelId :
频道id
        @param String msg :
要发布的消息
   
    */
   
function publish(channelId,msg){
        if(arguments.length === 1 && appcan.isPlainObject(channelId)){
            msg = channelId['msg'];
            channelId = channelId['channelId'];
        }
        if(appcan.isPlainObject(msg)){
            msg = JSON.stringify(msg);
        }
       
uexWindow.publishChannelNotification(channelId,msg);
    }
   
    /*
       
向全局的公共频道发送消息
        @param String msg
向全局频道发送消息
   
    */
   
   
function publishGlobal(msg){
        if(arguments.length === 1 && appcan.isPlainObject(msg)){
            msg = msg['msg'];
        }
       
uexWindow.postGlobalNotification(msg);
    }
   
    /*
       
处理全局回调订阅消息
        @param string msg
传递过来的消息
   
    */
   
function processSubscribeGolbalQueue(msg){
        if(subscribeGlobslQueue.length > 0){
            $.each(subscribeGlobslQueue,function(i,v){
                if(v && appcan.isFunction(v)){
                    v(msg);
                }
            });
        }
        return
   
}
   
    /*
       
订阅全局的频道
        @param Function callback
订阅的回调
   
    */
   
function subscribeGlobal(callback){
        if(arguments.length === 1 && appcan.isPlainObject(callback)){
            callback = callback['callback'];
        }
        if(!appcan.isFunction(callback)){
            return;
        }
        subscribeGlobslQueue.push(callback);
        uexWindow.onGlobalNotification = function(msg){
            processSubscribeGolbalQueue(msg);
        };
    }
   
    /*
       
移除全局订阅事件
        @param Function callback
:要移除的回调的引用
   
    */
   
function removeGlobalSubscribe(callback){
        if(arguments.length === 1 && appcan.isPlainObject(callback)){
            callback = callback['callback'];
        }
        if(!appcan.isFunction(callback)){
            return;
        }
        for(var i=0,len=subscribeGlobslQueue.length;i<len;i++){
            if(subscribeGlobslQueue[i] === callback){
                subscribeGlobslQueue.splice(i,1);
                return;
            }
        }
    }
   
    /*
       
处理多窗口滑动回调事件
       
    */
   
function processMultiPopover(err,res){
        if(err){
            //todo call error
       
}else{
            if(appcan.isString(res)){
                res = JSON.parse(res);
            }
            if(!res.multiPopName){
                return;
            }
            var multiCalls = multiPopoverQueue[res.multiPopName];
            $.each(multiCalls,function(i,fun){
                if(appcan.isFunction(fun)){
                    fun(null,res);
                }
            });
        }
    }
   
    /*
       
弹出多页面浮动窗口
        @param String popName:
弹出窗口的名称
        @param String content:
传入的数据
        @param String dataType:
传入数据的类型 0url方式载入;1html内容 方式载入;2:既有url方式,又有html内容方式
        @param Int left:
距离左边的距离
        @param Int top:
距离上边界的距离
        @param Int width:
弹出窗口的宽
        @param Int height:
弹出窗口的高
        @param Int fontSize:
字体大小
        @param Int flag:
弹出类型的标识
        @param Int indexSelected:
默认选中的窗口
       
   
    */
   
function openMultiPopover(popName,content,dataType, left, top,
width, height,change, fontSize, flag, indexSelected,extraInfo){
        if(arguments.length === 1 && appcan.isPlainObject(popName)){
            indexSelected = popName['indexSelected'];
            flag = popName['flag'];
            fontSize = popName['fontSize'];
            change = popName['change'];
            height = popName['height'];
            width = popName['width'];
            top = popName['top'];
            left = popName['left'];
            dataType = popName['dataType'];
            content = popName['content'];
         extraInfo = popName['extraInfo']
            popName = popName['popName'];
        }
        dataType = dataType || 0;
        flag = flag || 0;
        indexSelected = parseInt(indexSelected,10);
        indexSelected = isNaN(indexSelected)? 0 : indexSelected;
        width = width || 0;
        height = height || 0;
        change = change || function(){};
     
      try{
         extraInfo = appcan.isString(extraInfo) ? extraInfo : JSON.stringify(extraInfo);
         extraInfo = JSON.parse(extraInfo);
         if(!extraInfo.extraInfo){
            extraInfo = {extraInfo:extraInfo};
         }
         extraInfo = JSON.stringify(extraInfo);
      }catch(e){
         extraInfo = extraInfo || '';
      }
       
        //fixed android 如果少任何一个key就会crash bug
       
if(!appcan.isString(content)){
            if(!content.content){
                content={
                    content:content
                };
            }
        }else{
            content = JSON.parse(conent);
            if(!content.content){
                content={
                    content:content
                };
            }
        }
        //check all key
       
var mustKey = ['inPageName','inUrl','inData'];
        var realContent = content.content;
        $.each(realContent,function(i,v){
            $.each(mustKey,function(i1,v1){
                if(!(v1 in v)){
                    v[v1] = '';
                }
            });
        });
        //content
       
content = JSON.stringify(content);
        if(multiPopoverQueue[popName]){
            multiPopoverQueue[popName].push(change);
        }else{
            multiPopoverQueue[popName] = [change];
        }
        uexWindow.openMultiPopover(content,popName,dataType,
left, top, width, height, fontSize, flag, indexSelected,extraInfo);
        uexWindow.cbOpenMultiPopover = function(optId,dataType,res){
            if(optId == 0){
                if(dataType != 1){
                    processMultiPopover(new Error('multi popover error'));
                }else{
                    processMultiPopover(null,res);
                }
            }
        };
        //fixed ios indexed bug
       
setSelectedPopOverInMultiWindow(popName, indexSelected);
    }
   
    /*
       
关闭多页面浮动窗口
        @param String popName:
多页面弹出窗口
       
   
    */
   
function closeMultiPopover(popName){
        if(arguments.length === 1 && appcan.isPlainObject(popName)){
            popName = popName['popName'];
        }
        if(!popName){
            return;
        }
       
        uexWindow.closeMultiPopover(popName)
       
    }
   
    /*
       
设置多页面浮动窗口跳转到的子页面窗口的索引
        @param String popName:
多窗口弹出框的名称
       
@param String index:
页面的索引
       
       
    */
   
function setSelectedPopOverInMultiWindow(popName,index){
        if(arguments.length === 1 && appcan.isPlainObject(popName)){
            index = popName['index'];
            popName = popName['popName'];
        }
        if(!popName){
            return;
        }
        index = parseInt(index,10);
        index = isNaN(index)? 0 : index;
        //fixed 模拟器不支持MultiPopOver bug
       
uexWindow.setSelectedPopOverInMultiWindow
&& uexWindow.setSelectedPopOverInMultiWindow(popName,index);
       
    }
   
   
   
    var windowStatusCallList = [];
   
    /*
       
       
处理窗口回调事件
        @param Function state:
当前的状态
       
       
    */
   
function processWindowStateChange(state){
        $.each(windowStatusCallList,function(i,v){
            if(appcan.isFunction(v)){
                v(state);
            }
        })
    }
   
   
    /*
       
当前窗口的状态改变
        @param Function callback:
窗口事件改变后的回调函数
       
   
    */
   
function onStateChange(callback){
        if(!appcan.isFunction(callback)){
            return;
        }
        //兼容老用法
       
       
windowStatusCallList.push(callback);
       
        uexWindow.onStateChange = processWindowStateChange;
    }
   
    /*
       
默认状态改变事件
       
   
    */
   
   
function defaultStatusChange(state){
        var tmpResumeCall = null;
        var tmpPauseCall = null;
        if(appcan.window.onResume){
            tmpResumeCall = appcan.window.onResume;
        }
        if(appcan.window.onPause){
            tmpPauseCall = appcan.window.onPause;
        }
       
        if(state === 0){
            appcanWindow.emit('resume');
            tmpResumeCall && tmpResumeCall();
        }
       
        if(state === 1){
            appcanWindow.emit('pause');
            tmpPauseCall && tmpPauseCall();
        }
       
    }
   
   
    /*
   
        swipe
回调列表
       
       
    */
   
var swipeCallbackList = {
        left:[],
        right:[]
    };
   
    function processSwipeLeft(){
       
        $.each(swipeCallbackList.left,function(i,v){
            if(appcan.isFunction(v)){
                v();
            }
        })
       
    }
   
    function processSwipeRight(){
       
        $.each(swipeCallbackList.right,function(i,v){
            if(appcan.isFunction(v)){
                v();
            }
        })
    }
   
    /*
       
当页面滑动的时候,执行的回调方法
       
   
    */
   
function onSwipe(direction,callback){
       
        if(direction === 'left'){
            swipeCallbackList[direction].push(callback);
           
            uexWindow.onSwipeLeft = processSwipeLeft;
            return;
        }
        if(direction === 'right'){
            swipeCallbackList[direction].push(callback);
           
            uexWindow.onSwipeRight = processSwipeRight;
            return;
        }
    }
   
    function onSwipeLeft(callback){
        if(!appcan.isFunction(callback)){
            return;
        }
        onSwipe('left',callback);
    }
   
    function onSwipeRight(callback){
        if(!appcan.isFunction(callback)){
            return;
        }
        onSwipe('right',callback);
    }
   
    /*
       
       
兼容原始appcan.frame.onSwipeLeft appcan.window.onSwipeLeft 方法
       
   
    */
   
function defaultSwipeLeft(){
        var tmpSwipeLeftCall = null;
        var tmpFrameSLCall = null;
       
        if(appcan.window.onSwipeLeft){
            tmpSwipeLeftCall = appcan.window.onSwipeLeft;
        }
       
        if(appcan.frame.onSwipeLeft){
            tmpFrameSLCall = appcan.frame.onSwipeLeft;
        }
       
        appcanWindow.emit('swipeLeft');
        appcan.frame && appcan.frame.emit && appcan.frame.emit('swipeLeft');
        tmpSwipeLeftCall && tmpSwipeLeftCall();
        tmpFrameSLCall && tmpFrameSLCall();
       
    }
   
   
     /*
       
       
兼容原始appcan.frame.onSwipeRight appcan.window.onSwipeRight 方法
       
   
    */
   
function defaultSwipeRight(){
        var tmpSwipeRightCall = null;
        var tmpFrameSRCall = null;
       
        if(appcan.window.onSwipeRight){
            tmpSwipeRightCall = appcan.window.onSwipeRight;
        }
       
        if(appcan.frame.onSwipeRight){
            tmpFrameSRCall = appcan.frame.onSwipeRight;
        }
       
        appcanWindow.emit('swipeRight');
        appcan.frame && appcan.frame.emit && appcan.frame.emit('swipeRight');
        tmpSwipeRightCall && tmpSwipeRightCall();
        tmpFrameSRCall && tmpFrameSRCall();
    }
    /*
       
       
控制父组件是否拦截子组件的事件
        @param Int enable
设置父组件是否拦截子组件的事件,参数不为1时设置默认拦截;0:可以拦截,子组件不可以正常响应事件 ;1:不拦截,子组件可以正常响应事件
    */
   
function setMultilPopoverFlippingEnbaled(enable){
        var enable = parseInt(enable,10);
        enable = isNaN(enable)?0:enable;
        enable = enable!=1?0:enable;
        uexWindow.setMultilPopoverFlippingEnbaled(enable);
    }
   
   
    //默认绑定状态
   
appcan.ready(function(){
        //绑定默认状态改变事件
       
onStateChange(defaultStatusChange);
        //绑定默认swipe事件
       
onSwipeLeft(defaultSwipeLeft);
        //绑定默认swipe事件
       
onSwipeRight(defaultSwipeRight);
    });
   
    //导出接口
   
var appcanWindow = module.exports = {
        open:open,
        close:close,
        evaluateScript:evaluateScript,
        evaluatePopoverScript:evaluatePopoverScript,
        setBounce:setBounce,
        setBounceParams:setBounceParams,
        enableBounce:enableBounce,
        disableBounce:disableBounce,
        setBounceType:setBounceType,
        resetBounceView:resetBounceView,
        openToast:openToast,
        closeToast:closeToast,
        moveAnim:moveAnim,
        popoverElement:popoverElement,
        openPopover:openPopover,
        closePopover:closePopover,
        resizePopover:resizePopover,
        resizePopoverByEle:resizePopoverByEle,
        alert:windowConfirm,
        //popAlert:popAlert, 隐藏该接口,因为confirm
       
confirm:popConfirm,
        prompt:popPrompt,
        bringPopoverToFront:bringPopoverToFront,
        sendPopoverToBack:sendPopoverToBack,
        publish:publish,
        subscribe:subscribe,
        //publishGlobal:publishGlobal,
       
//subscribeGlobal:subscribeGlobal,
       
selectMultiPopover:setSelectedPopOverInMultiWindow,
        openMultiPopover:openMultiPopover,
        closeMultiPopover:closeMultiPopover,
        setWindowFrame:setWindowFrame,
        monitorKey:monitorKey,
        stateChange:onStateChange,
        swipeLeft:onSwipeLeft,
        swipeRight:onSwipeRight,
      getBounceStatus:getBounceStatus,
        setMultilPopoverFlippingEnbaled:setMultilPopoverFlippingEnbaled
       
   
};
   
    appcan.extend(appcanWindow,appcan.eventEmitter);

});

可以发现,将近1000行的代码大致可以分为3部分:

  1. appcan&&appcan.define(“modelName”,function($,exports,module){

});

  1. appcan&&appcan.define(“modelName”,function($,exports,module){

function fun1(){};

function fun2(){};

function fun3(){};

……

});

  1. appcan&&appcan.define(“modelName”,function($,exports,module){

function fun1(){};

function fun2(){};

function fun3(){};

……

var
appcanmodel=module.exports={

fun1:fun1,

fun2:fun2,

fun3:fun3,

}

});

之后我们就可以使用appcan.window.open等等的方法了。

从源码我们可以获得什么启示呢?

  1. 2.      从源码得到的启示

我们也可以自定义模块来实现JS的模块化操作。

举例:

我们现在要做一个项目,业务模块(buiness)都有登陆的功能,请假的功能,考勤的功能。

使用普通的方法我们需要写不同的方法来兼容登录,请假,请假的功能,或者说可以把这些方法写在同一个js里面,之后就可以调用,这种方式是会导致有在对外部js了解的情况下才能进行的。否则页面中突然出来一个login方法,也会让人有点不知所措。这种方式可以利用appcan JSSDK的扩展属性来实现。

首先我们定义一个js文件:名为:business.js之后,我们按照上面的模式写一段代码:

appcan.define('buiness', function($, exports,
module) {

//登陆方法

function denglu() {

alert("denglu");

}

//考勤方法

function kaoqin() {

alert("kaoqin");

}

//请假方法

function qingjia() {

alert("qingjia");

}

module.exports = {

exportDenglu : denglu,

exportKaoqin : login,

exportQingjia : qingjia

}

});

之后,我们在appcan页面中就可以调用这个模块的方法了。

appcan.button(".btn", "ani-act", function() {

appcan.buiness.exportDenglu();

})

效果如下:

如果自己写的模块不想用appcan.XXX.fun的方式,想自己定义一个对象,那么可以在上面的buiness.js中增加以下一段代码:

var tools = appcan.require("buniess");

之后在页面上就可以这样调用自己写的模块的方法:

tools.exportDenglu();

以上就是使用appcan JSSDK的扩展属性自己定义模块并且实现调用的过程。

  1. 3.      关于参数和选择器

参数:

在JavaScript中,自定义方法即是没有参数也是可以穿参数的,所有的参数都在arguments中:

例如:在buiness.js中定义一个login方法

function denglu() {

alert("denglu");

console.log(arguments);

}

module.exports = {

exportDenglu : denglu

}

页面代码

appcan.button(".btn", "ani-act", function() {

appcan.buiness.exportDenglu("zhangsan","123456");

})

这个时候,打开浏览器开发者模式看console:

这样的话就可以解决我们写模块传递参数的事情了。

选择器:

其实选择器也是参数的一种,所以我们可以使用传递参数的方法给传递选择器。

例如:在buiness.js中写下如下示例代码

//登陆方法

function denglu() {

var userName=arguments[0];

var pwd=arguments[1];

var selector = arguments[0];

if(userName==="zhangsan"&&pwd==="123456"){

appcan.window.openToast("登录成功",2000,5);

}

}

module.exports = {

exportDenglu : denglu,

}

前端页面:

appcan.button(".btn", "ani-act", function() {

appcan.buiness.exportDenglu("zhangsan","123456","#divid");

})

页面显示效果:

以上就是关于JSSDK的扩展部分,希望通过这篇文章可以给各位在做的appcan开发人员一一些灵感。让自己的代码变得有质量一些。

上一篇:iOS多线程GCD(转)


下一篇:[转]iOS代码块Block