防止动态创建的 onclick 事件过早触发

Prevent dynamically created onclick event from prematurely firing

我正在与一个小型图书馆合作,records audio in the browser 并将其上传到服务器,但我想让用户选择在单击按钮后上传到浏览器。

大部分库都导入到html页面,所以我想调用的函数,它的参数在页面上没有。

在调用 'upload' 函数的函数中,我尝试将函数调用分配给 onclick 事件:

document.getElementById("clickMe").onclick = endFile(buf, 'mp3');

HTML 为:

<a href='#' id="clickMe" class="btn btn-default">Upload</a>

但它过早触发,我猜是因为函数正在 'evaluated'。该库使用 jQuery,我尝试将 e.preventDefault()e.stopPropagation() 添加到外部函数,但都没有用。

注意到当我分配一个匿名函数时它没有被调用,所以我使用:

document.getElementById("clickMe").onclick = function(){
        endFile(buf, 'mp3');
        }

这似乎有效。有人能解释一下原因吗,并一定要让我知道为什么这可能是一种不可取的方法。

您的函数过早触发的原因是您实际上是在调用它,而您打算分配它。

改变这个...

document.getElementById("clickMe").onclick = endFile(buf, 'mp3');

为此...

document.getElementById("clickMe").onclick = function() {
  endFile(buf, 'mp3');
};

或者这个...

document.getElementById("clickMe").onclick = endFile.bind(this, buf, 'mp3');

进一步解释 - endFile(buf, 'mp3') 实际上调用了该函数。因此,您不是将函数分配为 onclick-handler,而是调用它并分配其 return 值。

Javascript 看看任何函数表达式 endFile(buf, 'mp3') 是否分配给变量或处理程序,就这样,"expression" 所以它会立即调用它。

你说它是 evaluating 函数方法是正确的。

document.getElementById("clickMe").onclick = endFile(buf, 'mp3');

类似于:

var returnValue = endFile(buf, 'mp3');

而您想将 onclick 设置为函数 endFilereference

document.getElementById("clickMe").onclick = endFile

虽然需要绑定您要在事件发生时传递的参数。这将取决于您的用例和这些值的范围。

document.getElementById("clickMe").onclick = endFile.bind(buf, 'mp3')

你创建匿名函数并没有错,但替代方法是一样的。

function endFile(typeOfFile) {
  var buffer = this;
  console.log(buffer, typeOfFile);
  return true;
}
var buf = 'some buffer value';
document.getElementById("clickMe").onclick = endFile.bind(buf, 'mp3');
<button id="clickMe">Click Me</button>