在检查组内小伙伴提交的tabToggler插件的js代码时,发现了onclick的如下用法:

                el.onclick = function(){
//按钮样式切换
for(var i=0;i<obj.btns.length;i++){
obj.btns[i].classList.remove("current");
}
this.classList.add("current");
//内容显示切换
for(var j = 0;j<obj.divs.length;j++){
obj.divs[j].style.display = 'none';
}
obj.divs[this.index].style.display = 'block';
console.log(this.index);
}

显然这个this指向事件源对象—eventTarget,最近一直在钻研闭包和this的我,看到这里觉得非常的怪,为什么这里的this可以指向eventTarget呢,而且在书写在html标签里的事件处理函数也可以在非闭包作用域下直接访问this(指向target),如下代码:

<div id="tab1" myonclick = "console.log(this.id);console.log(this)">Tab1</div>

打印结果:

这到底怎么实现的?按照需求一步一步分析就可以了,其实onclick的事件处理函数包括了两部分:

Part 1: 来自html标签内的onclick属性内的js代码;

Part 2: 来自己js脚本里的onclick方法

需求如下:

Part 1 里的onclick字符串可以被click事件执行,而且this作用域是eventTarget

问题:js里有什么机制能执行字符串形式的js代码?如何让代码作用域指向eventTarget?

答案:eval,且eval执行本身就有作用域的概念,让代码的作用域指向eventTarget就行了。

Part 2 里的onclick方法被click事件执行内部逻辑,而且this作用域是eventTarget;

综上,我们可以用eval和指定作用域的办法来扩展一个myonclick时间了,具体实现如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="tab1" myonclick = "console.log(this.id);console.log(this)">Tab1</div>
<div id="tab2">Tab2</div>
</body>
<script>
//扩展HTMLDivElement原型
HTMLElement.prototype.clickHandle = function(){
//1.检查dom标签里有myonclick属性
var _evalClickStr = this.getAttribute( "myonclick" );
//2.检查dom有无指定myonclick方法
if( !!this.myonclick && typeof this.myonclick === "function" ){
var _clickHandle = this.myonclick;
}
var nativeEventBind = this.addEventListener || this.attachEvent;
if( !!nativeEventBind ){
nativeEventBind( 'click',(function( e ){
//执行eavl代码串
eval( _evalClickStr );
//执行myonclick事件处理函数
_clickHandle.apply( this,e );
}).bind(this) );
}
else return;
} var tab1 = document.getElementById( "tab1" );
tab1.myonclick = function(){
console.log( this.id );
};
tab1.clickHandle(); </script>
</html>

核心设计要点:扩展了HTMLElement.prototype对象,在clickHandle方法里,指定了两部分onclick代码的执行上下文为HTMLElement元素本身。

用js的eval函数模拟Web API中的onclick事件的更多相关文章

  1. JS的eval函数解密反混淆

    https://www.hhtjim.com/js-decryption-de-obfuscate-eval-function.html JS的eval函数解密反混淆

  2. Java 实现 JS的eval函数

    JS的eval 函数, 给个表达式做参数, 返回表达式的值. Java的脚本引擎可以实现这个功能. 例子:   拼接一个字符串 \uxxxx, Unicode的十六进制编码, 然后把它打印出来. 即输 ...

  3. ASP.NET Web API中的JSON和XML序列化

    ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...

  4. 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务

    在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...

  5. Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化

    9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...

  6. Web APi 2.0优点和特点?在Web APi中如何启动Session状态?

    前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...

  7. Asp.Net Web Api中使用Swagger

    关于swagger 设计是API开发的基础.Swagger使API设计变得轻而易举,为开发人员.架构师和产品所有者提供了易于使用的工具. 官方网址:https://swagger.io/solutio ...

  8. Asp.Net MVC Web API 中Swagger教程,使用Swagger创建Web API帮助文件

    什么是Swagger? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法 ...

  9. 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理

    在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...

随机推荐

  1. flask的路由配置,特殊装饰器

    1,flask中的路由 endpoint-url_for反向地址 endpoint默认是视图函数名endpoint="雪雪" methods 指定视图函数的请求方式,默认GET d ...

  2. 返回模式有流式(streaming)和整体(total) 热词词表解决方案

    重要术语说明_语音识别(ASR)_智能语音交互-阿里云  https://help.aliyun.com/document_detail/72238.html 返回模式(response mode) ...

  3. Installing Node.js via package manager

    https://nodejs.org/en/download/package-manager/

  4. 设计模式-(9)中介者模式(swift)

    在对象去耦合的模式中,有两种模式:中介者模式,观察者模式 一,概念 用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 这个 ...

  5. HttpsURLConnection 安全传输(HTTPS--Secure Hypertext Transfer Protocol-安全超文本传输协议)

    HttpsURLConnection 扩展 HttpURLConnection,支持各种特定于 https 功能.此类使用 HostnameVerifier 和 SSLSocketFactory.为这 ...

  6. UICollectionView与UITableView混用手势冲突

    前言 最近在重构某个模块,以后别人封装的所谓的基类就像一坨死一样,看见就恶心,相信同行的你们能够明白那种心情.为什么要重构?并不是真的因为它像一坨死,而是因为这个模块是用户使用最频繁的,而且出现了不少 ...

  7. BZOJ3282:Tree(TCL基础题)

    给定N个点以及每个点的权值,要你处理接下来的M个操作. 操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和. 保证x到y是联通的. ...

  8. 部署到Linux并配置Java定时任务

    Java项目部署到Linux并配置定时任务 https://blog.csdn.net/u013850277/article/details/53447391 1.在Eclipse中将程序开发好,并进 ...

  9. python-----实现微信撤回消息还原

    有时候用微信聊天,好友会撤回一些聊天记录,我们好奇,但又没法看,以下代码就可以满足大家的好奇心. #!/usr/bin/env python # -*- coding: utf-8 -*- # @Ti ...

  10. 洛谷 P1315 观光公交 —— 贪心

    题目:https://www.luogu.org/problemnew/show/P1315 问题是想不明白改动一条边会对后面造成怎样的影响: 实际上影响的会是一段,当某个车站出发时间受其来人牵制时, ...