javascript模拟(触发)鼠标事件

   感言:
  苦逼的程序员经常遇到种种奇怪的需求,经常要想些奇怪的方法来解决问题。

   场景:
  最近用一个插件来展示大量图片,该插件封装逻辑很复杂,文档几乎为零。要修改其代码几乎是不可能完成的任务。因此我想要手工触发一个鼠标点击事件,以此激活其内部处理代码,完成相应的操作,不修改插件的任何代码、不用阅读任何插件的代码。

  简单地触发鼠标事件很容易,如果用jQuery就更容易了: $("#container").trigger("click");

  但我需要模拟鼠标在容器的某个位置点击。仔细阅读javascript的文档,找到了激活特定位置鼠标点击事件的方法。经测试,我用的插件收到mouseDown、mouseUp两个事件、且位置没有发生变化时,就会执行我需要的操作。那么我的代码如下:

function simulateClick(){
	//点击位置为屏幕中间
	var sx= window.innerWidth/2,sy= window.innerHeight/2,cx= sx,cy=sy;
	var eventDown = document.createEvent("MouseEvents");
	eventDown.initMouseEvent("mousedown",true,true,window,0,
		sx,sy,cx,cy,false,false,false,false,0,null);
	var eventUp = document.createEvent("MouseEvents");
	eventUp.initMouseEvent("mouseup",true,true,window,0,
		sx,sy,cx,cy,false,false,false,false,0,null);
	$("#container")[0].dispatchEvent(eventDown);
	$("#container")[0].dispatchEvent(eventUp);
}


  后来又用这样方法解决了插件不支持触屏移动的问题。通过附加事件、跟踪输出,发现插件不能很好地响应touchstart、touchmove、touchend事件,其中touchmove事件直接无视,如果触屏后立即移动,那么不会触发mousedown、mousemove、mouseup事件,总之一句话,需要将touchstart/touchmove/touchend转化为mousedown/mousemove/mouseup事件。
  以上这种需要可以用自定义事件、然后触发的机制来解决。

            /**
             * event为jquery的事件。真正的事件为event.originalEvent
             * 使用新的方法处理。http://wallimn.itey.com
             */
            function touchEventToMouseEvent(event,eventType){
                if(!event.originalEvent || !event.originalEvent.targetTouches || event.originalEvent.targetTouches.length!=1)
                    return null;
                var te = event.originalEvent.targetTouches[0];
                var clientX = te.clientX,clientY=te.clientY,screenX=te.screenX,screenY=te.screenY;

                var simEvent = new MouseEvent(eventType,{clientX:clientX,clientY:clientY,screenX:screenX,screenY:screenY,button:0,buttons:0});
                return simEvent;
            }

    function findElm(){
        var elm = $(".pivot_layer[title]");
	elm.bind("touchmove",function(e){
	var simEvent = touchEventToMouseEvent(e,"mousemove");
	if(simEvent!=null){
	    $(this)[0].dispatchEvent(simEvent);
	}
	});
	elm.bind("touchstart",function(e){
	console.log("touchstart");
	var simEvent = touchEventToMouseEvent(e,"mousedown");
	if(simEvent!=null){
	    $(this)[0].dispatchEvent(simEvent);
	}
	});
	elm.bind("touchend",function(e){
	console.log("touchend");
	var simEvent = touchEventToMouseEvent(e,"mouseup");
	if(simEvent!=null){
	    $(this)[0].dispatchEvent(simEvent);
	}
	});
        }
    }
    $(function(){
        findElm();
    });



  注:initMouseEvent是个将要废弃的方法,推荐使用new MouseEvent()方法来代替。上述代码基于jQuery插件。

猜你喜欢

转载自wallimn.iteye.com/blog/2358847
今日推荐