用js的eval函数模拟Web API中的onclick事件
在检查组内小伙伴提交的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事件的更多相关文章
- JS的eval函数解密反混淆
https://www.hhtjim.com/js-decryption-de-obfuscate-eval-function.html JS的eval函数解密反混淆
- Java 实现 JS的eval函数
JS的eval 函数, 给个表达式做参数, 返回表达式的值. Java的脚本引擎可以实现这个功能. 例子: 拼接一个字符串 \uxxxx, Unicode的十六进制编码, 然后把它打印出来. 即输 ...
- ASP.NET Web API中的JSON和XML序列化
ASP.NET Web API中的JSON和XML序列化 前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok ...
- 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务
在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
- Web APi 2.0优点和特点?在Web APi中如何启动Session状态?
前言 曾几何时,微软基于Web服务技术给出最流行的基于XML且以扩展名为.asmx结尾的Web Service,此服务在.NET Framework中风靡一时同时也被.NET业界同仁所青睐,几年后在此 ...
- Asp.Net Web Api中使用Swagger
关于swagger 设计是API开发的基础.Swagger使API设计变得轻而易举,为开发人员.架构师和产品所有者提供了易于使用的工具. 官方网址:https://swagger.io/solutio ...
- Asp.Net MVC Web API 中Swagger教程,使用Swagger创建Web API帮助文件
什么是Swagger? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法 ...
- 利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
在Asp.net Web API中,对业务数据的分页查询处理是一个非常常见的接口,我们需要在查询条件对象中,定义好相应业务的查询参数,排序信息,请求记录数和每页大小信息等内容,根据这些查询信息,我们在 ...
随机推荐
- Android5.0(lollipop)新特性介绍(一)
今年6月的Google I/O大会上.Android L的初次见面我相信让会让非常多android粉丝有些小激动和小期待.当然作为开发人员的我来说,激动不言而喻,毕竟这是自08年以来改变最大的一个版本 ...
- ASO--简单了解
ASO是“应用商店优化”的简称.ASO(App Search Optimization)就是提升你APP在各类APP应用商店/市场排行榜和搜索结果排名的过程. 类似普通网站针对搜索引擎的优化,即SEO ...
- 通过GhostDoc实现自定义方法概要(summary)
首先是下载GhostDoc 来自园友:http://www.cnblogs.com/VAllen/p/GhostDocPro49.html 修改模板 安装好后,修改下模板,工具>GhostDoc ...
- Java小白手记2:一些名词解释
看到<Java 征途:行者的地图> ,这是一篇有关java学习路径文章.对我等Java小白有指引作用.里面提到了一些基本的名词术语,有些我知道,有些不知道,再补上一些自己曾觉得模糊的,记录 ...
- Redhat enterpise6 安装unix2dos/dos2unix
初用unix2dos,在rhel6 上 用yum install unix2dos , 提示源不可用, 那好吧, 就去rpm包网:http://rpm.pbone.net/ 下载了一个unix2dos ...
- C项目实践--家庭财务管理系统
1.功能需求分析 家庭财务管理系统给家庭成员提供了一个管理家庭财务的平台,系统可以对家庭成员的收入和支出进行增加,删除.修改和查询等操作,并能统计总收入和总支出.其主要功能需求描述如下: (1)系统主 ...
- Linux的进程优先级NI和PR到底有什么区别
Linux的进程优先级NI和PR到底有什么区别 - 51CTO.COM http://os.51cto.com/art/201605/511559.htm
- CSS 对齐方式
居中设置 Center Align - Using margin Setting the width of a block-level element will prevent it from str ...
- MySql安装与使用图文教程
2.下载完成后将其解压到你想要安装的路径下,例如我的解压到D:\MySql\mysql-5.7.12-winx64\路径下,刚解压完应该是下图这些文件夹:最好解压到根目录. 5.新建一个my.in ...
- HDU1542 Atlantis —— 求矩形面积并 线段树 + 扫描线 + 离散化
题目链接:https://vjudge.net/problem/HDU-1542 There are several ancient Greek texts that contain descript ...