【问题标题】:Passing a callback to js via DOM elements dataset通过 DOM 元素数据集向 js 传递回调
【发布时间】:2019-04-02 00:32:57
【问题描述】:

我有一个模块化系统,它从我的服务器获取一些数据并通过 ajax 将其返回给客户端,然后客户端对这些数据进行处理。

为了保持代码模块化,我想引入一个回调变量,这样我就可以指定一个回调函数,该函数会根据请求的数据而变化。这最好插入到与功能相关的元素中(即按钮或输入)

现在我将回调函数名称存储在 dom 中,作为元素 data-callback="functionName" 属性,然后 eval()ing 该值以运行回调。

sn-p:

document.addEventListener( 'click', function( evt ){
  var tgt = evt.target;
  
  if( tgt.id == "btn" ){
  
    var callback = tgt.dataset.callback;
    var callbackParam = tgt.dataset.callbackParam;
  
    eval( callback + "('" + callbackParam + "')" );
  }
});



function foo( str ){

  document.getElementById( "returnDisplay" ).innerText = str;
  
  window.setTimeout( function(){
    document.getElementById( "returnDisplay" ).innerText = '';
  }, 1000 );
  
}
<div id=returnDisplay></div>
<button id=btn data-callback="foo" data-callback-param="bar">Click me</button>

我知道 eval 被认为是危险的,有没有其他方法可以通过 DOM 将回调传递给 javascript?

【问题讨论】:

  • 为什么不直接绑定事件呢?
  • @Ele,我猜是习惯,我喜欢处理 dom 上的所有事件,所以我只绑定一个事件,然后检查事件目标以执行它。这意味着当我向 DOM 添加元素时,我不需要为我使用 javascript 创建的每个元素分配事件,而是我可以放心,事件将在 DOM 根目录中被提取并相应地过滤掉。我自己编的,是不是坏主意?

标签: javascript ajax callback dataset


【解决方案1】:

您可以使用 setTimeout 实现您所需要的。

var callback = tgt.dataset.callback;
setTimeout(callback);

如果你需要传递一些参数,你可以,看例子

let fncName = 'alert'
let fncParam = 'hello'
setTimeout(`${fncName}("${fncParam}")`)

【讨论】:

【解决方案2】:

你也可以这样——我在创建时引用了these MDN docs

<div id=returnDisplay></div>
<button id="btn" data-callback-param="bar" data-callback-function="myFunc">Click me</button>
const log = document.getElementById('btn');

log.onclick = clickHandler;

function clickHandler(e) {
  const {callbackParam, callbackFunction} = e.target.dataset
  eval(`${callbackFunction}("${callbackParam}")`)
}

【讨论】:

  • 嗯,这只是记录嵌入在数据属性中的字符串,它不会通过数据属性中传递的名称调用函数,这正是我想要的
  • 知道了...我想我会质疑你为什么要这样做?正如您所提到的,对字符串进行评估是非常危险的,而且您似乎仍然可以以模块化方式构建系统,其中每个组件(或任何您的组织单位)都可以有自己的初始化处理程序。无论如何,我会更新我的答案以反映你在寻找什么:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 2011-02-14
相关资源
最近更新 更多