淡定啊淡定

一些前端效果在dom的事件处理上比较啰嗦,而公司的framework乃至browser也总是出一些奇特的现象。。

于是bug出现了,改着改着就不淡定了。。

事实证明必须淡定,不淡定你永远没能力!

首先把自己写的代码逐一检查,必要时jshint发现一些语法上不规范的地方,比如循环内部不该干的事(= =;;)

然后把整体划分为各个功能性逻辑,比如计数是否准确?是否有必要阻挡冒泡?

如果确认了每部分代码都是正确的而结果不正确,那一定是时序出了问题。

如果时序也没有问题,可是事件的响应有些失控。。必要时下一些不太干净的狠手段,比如加flag。。

下面我模拟drag事件的时候就用一个flag阻断了多余的touchmove,在touchstart时还原。

否则我每拖一次,touchmove响应N多次,次数还不一定。

很难判断是用框架绑定时间的问题,还是其他问题。

一时得不到解决,或者说根本没人来解决,只有自己屏蔽了。

itu.xcontrol.define("tabMain", {

    views: ["tabMain.html"],
    _fnOnTouchStart: null,
    _fnOnTouchMove: null,
    _fnOnTouchEnd: null,
    _touchStartPosX: null,
    _touchStartPosY: null,

    constructor: function() {
        try {
            var me = this;
            me._fnOnTouchStart = iAuto.Util.bind(me, me._onTouchStart);
            me._fnOnTouchMove = iAuto.Util.bind(me, me._onTouchMove);
            me._fnOnTouchEnd = iAuto.Util.bind(me, me._onTouchEnd);

        } catch (e) {
            iAuto.Logger.error(e.stack);
        }
    },
    config: {

    },
    titles: ".titles",
    divs: "#tabMain_div",
    press: "pressed",
    left: "fromleft",
    right: "fromright",
    pop: "#tabMain_popularlist1",
    channel: "#tabMain_channelslist1",
    playlist: "#tabMain_playlists1",
    CUR: 1,
    tabs: ".tabs",
    TAB: "#tabMain_tabs",
    NONE: "none",
    isdoing: "false",

    onCreate: function() {
        this.setView("tabMain.html", {});
    },

    _createCmp_: function() {
        itu.xcontrol.create('popularList', 'tabMain_popularlist1', {});
        itu.xcontrol.create('channelsList', 'tabMain_channelslist1', {});
        itu.xcontrol.create('playLists', 'tabMain_playlists1', {});
    },

    _bindEvent_: function() {
        var me = this;
        itu.event.addListener('tabMain_popularlist1', {
            'name': 'popularList_pressed',
            'callback': me.on_tabMain_popularlist1_popularList_pressed,
            'context': me
        });
        itu.event.addListener('tabMain_channelslist1', {
            'name': 'channelsList_pressed',
            'callback': me.on_tabMain_channelslist1_channelsList_pressed,
            'context': me
        });
        itu.event.addListener('tabMain_playlists1', {
            'name': 'playList_pressed',
            'callback': me.on_tabMain_playlists1_playList_pressed,
            'context': me
        });
    },

    bindEvents: function() {
        try {
            var me = this;
            var $el = me.$element;
            var $titles = $el.find(me.titles);
            var $tab = $el.find(me.tabs);
            $tab.bind('touchstart', me._fnOnTouchStart);
            $tab.bind('touchmove', me._fnOnTouchMove);
            $tab.bind('touchend', me._fnOnTouchEnd);
            itu.event.on($titles, "touchstart", me.animateIn, me);
            itu.event.on($titles, "touchend", me.triggerTitles, me);
            for (var i = 1; i < 4; i++) {
                $(me.divs + i).attr("data-num", i);
            }
        } catch (e) {
            iAuto.Logger.error(e.stack);
        }
    },

    unbindEvents: function() {
        try {
            var me = this;
            var $el = me.$element;
            var $titles = $el.find(me.titles);
            var $tab = $el.find(me.tabs);
            $tab.unbind('touchstart');
            $tab.unbind('touchmove');
            $tab.unbind('touchend');
            itu.event.off($titles, "touchstart");
            itu.event.off($titles, "touchend");

        } catch (e) {
            iAuto.Logger.error(e.stack);
        }
    },

    animateIn: function(evt) {
        var me = this;
        var n = parseInt($(evt.target).data("num"));
        iAuto.Logger.log("[tabMain] num is:::", n);
        me.activeTitle(n);
        me.CUR = n;
    },

    triggerTitles: function(evt) {
        var me = this;
        var $el = me.$element;
        var id = $(evt.target).data("num");
        $el.trigger("title" + id + "_pressed");
    },

    onShow: function() {
        iAuto.Logger.log("[tabMain] onShow");
        var me = this;
        me.bindEvents();
    },

    onHide: function() {
        iAuto.Logger.log("[tabMain] onHide");
        var me = this;
        me.unbindEvents();
    },

    on_tabMain_popularlist1_popularList_pressed: function(evt) {
        // TODO Auto-generated method stub
        var me = this, $el = me.$element;
        var id = evt.data;
        me.CUR = 1;
        $el.trigger("popular_pressed", id);
    },

    on_tabMain_playlists1_playList_pressed: function(evt) {
        // TODO Auto-generated method stub
        var me = this, $el = me.$element;
        var id = evt.data;
        me.CUR = 2;
        $el.trigger("playlist_pressed", id);
    },

    on_tabMain_channelslist1_channelsList_pressed: function(evt) {
        // TODO Auto-generated method stub
        var me = this, $el = me.$element;
        var id = evt.data;
        me.CUR = 3;
        $el.trigger("channel_pressed", id);
    },
    setTitles: function(arr) {
        var me = this;
        var titles = arr;
        for (var i = 0; i < titles.length; i++) {
            $(me.divs + (i + 1)).html(titles[i] + '<div id="" class="span" style=""></div>');
        }
    },
    showPop: function(data) {
        var me = this;
        var item = data;
        var pop = me.getCmp("tabMain_popularlist1");
        pop.update(item);
        $(me.channel).hide();
        $(me.playlist).hide();
        $(me.pop).show();
    },
    showChannel: function(data) {
        var me = this;
        var item = data;
        var channel = me.getCmp("tabMain_channelslist1");
        channel.update(item);
        $(me.playlist).hide();
        $(me.pop).hide();
        $(me.channel).show();
    },
    showPlaylist: function(data) {
        var me = this;
        var item = data;
        var playlist = me.getCmp("tabMain_playlists1");
        playlist.update(item);
        $(me.channel).hide();
        $(me.pop).hide();
        $(me.playlist).show();
    },
    _onTouchStart: function(evt) {
        try {
            var me = this;
            if (evt.touches.length === 1) {
                me._touchStartPosY = parseInt(evt.touches[0].pageY);
                me._touchStartPosX = parseInt(evt.touches[0].pageX);
                evt.stopPropagation();
                me.isdoing = false;
            }
        } catch (e) {
            iAuto.Logger.error(e.stack);
        }
    },

    _onTouchMove: function(evt) {
        try {
            var me = this;
            var $el = me.$element;
            var currentPositionX = parseInt(evt.touches[0].pageX);
            var currentPositionY = parseInt(evt.touches[0].pageY);
            var offsetX = currentPositionX - me._touchStartPosX;
            var offsetY = currentPositionY - me._touchStartPosY;

            if (Math.abs(offsetY) > 30) {
                if (me.scroller !== null) {
                    itu.event.on(me.scroller, "scrollend", me.refreshMore, me);
                }
                return;
            }
            var isLeft = (Math.abs(offsetY) / Math.abs(offsetX) < 0.33) && offsetX < 0;
            var isRight = (Math.abs(offsetY) / Math.abs(offsetX) < 0.33) && offsetX > 0;
            if (isRight) {
                if (me.isdoing === true) {
                    return;
                }
                iAuto.Logger.log("[tabMain] _onTouchMove currentPositionX", currentPositionX);
                iAuto.Logger.log("[tabMain] _onTouchMove touchStartPosX", me._touchStartPosX);
                me.CUR--;
                if (me.CUR < 1) {
                    me.CUR = 3;
                }
                $el.trigger("title" + me.CUR + "_pressed");
                me.activeTitle(me.CUR);
                iAuto.Logger.log("[tabMain] go right CUR:::after", me.CUR);
                me.isdoing = true;
            }
            if (isLeft) {
                if (me.isdoing === true) {
                    return;
                }
                iAuto.Logger.log("[tabMain] _onTouchMove currentPositionX", currentPositionX);
                iAuto.Logger.log("[tabMain] _onTouchMove _touchStartPosX", me._touchStartPosX);
                me.CUR++;
                if (me.CUR > 3) {
                    me.CUR = 1;
                }
                $el.trigger("title" + me.CUR + "_pressed");
                me.activeTitle(me.CUR);
                iAuto.Logger.log("[tabMain] go left CUR:::after", me.CUR);
                me.isdoing = true;
            }
        } catch (e) {
            iAuto.Logger.error(e.stack);
        }
    },
    _onTouchEnd: function(evt) {
        try {
            var me = this;
            if (me.scroller !== null) {
                itu.event.off(me.scroller, "scrollend");
                iAuto.Logger.log("[tabMain] _onTouchEnd scrollend disabled");
            }
        } catch (e) {
            iAuto.Logger.error(e.stack);
        }
    },
    refreshMore: function(x, y) {
        var me = this;
        var $el = me.$element;
        var contentHeight = parseInt($(".c-scroller__scroller-content").css("height"));
        var scrollerHeight = parseInt($(".c-scroller").css("height"));
        var scrollerMaxY = contentHeight - scrollerHeight;
        if (y >= scrollerMaxY && scrollerMaxY > 0) {
            iAuto.Logger.log("[tabMain]:scrollMore loading more contents... ");
            $el.trigger("loadMore", me.CUR);
        } else if (y <= 0) {
            $el.trigger("refresh", me.CUR);
            iAuto.Logger.log("[tabMain]:scrollMore refreshing more contents... ");
        }
    },
    activeTitle: function(_n) {
        var me = this;
        var $el = me.$element;
        var n = _n;
        $el.find(me.titles).removeClass(me.press);
        $(me.divs + n).addClass(me.press);
    }
});

话说这段代码的初版是很惨不忍睹的。

花了几个小时时间几近绝望,但总算hold住了。

多处参考别人的处理(有些需求或者dom没这么复杂,有些堪称lib高端大气上档次看懂都难)。

总归吸取正能量。。比如用Y和X的比例小于0.33来屏蔽一些斜向滑动。

最后控制出来的效果很满意,很有成就感。

原文地址:https://www.cnblogs.com/haimingpro/p/5072631.html