六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 35|回复: 0

dwr useLoadingMessage 改进

[复制链接]

升级  12%

172

主题

172

主题

172

主题

进士

Rank: 4

积分
560
 楼主| 发表于 2013-1-23 02:29:23 | 显示全部楼层 |阅读模式
背景:

遗留项目中用了 dwr 1.1 ,修 bug 看了看 DWRUtil.useLoadingMessage 有问题,修正后再看 dwr 2.0 ,3.0 rc1的 useLoadingMessage 实现,也不是很完美,改进下





dwr:

在 ajax 应用中,在同服务器通信的同时显示当前运行状态,可以达到很好的用户体验,如 经典的 Gmail loading :





dwr 作为整合后端的 ajax 框架,很早的就考虑到了这个问题,提供了useLoadingMessage  ( 底层依靠prehook 与 posthook ) 使得用户可以介入 xhr 请求的发送过程中去,这个机制对所有的请求统一考虑,可以一次设置,每次请求都应用。但是dwr 的实现不是很完美。



dwr 1.1
 
function(message) {    var loadingMessage;    if (message) {        loadingMessage = message;    } else {        loadingMessage = "Loading";    }    DWREngine.setPreHook(function() {        var disabledZone = $("disabledZone");        if (!disabledZone) {            disabledZone = document.createElement("div");            disabledZone.setAttribute("id", "disabledZone");            disabledZone.style.position = "absolute";            disabledZone.style.zIndex = "1000";            disabledZone.style.left = "0px";            disabledZone.style.top = "0px";            disabledZone.style.width = "100%";            disabledZone.style.height = "100%";            document.body.appendChild(disabledZone);            var messageZone = document.createElement("div");            messageZone.setAttribute("id", "messageZone");            messageZone.style.position = "absolute";            messageZone.style.top = "0px";            messageZone.style.right = "0px";            messageZone.style.background = "red";            messageZone.style.color = "white";            messageZone.style.fontFamily = "Arial,Helvetica,sans-serif";            messageZone.style.padding = "4px";            disabledZone.appendChild(messageZone);            var text = document.createTextNode(loadingMessage);            messageZone.appendChild(text);        } else {            $("messageZone").innerHTML = loadingMessage;            disabledZone.style.visibility = "visible";        }    });    DWREngine.setPostHook(function() {        $("disabledZone").style.visibility = "hidden";    });} 
问题:


1.disableZone ie 下百分比大小不能正常设置
2.当多个同时请求发生时,当一个请求返回则 loadingMessage 就被 hidden ,而其实后面的请求还没回来,当前总体状态应为 loading 。




dwr 2.0
 
function(message) {    var loadingMessage;    if (message) {        loadingMessage = message;    } else {        loadingMessage = "Loading";    }    dwr.engine.setPreHook(function() {        var disabledZone = dwr.util.byId("disabledZone");        if (!disabledZone) {            disabledZone = document.createElement("div");            disabledZone.setAttribute("id", "disabledZone");            disabledZone.style.position = "absolute";            disabledZone.style.zIndex = "1000";            disabledZone.style.left = "0px";            disabledZone.style.top = "0px";            disabledZone.style.width = "100%";            disabledZone.style.height = "100%";            document.body.appendChild(disabledZone);            var messageZone = document.createElement("div");            messageZone.setAttribute("id", "messageZone");            messageZone.style.position = "absolute";            messageZone.style.top = "0px";            messageZone.style.right = "0px";            messageZone.style.background = "red";            messageZone.style.color = "white";            messageZone.style.fontFamily = "Arial,Helvetica,sans-serif";            messageZone.style.padding = "4px";            disabledZone.appendChild(messageZone);            var text = document.createTextNode(loadingMessage);            messageZone.appendChild(text);            dwr.util._disabledZoneUseCount = 1;        } else {            dwr.util.byId("messageZone").innerHTML = loadingMessage;            disabledZone.style.visibility = "visible";            dwr.util._disabledZoneUseCount++;        }    });    dwr.engine.setPostHook(function() {        dwr.util._disabledZoneUseCount--;        if (dwr.util._disabledZoneUseCount == 0) {            dwr.util.byId("disabledZone").style.visibility = "hidden";        }    });} 
新增了一个属性 _disabledZoneUseCount 记录了当前还没处理完毕的请求个数,只有在所有请求处理完毕后才隐藏 loadingMessage 。


问题:


1.disableZone ie 下百分比大小不能正常设置

2.loadingMessage 定位为absolute ,当页面很长出现滚动条时,则当用户在页面底部操作时会出现loadingMessage 仍在文档顶部窗口之外的现象,合适的做法应该是用 fixed 定位,但是 ie6 不支持,但对ie6合适的做法应为 绝对定位到 scrollTop 坐标处即可。


