JavaScript模拟用户单击事件

简介:
公司项目想要实现一种功能:

单击一个按钮或超链接,然后会出现其他的超链接,这时要让其中的一个超链接被单击,以显示一个初始页面。(公司页面使用了frameset) 
很显然,之后的超链接单击事件需要通过JavaScript来触发。 
一开始,我想到了用jQuery的click()事件来触发超链接的单击事件(与trigger("click")一样的效果)。结果发现不如人意。 
实例如下: 
效果图 
IE: 
寰愭柊鍗巔olaris
FireFox: 
寰愭柊鍗巔olaris
Html代码 
< h3 >请单击”Click Me"。测试提交按钮与超链接是否也被单击了。 </h3> 
   < button  id ="btn" >Click Me </button> 
   < form  action ="#" > 
     < input  type ="text"  name ="userName"  value ="徐新华-polaris" readonly /> 
     < input  id ="submit"  type ="submit"  value ="别点击此按钮提交"  onclick ="alert('触发了提交按钮的单击事件!');" /> 
   </form> 
   < a  id ="aLink"  href ="http://www.google.cn" onclick = "alert('触发了超链接的单击事件!');" >代码触发超链接 </a>
 
Javascript代码
$( function() 

  $( "#btn").click( function() 
  { 
    $( "#submit").click(); 
    $( "#aLink").click(); 
  }); 
});

当单击:Click Me按钮时,先后弹出提交按钮被单击、超链接被单击的对话框,这表明两者的单击事件都被触发了。然而,从地址栏中可以看到,提交按钮的单击事件触发后,执行了它的默认行为:提交表单;可是超链接的单击事件触发后,并没有链接到目标地址。(不要怀疑说是提交按钮的提交地址对超链接有影响,因为我去掉提交按钮,只留下超链接也不会链接到目标地址。) 
也许jQuery中的click()方法对超链接的单击事件并没有使其执行浏览器的默认行为(即使你手动加入return true也没有用)。注意:tigger("click")与click()一样的。jQuery文档中说“这个函数也会导致浏览器同名的默认行为的执行”。同名的?不太明白,但是超链接的确不能执行它的默认行为。这是,只能想另外的方法——抛弃jQuery提供的事件。 
回到JavaScript自己的事件——click。代码如下:
Javascript代码
$( function() 

  $( "#btn").click( function() 
  { 
    $( "#submit").click(); 
    $( "#aLink").get(0).click(); 
  }); 
});

在IE中一测试,通过了……有点兴奋。可是,在fireFox中却提示:click()不是一个function。说真的,IE浏览器提供的东西对开发人员来说很好,而fireFox却没有,比如之前说到的onpropertychange等。不过,我们必须的考虑IE之外的浏览器。在网上查资料,有不少人提到在fireFox中要用代码触发一个事件,需要如下处理:
Javascript代码
var evt = document.createEvent( "MouseEvents"); 
evt.initEvent( "click"falsefalse); // 或用initMouseEvent(),不过需要更多参数 
$( "#aLink").get(0).dispatchEvent(evt);

按以上方法来实现我想要的功能,代码如下:
Javascript代码
$( function() 

  $( "#btn").click( function() 
  { 
    $( "#submit").click(); 

     if($.browser.msie) 
    { 
      $( "#aLink").get(0).click(); 
    } 
     else 
    { 
       var evt = document.createEvent( "MouseEvents"); 
      evt.initEvent( "click"falsefalse); 
      $( "#aLink").get(0).dispatchEvent(evt);    
    } 
  }); 
});

这时,在IE中是完全正常的。然而,在fireFox中的情况与直接使用jQuery的click()事件一样,能触发单击事件,超链接却没有转到目标地址(注意:提交按钮用此方法也是能够提交的,我想jQuery的click()的实现大概是这样实现的吧)。哎,觉得还是IE好。呵呵。 
如此一来,这种方法仍然不能解决FireFox中的问题。得继续寻找其他方法。 
既然在fireFox中能够触发单击事件,却不能转到超链接的目标地址,那么,可以用js来实现跳转,即:使用location对象。代码如下:
Javascript代码
$( function() 

  $( "#btn").click( function() 
  { 
    $( "#submit").click(); 

     if($.browser.msie) 
    { 
      $( "#aLink").get(0).click(); 
    } 
     else 
    { 
       // 绑定单击事件 
      $( "#aLink").click( function() 
      { 
        document.location = $( this).attr( "href"); // window.location = $(this).attr("href");也可以,但是执行的时间不同 
      }); 
        
       // 触发单击事件 
      $( "#aLink").click(); 
    } 
  }); 
});

这样就大功告成。有一个地方要说明一下:document.location与window.location。这两个都可以,然而他们的执行时间不同,window的执行时间较早。读者可以自己试试。 
虽然实现了这个例子,然而,运用到项目中却出问题了,因为项目中使用了frameset(虽然现在很多人不建议使用frameset,但项目用了也没办法,得这样做)。因此需要指定链接的目标url在哪个frame中显示,然而,通过<a>中的target是无法实现的,因为<a>根本不会执行默认行为,需要通过js来实现。 
我们知道,document代表当前的页面(当前执行元素所在页面)。如果我们能够找到当前超链接的url希望放入的frame,我们就可以找到它对象的document。当然找到超链接url希望放入的frame很容易,这是由你自己决定将其放到哪的。示例代码如下:
Javascript代码
window.parent.frames['view'].document.location = $( "#aLink").attr( "href");    

