• 浅谈JavaScript的事件(事件模拟)


      事件经常由操作或者通过浏览器功能触发,通过JavaScript也可以触发元素的事件。通过JavaScript触发事件,也称为事件的模拟。

    • DOM中事件模拟

      可以document的createEvent方法创建event对象。这个方法接收一个参数,即表示要创建的事件类型的字符串。在DOM2级中,所有这些字符串都使用英文复数形式,在DOM3级中都变成了单数。这几个字符串如下:UIEvents,一般化的ui事件,鼠标事件和键盘事件都继承于该事件,在DOM3级中是UIEvent;MouseEvents,一般化的鼠标事件,在DOM3级中是MouseEvent;MutationEvents,DOM变动事件DOM3级是MutationEvent;HTMLEvents,html事件,没有对应的DOM3级。

      在创建了event对象后,还需要使用与事件有关的信息对其进行初始化。每种类型的event都有一个对应的方法,为其传入一个参数就可以初始化事件对象。模拟事件的最后一步是触发事件,触发事件使用dispatchEvent方法,所有支持DOM事件的节点都支持该方法。调用dispatchEvent方法需要传入一个参数,即表示要触发事件的event对象。

      创建鼠标事件对象,并为其指定必要的信息,就可以模拟鼠标事件。创建鼠标事件的对象方法是createEvent方法,传入的参数是MouseEvents。返回的event对象有一个initMouseEvent方法,用于指定与鼠标事件有关的信息。这个方法接收15个参数,分别与鼠标事件中典型的属性一一对应,属性如下:type,表示要触发的事件类型,如“click”;bubbles,是否支持冒泡,如true;cancelable,表示事件是否可以取消,如true;view,事件关联的视图,一般是document.defaultView;detail,与事件有关的详细信息,通常设置为0;screenX,事件相对于屏幕的x坐标;screenY,事件相对于屏幕的y坐标;clientX,事件相对于视口的X坐标;clientY,事件相对于视口的Y坐标;ctrlKey,表示是否按下了ctrl键,一般为false;shiftKey,表示是否按下了shit键,一般为false;metaKey,表示是否按下了meta键,一般为false;button,表示按下的是哪一个鼠标键,默认为0;relatedTarget,表示与事件相关的对象,在模拟mouseout和mouseover时使用。

      对于需要模拟鼠标事件,一般只需要传递前3个参数。

      

    1 var callback =function(event){
    2                 console.log("1");
    3             }
    4             EventUtil.addEvent(document.getElementById("btnadd"),"click",callback);
    5             var evt = document.createEvent("MouseEvents");
    6             evt.initMouseEvent("click",false,false);
    7             var btn =document.getElementById("btnadd");
    8             btn.dispatchEvent(evt);

      通过上面的事件,我们就能触发btnadd元素的click事件。首先我们为元素绑定了click事件,这个事件需要用户操作才能触发。第5行通过createEvent创建了鼠标事件对象,通过initMouseEvent初始化了事件对象。然后通过元素的dispatchEvent方法来触发事件。

      DOM2级中对键盘事件没有做出规范的规定。在DOM3级中对键盘事件有明确的定义。调用createEvent方法,传入KeyboardEvent能够创建键盘事件。返回的事件对象包含一个initKeyEvent的方法。这个方法的参数如下:type,事件类型,如keydown;bubbles,事件是否支持冒泡,如true;cancelable,事件是否可以取消,如true;view,事件的视图,一般为document.defaultView;key,表示按下键的键码;location,表示按下了哪里的键,0表示默认的主键盘,1表示左,2表示右,3表示数字键盘,4表示移动设备,5表示手柄;modifiers,空格分隔的修改键列表,如shift;repeat,按这个键的次数。

    1 var txt=document.getElementById("inputtext");
    2             txt.focus();
    3             var evt =document.createEvent("KeyboardEvent");
    4             evt.initKeyboardEvent("keydown",false,false,document.defaultView,"a",0,"Shift",0);
    5             txt.dispatchEvent(evt);

      上面的代码模拟了keydown事件,同时按下shift键和a键。

      可以通过JavaScript代码模拟鼠标事件、键盘事件、HTML事件和变动事件。同时也可以模拟自定义事件。

      

    1 var add=document.getElementById("btnadd");
    2             EventUtil.addEvent(add,"myevent",function(ev){
    3                 ev=EventUtil.getEvent(ev);
    4                 var target=EventUtil.getTarget(ev);
    5                 console.log(ev.type);//myevent
    6             });
    7             var evt=document.createEvent("CustomEvent");
    8             evt.initCustomEvent("myevent",false,false,"hello");
    9             add.dispatchEvent(evt);

      上面的代码通过createEvent方法创建了CustomEvent事件对象,也就是自定义事件对象,通过initCustomEvent初始化对象,最后触发myevent事件。第5行输出事件的类型为myevent,正是我们自定义的事件。

      上面的创建模拟事件的方法在ie8以及ie8以下的浏览器中,并不支持。可以使用以下的代码来模拟事件。

    1 var btn =document.getElementById("btnadd");
    2             EventUtil.addEvent(btn,"click",function(e){
    3                 console.log("click");
    4             })
    5             var evt=document.createEventObject();
    6             btn.fireEvent("onclick",evt);

      最后讲一下事件模拟中经常用到的一场景,比如需要下载一幅图片或者导出excel等,可以通过事件模拟来实现。

     1 function downloadImg(){
     2                 var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
     3                     var img = document.createElement("img");
     4                     img.src="Font-Awesome-3.2.1/src/assets/img/fort_awesome.jpg";
     5                     img.style.display="none";
     6                     document.body.appendChild(img);
     7                  if (userAgent.indexOf("MSIE") > -1) {
     8                       var oPop = window.open(img.src,"","width=1, height=1, top=5000, left=5000");
     9                     for(; oPop.document.readyState != "complete"; )
    10                     {
    11                         if (oPop.document.readyState == "complete")break;
    12                     }
    13                     oPop.document.execCommand("SaveAs");
    14                     oPop.close();
    15                     
    16                 }
    17                  else{
    18                  
    19                     var evt=document.createEvent("MouseEvents");
    20                     evt.initMouseEvent("click",false,false);
    21                     var a=document.createElement("a");
    22                     a.download="test.jpg";
    23                     a.href=img.src;
    24                     a.dispatchEvent(evt);
    25                  }
    26             }
    27             downloadImg();
  • 相关阅读:
    LeetCode_21.合并两个有序链表
    LeetCode_70.爬楼梯
    LeetCode_001.两数之和
    LeetCode_509.斐波那契数
    Eclipse(2019-03版本)汉化
    修改Gradle本地仓库
    解决Eclipse导入Gradle项目时在 Building gradle project info 一直卡住
    Eclipse设置字体大小
    @Transactional spring 事务(转载)
    @Transactional spring 事务失效(转载)
  • 原文地址:https://www.cnblogs.com/ggz19/p/8461448.html
Copyright © 2020-2023  润新知