【JS交互埋坑】事件函数自动将数字字符串String转为数值Number

一、DOM操作中自定义事件函数形参传参自动将数字字符串String转为数值Number。

这是一个表格列表数据的渲染,通过配置项的方式,去通过原生DOM渲染到页面。每一项中有一个format函数可以格式化当前行的数据,它返回一个包裹标签和事件的字符串。恰恰就是这个字符串,在自定义函数中传参时暗中捣鬼,将数字字符串转成了数值。

如下代码,这是一段做了拼接的代码,很难发现它会有问腿:

]

{
	display:操作',
	name '',
	index:'',
	width: 100,
	align:"center",
	editable: false,
	sortable: true,
	hidden: false,
	formatter: function (y, o, r) {
		return '<a operate="delete" href="javascript:void(@)" οnclick="revocationHandle(' + r.VC_BATCH_ID +')">撤销</a>
}

然而是事实是,当我传递 VC_BATCH_ID 的时候总会报 SyntaxError: invalid syntax 这个错误

SyntaxError(语法错误)对象代表尝试解析不符合语法的代码的错误。当 Javascript 引擎解析代码时,遇到了不符合语法规范的标记(token)或标记顺序,则会抛出 SyntaxError。

SyntaxError 是一个可序列化对象,所以可以使用 structuredClone() 对它进行克隆,也可以使用 postMessage() 在 Worker 之间拷贝它。

VC_BATCH_ID 是诸如 asd-231-tfd-23334 类似的 id 值,所以我尝试传递 123 、'Hello'、'中国' 这些数字或字符串常量,发现都可以正常拿到结果。所以又尝试直接把 asd-231-tfd-23334 字面量做了传递,果不其然,又开始报错了。我又尝试传递了对象、数组,都是报错。真是一头雾水,两眼懵逼。

我又尝试使用 String() 、JSON.stringify() 去处理,依旧不行。

问题定位到了,就在于这个传递的参数上,它自己偷偷做了处理。那么到底是什么原因呢?

原来是字符串拼接的过程中,如果有事件函数要传递参数,参数部分应该是 removeHandle("id")这样的。所以我们这里需要转义字符转义一下引号。如下:

{
	display:操作',
	name '',
	index:'',
	width: 100,
	align:"center",
	editable: false,
	sortable: true,
	hidden: false,
	formatter: function (y, o, r) {
		return '<a operate="delete" href="javascriptvoid(@)" οnclick="revocationHandle(\'' + r.VC_BATCH_ID +'\')">撤销</a>
}

注:因为之前的纯原生操作,并没有遇到此类问题。这里不熟悉对方代码到底是如何封装和处理的,有可能与之有关系。但是再遇到诸如此类问题的时候,大家可以参考下解决方案。

二、批量定义元素事件不生效问题

这个问题对于一些成熟的开发人员不算难,很好解决。但是对于一些新手、甚至初级开发人员会造成困扰,所以在这里顺便讲一下。

在原生JS中,假设有一列表内容,点击我们可以进行页面的跳转到响应的详情页面,这就需要给每一个都定义点击事件:

  1. 通过 ul>li 标签定义页面列表内容,并定义相关的类名如:list、item
  2. 在js中通过document.getElementsByClassName获取所有的元素
  3. 遍历所有获取的元素,并给每一个都定义点击事件

代码如下:

# HTML 代码
<ul class="list">
	<li class="item">列表展示内容一</li>
	<li class="item">列表展示内容二</li>
	<li class="item">列表展示内容三</li>
	<li class="item">列表展示内容四</li>
	<li class="item">列表展示内容五</li>
	<li class="item">列表展示内容六</li>
	<li class="item">列表展示内容七</li>
</ul>


# JavaScript 代码
var items = document.getElementsByClassName('item')
for(var i = 0; i < items.length; i++){
	items[i].onclick = function(){
		// 执行相关代码
		console.log(i, this)
	}
}

上面的代码,一气呵成,看起来没有什么问题。如果仅仅是跳转到同一个页面,获取操作当前这个元素,完全可以使用 this 获取对应的内容。但是如果想要携带数据跳转到指定页面,或者当前页面中需要获取当前索引做进一步处理,会发现,索引并不存在于任何一个上面,而是一个固定值。

什么原因呢?

for 循环中 var 声明的变量是一个全局变量,而且点击事件属于人为触发后执行,而此时循环已经执行完毕,所以当人为i点击时,i的全局变量值已经时 items.length 了。

提供三种解决办法:

1、通过给每一个定义一个属性存储遍历的索引

for(var i = 0; i < items.length; i++){
	items[i],idx = i
	items[i].onclick = function(){
		// 执行相关代码
		console.log(i, this, this.idx)
	}
}

2、通过闭包的方式,形成独立作用域,保存变量的值

for(var i = 0; i < items.length; i++){
	(function(j){
		items[j].onclick = function(){
			// 执行相关代码
			console.log(i, this, j)
		}
	})(i)
}

3、通过let定义场域,让 i 成为局部作用于快中的值保存下来

for(let i = 0; i < items.length; i++){
	items[i].onclick = function(){
		// 执行相关代码
		console.log(i, this)
	}
}

注:三种方式都可以解决问题,可以根据现阶段的知识和能力选择合适的方案

相关推荐
Dread_lxy12 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
娅娅梨18 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
汤米粥23 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾26 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺33 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
涔溪1 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
好睡凯1 小时前
c++写一个死锁并且自己解锁
开发语言·c++·算法