dwr 3.0 rc1 基本等同 dwr 2.0
 
function(message) {    var loadingMessage;    if (message) {        loadingMessage = message;    } else {        loadingMessage = "Loading";    }    dwr.engine.setPreHook(function() {        var disabledZone = dwr.util.byId("disabledZone");        if (!disabledZone) {            disabledZone = document.createElement("div");            disabledZone.setAttribute("id", "disabledZone");            disabledZone.style.position = "absolute";            disabledZone.style.zIndex = "1000";            disabledZone.style.left = "0px";            disabledZone.style.top = "0px";            disabledZone.style.width = "100%";            disabledZone.style.height = "100%";            if (window.ActiveXObject) {                disabledZone.style.background = "white";                disabledZone.style.filter = "alpha(opacity=0)";            }            document.body.appendChild(disabledZone);            var messageZone = document.createElement("div");            messageZone.setAttribute("id", "messageZone");            messageZone.style.position = "absolute";            messageZone.style.top = "0px";            messageZone.style.right = "0px";            messageZone.style.background = "red";            messageZone.style.color = "white";            messageZone.style.fontFamily = "Arial,Helvetica,sans-serif";            messageZone.style.padding = "4px";            document.body.appendChild(messageZone);            var text = document.createTextNode(loadingMessage);            messageZone.appendChild(text);            dwr.util._disabledZoneUseCount = 1;        } else {            dwr.util.byId("messageZone").innerHTML = loadingMessage;            disabledZone.style.visibility = "visible";            dwr.util._disabledZoneUseCount++;            dwr.util.byId("messageZone").style.visibility = "visible";        }    });    dwr.engine.setPostHook(function() {        dwr.util._disabledZoneUseCount--;        if (dwr.util._disabledZoneUseCount == 0) {            dwr.util.byId("disabledZone").style.visibility = "hidden";            dwr.util.byId("messageZone").style.visibility = "hidden";        }    });} 我的改进:


可用闭包将当前active的请求封在小作用域内,判断ie6 绝对定位到scrollTop,而对于高级浏览器则直接fixed定位,另外 ie disableZone 百分比大小不起作用,改做每次都算一下,完美解决:
 
(function(){       var ua = navigator.userAgent.toLowerCase();    //judge ie6    var isIE6=/msie 6/.test(ua);        // number of activeRequests    var activeRequests=0;        //disable zone    var disabledZone;    //loading message zone    var messageZone        DWRUtil.useLoadingMessage = function(message) {        var loadingMessage;        if (message) {            loadingMessage = message;        } else {            loadingMessage = "Loading";        }        DWREngine.setPreHook(function() {                        var fixTop=(isIE6?(document.documentElement.scrollTop || (document.body.scrollTop || 0)):0)+"px";            var fixWidth=(document.documentElement.scrollWidth || (document.body.scrollWidth || 0))+"px";            var fixHeight=(document.documentElement.scrollHeight || (document.body.scrollHeight || 0))+"px";                        if (!disabledZone) {                disabledZone = document.createElement("div");                disabledZone.setAttribute("id", "disabledZone");                disabledZone.style.position = "absolute";                disabledZone.style.zIndex = "10001";                disabledZone.style.left = "0px";                disabledZone.style.top = "0px";                                //ie 100% can not work                disabledZone.style.width = fixWidth;                disabledZone.style.height = fixHeight;                                //ie opacity                if (window.ActiveXObject) {                    disabledZone.style.background = "#cccccc";                    disabledZone.style.filter = "alpha(opacity=30)";                }                document.body.appendChild(disabledZone);                messageZone = document.createElement("div");                messageZone.setAttribute("id", "messageZone");                if(isIE6) {                    messageZone.style.position = "absolute";                } else {                    messageZone.style.position = "fixed";                }                messageZone.style.top = fixTop;                messageZone.style.right = "0px";                messageZone.style.background = "red";                messageZone.style.color = "white";                messageZone.style.fontFamily = "Arial,Helvetica,sans-serif";                messageZone.style.padding = "4px";                document.body.appendChild(messageZone);                var text = document.createTextNode(loadingMessage);                messageZone.appendChild(text);            } else {                disabledZone.style.width = fixWidth;                disabledZone.style.height = fixHeight;                messageZone.style.top = fixTop;                messageZone.innerHTML = loadingMessage;                disabledZone.style.visibility = "visible";                messageZone.style.visibility = "visible";            }            ++activeRequests;        });        DWREngine.setPostHook(function() {            --activeRequests;            if(!activeRequests) {                disabledZone.style.visibility = "hidden";                messageZone.style.visibility = "hidden";            }        });    };    })();  
 
 
 
 
 
 
 
 
 
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表