HTML5:百度地圖手機端單觸點單擊和長按事件置蜀,解決部分手機點地圖擊失效,多觸點悉盆、拖動依然觸發(fā)長按的bug


/**
 *
 * 對百度地圖的事件擴展盯荤,目前擴展了fastclick和longclick,
 * 解決某些設備click不執(zhí)行的問題
 * 解決長按事件在拖動、多觸點依然執(zhí)行的bug
 * v1.0.0
 */
require('baiduMap');
(function(){
    BMap.Map.prototype.on=function(evt,fn,option){
        var _option = {
            canBubble:true
        }

        extend(_option,option)

        if(!evt || !fn) return;


        var $this = this;
        var evtList = ["longtouch","onetouch"];
        if(inArray(evt,evtList)){
            MesureEvents[evt]($this,evt,fn,option);
            $this.getContainer().querySelector("div.BMap_mask").addEventListener(evt,fn);
        }
        else{
            $this.addEventListener(evt,fn);
            /*function(e){
                if(option.canBubble){
                    e.domEvent.stopPropagation();
                }
                fn.call(this,e);
            });*/
        }
    };

    var centerAndZoom = BMap.Map.prototype.centerAndZoom;

    BMap.Map.prototype.centerAndZoom  = function(){

        var $this = this;
        centerAndZoom.apply(this,arguments);
        if(!$this.hasRegistMyTouch){
            $this.on("onetouch",function(e){
                //console.log(e);
                var event = document.createEvent("MouseEvent");
                event.initEvent("fastclick",true,true);



                event.clientX = e.clientX;
                event.clientY = e.clientY;
                event.point = e.point;
                $this.dispatchEvent(event);

                var event = document.createEvent("MouseEvent");
                event.initEvent("click",true,true);
                event.clientX = e.clientX;
                event.clientY = e.clientY;
                $this.dispatchEvent(event);
            });
            $this.on("longtouch",function(e){
                //console.log(e);
                var event = document.createEvent("TouchEvent");
                event.initEvent("longclick",true,true);
                event.clientX = e.clientX;
                event.clientY = e.clientY;
                event.point = e.point;
                $this.dispatchEvent(event);
            });
            $this.hasRegistMyTouch = true;
        }

    }
    var MesureEvents = {
        onetouch:function($this,evt,fn,data,option){
            var ismoved;
            var time = null;
            var touchLocation = null;
            var maxTouchesCount = 0;

            var container = $this.getContainer();
            var mask = container.querySelector("div.BMap_mask");
            var panes = $this.getPanes();

            $this.addEventListener("touchstart",function(e){

                var temp = Math.max(maxTouchesCount,e.touches.length);
                if(temp==1) {
                    var touch = e.changedTouches[0];

                    if(isAncestors(touch.target,[panes.floatPane,panes.markerMouseTarget,panes.markerPane],container)) return;

                    maxTouchesCount = temp;

                    touchLocation = {
                        x:touch.clientX,
                        y:touch.clientY
                    };
                    time = new Date().getTime();
                }
            });
            $this.addEventListener("touchmove",function(e){
                maxTouchesCount = Math.max(maxTouchesCount,e.touches.length);

                if(maxTouchesCount==1) {
                    var touch = e.changedTouches[0];

                    if(isAncestors(touch.target,[panes.floatPane,panes.markerMouseTarget,panes.markerPane],container)) return;


                    if(Math.abs(touchLocation.x-touch.clientX)>0 && Math.abs(touchLocation.y-touch.clientY)>0){//解決部分手機對touchmove過分“敏感”的問題
                        ismoved = true;
                        //console.log("touchmove---");
                    }
                    else{
                        ismoved = false;
                    }
                }
            });
            $this.addEventListener("touchend",function(e){

                var touches =e.touches.length;

                if(touches==0){

                    var touch = e.changedTouches[0];

                    if(isAncestors(touch.target,[panes.floatPane,panes.markerMouseTarget,panes.markerPane],container)) return;


                    var temp = maxTouchesCount;
                    var tempM = ismoved;
                    ismoved= false;
                    maxTouchesCount = 0;
                    if(temp==1 && !tempM /*&& /BMap_mask/.test(e.srcElement.className)*/ && new Date().getTime()-time<500){

                        var event = document.createEvent("Event");
                        event.initEvent("onetouch",true,true);
                        var touch = e.changedTouches[0];

                        event.clientX = touch.clientX;
                        event.clientY = touch.clientY;
                        event.point =calLngLat($this,event.clientX,event.clientY);
                        mask.dispatchEvent(event,fn);
                    }
                }
            });
        },
        longtouch:function($this,evt,fn,data,option){
            var ismoved;
            var time = null;
            var timeout;
            var maxTouchesCount = 0;
            var touchLocation = null;
            var container = $this.getContainer();
            var mask = container.querySelector("div.BMap_mask");
            var panes = $this.getPanes();
            $this.addEventListener("touchstart",function(e){

                var temp = Math.max(maxTouchesCount,e.touches.length);
                if(temp==1) {
                    var touch = e.changedTouches[0];

                    if(isAncestors(touch.target,[panes.floatPane,panes.markerMouseTarget,panes.markerPane],container)) return;

                    maxTouchesCount = temp;

                    touchLocation = {
                        x:touch.clientX,
                        y:touch.clientY
                    };
                    time = new Date().getTime();
                    timeout = setTimeout(function(){

                        clearTimeout(timeout);
                        timeout = null;
                        longtouch(e);
                    },750);
                }
            });
            $this.addEventListener("touchmove",function(e){
                maxTouchesCount = Math.max(maxTouchesCount,e.touches.length);
                if(maxTouchesCount==1) {
                    var touch = e.changedTouches[0];

                    if(isAncestors(touch.target,[panes.floatPane,panes.markerMouseTarget,panes.markerPane],container)) return;

                    //console.log("move:" +touch.clientX +"," + touch.clientY);
                    if(Math.abs(touchLocation.x-touch.clientX)>=2 && Math.abs(touchLocation.y-touch.clientY)>2){//解決部分手機對touchmove過分“敏感”的問題
                        ismoved = true;
                        //console.log("touchmove---");
                        if(timeout){
                            clearTimeout(timeout);
                            timeout = null;
                        }
                    }
                    else{
                        ismoved = false;
                    }
                }
                else{
                    if(timeout){
                        clearTimeout(timeout);
                        timeout = null;
                    }
                }
            });

            function longtouch(e){
                var temp = maxTouchesCount;
                var tempM = ismoved;
                ismoved= false;
                maxTouchesCount = 0;
                if(temp==1 && !tempM){

                    var event = document.createEvent("Event");
                    event.initEvent("longtouch",true,true);
                    var touch = e.changedTouches[0];

                    event.clientX = touch.clientX;
                    event.clientY = touch.clientY;
                    event.point =calLngLat($this,event.clientX,event.clientY);
                    $this.getContainer().querySelector("div.BMap_mask").dispatchEvent(event);

                }
            }

            $this.addEventListener("touchend",function(e){

                var touches =e.touches.length;

                if(touches==0){

                    var touch = e.changedTouches[0];

                    if(isAncestors(touch.target,[panes.floatPane,panes.markerMouseTarget,panes.markerPane],container)) return;

                    maxTouchesCount = 0;
                    ismoved= false;
                }
                if(new Date().getTime()-time<1000){
                    if(timeout){
                        clearTimeout(timeout);
                        timeout = null;
                    }
                }
            });
        }
    }

    function calLngLat($this,x,y){
        var container = $this.getContainer();
        var rect = container.getBoundingClientRect();
        var y = y - rect.top;
        var x = x - rect.left;
        var bounds = $this.getBounds();
        var lefTop = new BMap.Point(bounds.getSouthWest().lng,bounds.getNorthEast().lat);
        var lefTopPix = $this.pointToPixel(lefTop);
        var pix = new BMap.Pixel(lefTopPix.x + x,lefTopPix.y+y);
        var point = $this.pixelToPoint(pix);
        return point;
    }

    function inArray(obj,array){
        for(x in array){
            if(obj==array[x]) return true;
        }
        return false;
    }

    function extend(o1,o2){
        if(o1 && o2){
            for(x in o2){
                if(o2.hasOwnProperty(x) && o2[x]!=undefined){
                    o1[x] = o2[x];
                }
            }
        }
    }

    function isAncestors(element,nodes,root){
        var p = element;
        while(p && p!=root){
            if(inArray(p,nodes)){
                return true;
            }
            p = p.parentElement;
        }
        return false;
    }

})(BMap);

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末焕盟,一起剝皮案震驚了整個濱河市秋秤,隨后出現的幾起案子,更是在濱河造成了極大的恐慌脚翘,老刑警劉巖灼卢,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異来农,居然都是意外死亡鞋真,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門备图,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灿巧,“玉大人赶袄,你說我怎么就攤上這事揽涮。” “怎么了饿肺?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵蒋困,是天一觀的道長。 經常有香客問我敬辣,道長雪标,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任溉跃,我火速辦了婚禮村刨,結果婚禮上,老公的妹妹穿的比我還像新娘撰茎。我一直安慰自己嵌牺,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著逆粹,像睡著了一般募疮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上僻弹,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天阿浓,我揣著相機與錄音,去河邊找鬼蹋绽。 笑死芭毙,一個胖子當著我的面吹牛,可吹牛的內容都是我干的卸耘。 我是一名探鬼主播稿蹲,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鹊奖!你這毒婦竟也來了苛聘?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤忠聚,失蹤者是張志新(化名)和其女友劉穎设哗,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體两蟀,經...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡网梢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了赂毯。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片战虏。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖党涕,靈堂內的尸體忽然破棺而出烦感,到底是詐尸還是另有隱情,我是刑警寧澤膛堤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布手趣,位于F島的核電站,受9級特大地震影響肥荔,放射性物質發(fā)生泄漏绿渣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一燕耿、第九天 我趴在偏房一處隱蔽的房頂上張望中符。 院中可真熱鬧,春花似錦誉帅、人聲如沸淀散。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吧凉。三九已至隧出,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間阀捅,已是汗流浹背胀瞪。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留饲鄙,地道東北人凄诞。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像忍级,于是被迫代替她去往敵國和親帆谍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內容