其中,'view'是超链接url希望放入的frame的name或id(最好是id和name命名一样)。建议IE中别用上面的方法,而用前面介绍的click()方法。 
现在已经解决了所有的问题。可能还有人会有这种需求:就是在<a>中写上target,如<a target="_blank"></a>之类的。希望按target的要求触发超链接。当然,这是非IE浏览器有的问题。 
实际上,下面我要介绍的方法是通用行的。可以替代window.parent.frames['view'].document.location。代码如下:
Javascript代码
window.open($( this).attr( "href"),$( this).attr( "target"));    

如果没有定义target属性,默认会当成'_blank'处理,这与用户单击超链接的效果不一样。这种方式是跨浏览器的,所以,只需要要用这种方式即可。这时,回到用jQuery+原始JavaScirpt来实现,这时最终、个人认为最好的方法。完整最终代码如下:
Html代码
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > 
< html > 
     < head > 
         < title >JavaScript模拟用户单击事件——徐新华 polaris </title> 
    
         < meta  http-equiv ="keywords"  content ="keyword1,keyword2,keyword3" > 
         < meta  http-equiv ="description"  content ="this is my page" > 
         < meta  http-equiv ="content-type"  content ="text/html; charset=UTF-8" > 

   < ! -- 引入jQuery -- > 
   < script  type ="text/javascript"  src ="scripts/jQuery/jquery-1.3.2.js" > </script> 
   < script  type ="text/javascript" > 
    /**    
    * 模拟用户单击事件 处理超链接的问题 
    * @author xuxinhua 
    */ 
    $(function() 
    { 
      $("#btn").click(function() 
      { 
        $("#submit").click(); 
         
        // 绑定单击事件 
        $("#aLink").click(function() 
        { 
          window.open($(this).attr("href"),$(this).attr("target")); 
        }); 
            
        // 触发单击事件(会执行所有绑定的单击事件处理函数) 
        $("#aLink").click(); 
      }); 
    }); 
   </script> 
     </head> 
     
     < body > 
       < h3 >请单击”Click Me"。测试提交按钮与超链接是否也被单击了。 </h3> 
   < button  id ="btn" >Click Me </button> 
   < form  action ="#" > 
     < input  type ="text"  name ="userName"  value ="徐新华-polaris" readonly /> 
     < input  id ="submit"  type ="submit"  value ="别点击此按钮提交"  onclick ="alert('触发了提交按钮的单击事件!');" /> 
   </form> 
   < a  id ="aLink"  href ="http://www.google.cn"  target ="_self" onclick = "alert('触发了超链接的单击事件!');" >代码触发超链接 </a> 
     </body> 
     
</html>

注意:需要此处需要先绑定一个click处理函数,然后再触发click事件 
总结: 
网上有一些JavaScript模拟用户单击事件的文章,但是都不全面,总会有这样那样的问题。虽然,我在此列举了众多的方法,觉得基本的问题都应该解决了,然而还是有可能有人遇到新的问题。如果遇到什么问题,可以跟我一起探讨……



     本文转自polaris1119 51CTO博客,原文链接:http://blog.51cto.com/polaris/269758 ,如需转载请自行联系原作者

相关文章
|
2月前
|
JavaScript 前端开发
js事件队列
js事件队列
137 55
|
29天前
|
JavaScript 前端开发
JavaScript 事件
JavaScript 事件
30 2
|
2月前
|
JavaScript 前端开发
javascript中常用的事件
这篇文章列出并演示了JavaScript中常用的DOM事件,包括失去焦点、获得焦点、鼠标点击、键盘事件等,并展示了如何通过直接在HTML标签中使用事件句柄和通过JavaScript为元素添加事件监听器两种方式来注册事件。
|
2月前
|
JavaScript 前端开发
JavaScript 事件的绑定
JavaScript 事件的绑定
33 0
|
4月前
|
JavaScript 前端开发
事件委托是JS技巧,通过绑定事件到父元素利用事件冒泡,减少事件处理器数量,提高性能和节省内存。
【6月更文挑战第27天】事件委托是JS技巧,通过绑定事件到父元素利用事件冒泡,减少事件处理器数量,提高性能和节省内存。例如,动态列表可共享一个`click`事件处理器,通过`event.target`识别触发事件的子元素,简化管理和响应动态内容变化。
39 0
|
11天前
|
JavaScript 前端开发
JavaScript HTML DOM 事件
JavaScript HTML DOM 事件
14 5
|
12天前
|
监控 JavaScript 前端开发
|
29天前
Nest.js 实战 (十二):优雅地使用事件发布/订阅模块 Event Emitter
这篇文章介绍了在Nest.js构建应用时,如何通过事件/发布-订阅模式使应用程序更健壮、灵活、易于扩展,并简化服务间通信。文章主要围绕@nestjs/event-emitter模块展开,这是一个基于eventemitter2库的社区模块,提供了事件发布/订阅功能,使得实现事件驱动架构变得简单。文章还介绍了如何使用该模块,包括安装依赖、初始化模块、注册EventEmitterModule、使用装饰器简化监听等。最后总结,集成@nestjs/event-emitter模块可以提升应用程序的事件驱动能力,构建出更为松耦合、易扩展且高度灵活的系统架构,是构建现代、响应迅速且具有高度解耦特性的Nest.
|
2月前
|
编解码 JavaScript 前端开发
JS逆向浏览器脱环境专题:事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决
JS逆向浏览器脱环境专题:事件学习和编写、DOM和BOM结构、指纹验证排查、代理自吐环境通杀环境检测、脱环境框架、脱环境插件解决
59 1
|
24天前
|
JavaScript 前端开发
js事件队列
js事件队列
25 0