提子干
提子干
  • 发布:2016-01-19 17:58
  • 更新:2018-07-18 22:37
  • 阅读:30415

不要使用mui.plusReady() !!!!

分类:MUI
mui

H5+ 和 HBUILDER 都非常好,我们公司也在使用其作为项目开发,效果不错,也尝试MUI作为界面层开发,BUT,我着重地说BUT!MUI在界面上清爽、简单、效率高,但其自带的API除了API文档不全外,MD,还有不少BUG,不成熟,我发现如果直接用 H5+ 的 document.addEventListener('plusready', fn) 在加载时是没有问题的,但使用mui.plusReady加载却不定时没有被加载问题,发现mui加载是比H5要延迟和有问题!希望开发团队注意。

// common.js APP公用函数对象  
document.addEventListener('plusready', lib_init);  

var $GOODS_DAO, $PLAN_DAO, $USER_DAO, $SHOPS_DAO, $STATIS_DAO, $ORDERS_DAO, $NEWS_DAO, $FRIENDS_DAO, $MESSAGES_DAO;  

function lib_init() {  
    /*  
     * 商品操作对象函数  
     */  
    $GOODS_DAO = {  

        /*  
         * 记录商品  
         * @param goods: 商品数组JSON Object  
         * @return Boolen 成功与否  
         */  
        record: function(goods) {  
            var goods_orgin = plus.storage.getItem('goods');  

            if(!goods_orgin) {  
                plus.storage.setItem('goods', JSON.stringify(goods));             
            }else {  
                goods_orgin = JSON.parse(goods_orgin);  
                for(var key in goods) {  
                    goods_orgin[key] = goods[key]; //没有则新增,有则更新  
                }  
                plus.storage.setItem('goods', JSON.stringify(goods_orgin));  
            }  

            return true;  
        }

云滋味老板APP内部泄露版

2016-01-19 17:58 负责人:无 分享
已邀请:
小明媛媛

小明媛媛

mui.plusready,的确是延迟呀。我用 addEventListener 的确比 mui.plusready快,mui加载是比H5要延迟和有问题。+1

  • 提子干 (作者)

    的确,在同样的plusready 事件中进行页面预加载,或者全app的预加载,好明显H5+的速度快很多,而且不会出现有时候没有加载的情况

    2016-01-19 22:43

maq

maq

看了上面的内容,基本上问题已经清楚了。

官方代码唯一可以说的问题就是没有 guarantee 多个 plusReady 的执行顺序,其实这算不上是 BUG,更多的是在于用户程序的编写习惯,有依赖关系的代码就应该用更明确的方式来保障执行顺序。

顺便说一下,第一次看见官方人员对一个帖子的问题如此密集地跟进,赞一个!

  • 云海帆

    恭喜,不过回答的大部分是水友,现在水友水平很高了 :)

    2016-01-20 22:44

DCloud_UNI_FXY

DCloud_UNI_FXY

能否发一下可以重现的测试工程。
并描述问题出现的环境,是所有手机都有该现象,还是特定机型,特定系统出现的

  • 提子干 (作者)

    IOS 9.2,简单陈述下情况,有一个共用common.js 用于plus.storage的各种对象操作,例如用户、新闻、商品等的数据CRUD(例如$USER_DAO.get()),然后页面会使用 <script src='common.js' 加载使用,好了,困扰我几天的问题来了,在 mui.plusReady里使用 $USER_DAO.get() ,竟然提示$USER_DAO不存在!而且不是每次都是,而是不定时!出现有时候页面加载快点时就正常,有时候慢点就绝对不正常!我就觉得奇怪,没可能已经引用了,却提示没有这个对象,然后我今天换了document.addEventListener('plusready', fn)来加载,一切正常,而且速度快了很多。。。。

    2016-01-19 22:57

  • maq

    调用 mui.plusReady 的代码不在 common.js 里面吧?它们的关系是怎样的?(在 html 里面的书写顺序)

    2016-01-20 09:49

  • DCloud_UNI_FXY

    回复 提子干:你是真机联调的时候调整代码,然后手机自动刷新,测试的、还是每次都是重新运行测试的?建议重新运行测试,只要你的common.js引用在你的mui.plusReady代码之前,那么$USER_DAO不存在跟plusReady就没有任何关系。有可能的就是因为真机联调,自动刷新页面等操作导致环境不一致。

    2016-01-20 15:10

  • 提子干 (作者)

    回复 maq:common.js里有调用plusready,但这个应该不影响的,因为js都在</body>前引用,而且plusready可以加入多个function,页面内连同引用的js,总共调用过两次plusready

    2016-01-20 15:51

  • 提子干 (作者)

    回复 DCloud_UNI_FXY:common.js有调用plusready,不调用无法调用plus.storage,可以用localStorage,但有容量限制,所以我弃用了,手动刷新试过,重新运行也试过,的确出现此问题,而且是出现在DOM要加载多的时候,不间断发生

    2016-01-20 15:53

  • 提子干 (作者)

    回复 DCloud_UNI_FXY:我现在全部换成document.addEventListener('plusready' 就完全正常了,所以你们真的要看看是什么问题,要么去除mui.plusReady的使用

    2016-01-20 15:54

  • DCloud_UNI_FXY

    回复 提子干:发测试工程。应该是使用上的问题。$USER_DAO如果是在common.js里边全局定义的。而且在调用mui.plusReady之前就引用了。那根本不可能出现在plusReady内访问不到$USER_DAO,这是基本的js常识,跟mui没关系,除非真机联调时因为自动刷新,影响了整个运行环境。

    2016-01-20 16:01

  • 提子干 (作者)

    回复 DCloud_UNI_FXY:如上原文添加的代码:你将plusready换成mui.plusReady就有问题了

    2016-01-20 16:19

  • DCloud_UNI_FXY

    回复 提子干:你是在真机联调,边改代码,边看效果时发现的,还是直接运行,不改代码时发现的。

    2016-01-20 16:24

  • 提子干 (作者)

    回复 DCloud_UNI_FXY:两种都试过,两种都出现问题,是不定时出现

    2016-01-20 16:52

  • DCloud_UNI_FXY

    回复 提子干:你改下mui的源码,把window.plus底下的setTimeout去掉,直接callback试试,还有没有类似现象

    2016-01-20 17:05

  • 提子干 (作者)

    回复 DCloud_UNI_FXY:如果是这样的话,其实就是直接调用H5的plusready了,源码我就不修改了,直接H5+的好,只是告诉大家一下经验和你们,然后我也发现了,其实mui.init()没什么用,我没有运行都很正常

    2016-01-20 20:14

  • DCloud_UNI_FXY

    回复 提子干: plusReady只是为了确保plus的环境已经ready了。目前的设计并未考虑多个plusReady一定会顺序执行,比如你的情况,先通过plusReady来初始化一些全局变量,然后在其他plusReady里边调用。有可能因为timeout的执行时机问题,导致后续plusReady先执行了。对于你的问题,你在common.js里边可以直接初始化你的DAO,无需等plusReady,因为后续对DAO的调用都是在plusReady里边调用的。已经保证了plus存在了。

    2016-01-20 20:28

  • 提子干 (作者)

    回复 DCloud_UNI_FXY: 嗯,估计我在刚刚也已经找到这个问题原因了,正如你所说,就是mui源代码中使用了setTimeout(fn, 0)所导致的执行时机,setTimeout导致了plusReady里的fn有时执行了两次,我刚实现的左滑删除列表中的JS代码中,发现了你们官方的源代码使用了setTimeout(fn, 0),当左滑删除列表有两项以上就出现了两次是否删除的对话框,不使用setTimeout就没问题了,估计mui.plusReady也是这样导致的,你们可以试一下,我们第三方使用不会太研究你们源代码,但如果使用上经常出现奇怪问题,就会感觉不成熟

    2016-01-20 21:40

  • DCloud_UNI_FXY

    回复 提子干:setTimeout只是为了把操作放到异步里,跟执行两次没关系,你执行两次弹出,应该是绑定事件的问题

    2016-01-20 21:48

  • 提子干 (作者)

    回复 DCloud_UNI_FXY:我也找到为何会发生这个弹出对话框的问题了。。。。mui('#news-list').on('tap', '.mui-btn', fn) 原来mui这个动作绑定方法是可以自动绑定到相应的动态加载 的dom!!!!所以我在动态添加的dom上无需继续addEventListener!!!兄弟啊~API文档能否说更详细清楚点啊~

    2016-01-20 22:47

  • DCloud_UNI_FXY

    回复 提子干:on方法是事件委托,事件委托的意思就是支持动态元素的事件,比如jQuery的on方法

    2016-01-20 22:53

  • 提子干 (作者)

    回复 DCloud_UNI_FXY:嗯,经过实践调试,我也明白了,谢谢回答!不过望官方能将相关文档尽可能详细,或者奖励民间完善文档,请个人专门文档也好,更多用户是零基础,所以不能太多深入了解和尝试,最后在原文附上我们项目的截图,由于涉及机密,不能展现更多,很快会上线,希望上线后能成为DCloud的一个经典案例!请原谅我在此做下广告,谢谢你们提供的技术支持!

    2016-01-20 23:10

云海帆

云海帆 - 咨询问题请+Q1395641578

无聊翻了下mui源码
plusReady 和addEventListender 毫无区别啊.... 是不是幻觉了

/**  
     * plusReady  
     * @param {type} callback  
     * @returns {_L6.$}  
     */  
    $.plusReady = function(callback) {  
        if (window.plus) {  
            setTimeout(function() { //解决callback与plusready事件的执行时机问题(典型案例:showWaiting,closeWaiting)  
                callback();  
            }, 0);  
        } else {  
            document.addEventListener("plusready", function() {  
                callback();  
            }, false);  
        }  
        return this;  
    };
  • maq

    这么明显的区别……

    2016-01-20 09:41

  • 提子干 (作者)

    好明显的区别,好不。。。。做了这个判断,还不如我自己来解决执行时机问题

    2016-01-20 09:51

  • 云海帆

    回复 提子干: 我理解如果你是在html最前面调用,一定进入else分支的; 除非你在Plus ready之后调用,那么延迟是必须的吧

    2016-01-20 09:54

  • 提子干 (作者)

    回复 云海帆:我想问一下plus是什么时候ready的?是mui.js装载完?还是html dom全部加载完后再plusready?

    2016-01-20 10:05

  • 云海帆

    我觉得顺序是dom, js, plusReady。 不是很确定,可以做个实验验证下。

    2016-01-20 11:10

  • 提子干 (作者)

    回复 云海帆:估计就是这个原因,mui.plusReady是在最后加载,而H5+ 的plusready则不是,估计就是这个导致

    2016-01-20 15:56

  • maq

    的确 mui.plusReady 触发的时机更靠后一些。不过,应该是越靠后越安全哪,而你描述的问题现象却是【在 mui.plusReady里使用 $USER_DAO.get() ,竟然提示$USER_DAO不存在!】,这就奇怪了。

    2016-01-20 17:42

  • 提子干 (作者)

    回复 maq:是很奇怪,我也觉得奇怪,而且是不定时发生,估计是dom装载多了就会这样

    2016-01-20 20:16

风云酷小子

风云酷小子 - 苦逼的全栈

宫留留

宫留留

学习到了

  • tyswk

    有些机型的确有问题

    2018-07-19 08:23

该问题目前已经被锁定, 无法添加新回复