JavaScript单击按钮执行两个函数

3
我使用了从网上下载的HTML和JS代码来记录音频,但是有一个问题,页面加载后立即出现允许麦克风的消息。这是因为源代码record.js中的window.onload = function init()。但我希望在点击按钮后再显示该消息。
因此,我尝试使用这个按钮调用两个函数-toggleRecording(button)init(),但是由于"button"元素存在问题,所以它没有起作用,但我认为如果以正确的形式编写,它可能会起作用。你能给我展示如何修改这两个函数inittoggleRecording,让它们可以被这个按钮调用吗?我是JS新手,不知道它是如何工作的。 index.html
<button type="submit" onclick="toggleRecording()" data-run="0"></button>

record.js

//starts by click on button
  function toggleRecording() {
    var run = parseInt(getAttribute('data-run')); //

      if(run === 1) {
      recorder && recorder.stop();
      recorder && recorder.exportWAV(function(blob) {
        uploadAudioFromBlob(blob);
      });
      __log('Recording is  stopped.');
      button.setAttribute('data-run', 0);

    } 

    else {
      recorder && recorder.clear();
      recorder && recorder.record();
      __log('Speak...');
      button.setAttribute('data-run', 1);
    }
  }

  function __log(e, data) {     
showInfo("\n" + e + " " + (data || ''));  
  }

  var audio_context;
  var recorder;
  function startUserMedia(stream) { 
    var input = audio_context.createMediaStreamSource(stream); 
    recorder = new Recorder(input); 
    __log('Systém for recording is available.'); 
  }

  function startRecording(button) {   
    recorder && recorder.clear(); 
    recorder && recorder.record(); 
    button.nextElementSibling.disabled = false;
    __log('Talk...'); 
  }

   window.onload=function init() {
    try { 
      window.AudioContext = window.AudioContext || window.webkitAudioContext; 
      navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;   
      window.URL = window.URL || window.webkitURL;      
      audio_context = new AudioContext;      
    } catch (e) { 
      alert('This browser do not support audio!');
    }    
    navigator.getUserMedia({audio: true}, startUserMedia, function(e) {
      __log('No audio was detected: ' + e);
    });
  };
更新: 现在该系统的运行步骤如下: 1. function init() 在页面加载后立即运行,用户允许使用麦克风之后运行startusermedia函数 2. 点击按钮后运行toggleRecording(button)函数,开始录音 3. 第二次点击按钮后,运行toggleRecording函数,停止录音
如果可能的话,我希望该系统可以按以下步骤进行操作: 1. 点击按钮后首先运行initstartusermediatogglerecording函数,因此在点击后立即开始录制 2. 第二次点击将调用toggleRecording函数以停止录音。

1
你尝试过这种方式 onclick="toggleRecording(); init();" 吗?可以随意更改顺序。 - A l w a y s S u n n y
4个回答

2

出现问题的原因是 init() 实际上是附加到 window.onload 的变量。尝试移除 window.onload=function init(), 然后用 function init() 替换它 (这样它就不会在页面加载时立即运行),然后调用:

<button type="submit" onclick="init();toggleRecording()" data-run="0"></button>

当您设置事件处理程序时,甚至不需要给函数命名。像 window.onload = function() { ... } 这样的代码是完全有效的 - 它们被称为匿名函数。 我还注意到了一些在 toggleRecording() 中的实现问题,所以我尽力修复了这些问题。当然,getAttribute() 需要一个元素,因此我们可以使用 this 传递按钮,并将其作为 button 变量在 toggleRecording() 中接收。
您的完整代码现在如下:

//starts by click on button
function toggleRecording(button) {
  var run = parseInt(button.getAttribute('data-run')); //

  if (run === 1) {
    recorder && recorder.stop();
    recorder && recorder.exportWAV(function(blob) {
      uploadAudioFromBlob(blob);
    });
    __log('Recording is  stopped.');
    button.setAttribute('data-run', 0);

  } else {
    recorder && recorder.clear();
    recorder && recorder.record();
    __log('Speak...');
    button.setAttribute('data-run', 1);
  }
}

function __log(e, data) {
  //TODO: Uncomment this, I have it commented so there are no errors in the StackSnippet
  //showInfo("\n" + e + " " + (data || ''));
  console.log(e.data);
}

var audio_context;
var recorder;

function startUserMedia(stream) {
  var input = audio_context.createMediaStreamSource(stream);
  recorder = new Recorder(input);
  __log('Systém for recording is available.');
}

function startRecording(button) {
  recorder && recorder.clear();
  recorder && recorder.record();
  button.nextElementSibling.disabled = false;
  __log('Talk...');
}

function init() {
  try {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
    window.URL = window.URL || window.webkitURL;
    audio_context = new AudioContext;
  } catch (e) {
    alert('This browser do not support audio!');
  }
  navigator.getUserMedia({
    audio: true
  }, startUserMedia, function(e) {
    __log('No audio was detected: ' + e);
  });
};
<button onclick="init(); toggleRecording(this)">Click me</button>


非常感谢。我发现它不起作用。请查看我的问题更新,了解它应该如何工作。如果您知道如何做,请给我展示一个例子。 - Nikolaus

0
在您的情况下,init函数直接附加到window.onload事件上,无法通过按钮调用。为了确保在这两个事件中调用它,请将其声明为全局函数,然后像这样将其附加到onload事件上:

JavaScript:

//function declaration
init = function init() {
try { 
  window.AudioContext = window.AudioContext || window.webkitAudioContext; 
  navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;   
  window.URL = window.URL || window.webkitURL;      
  audio_context = new AudioContext;      
} catch (e) { 
  alert('This browser do not support audio!');
}    
navigator.getUserMedia({audio: true}, startUserMedia, function(e) {
  __log('No audio was detected: ' + e);
});
};

//Call
 window.onload = init();

HTML:

<button type="submit" onclick="init();toggleRecording()" data-run="0"></button>

应该可以了。

编辑:

为了实现你想要的功能,你需要将init()函数附加到window.onload事件上,将toggleRecording()函数附加到run button的onclick事件上,像这样:

//Call
 window.onload = init();
 document.getElementById("run").onclick = toggleRecording();

并给你的按钮添加 id="run"

<button type="submit" id="run" onclick="init();toggleRecording()" data-run="0"></button>

非常感谢。我发现它无法正常工作。请查看我的问题更新,了解它应该如何工作。如果您知道如何做,请向我展示示例。 - Nikolaus
@Nikolaus,请看一下我的编辑。 - cнŝdk

0

如果需要,您可以使用addEventListener以编程方式将多个操作附加到按钮。

因此,您可能会有:

<button id="test" type="submit" onclick="toggleRecording()" data-run="0"></button>
<script>
   var btn = document.getElementById("test");
   btn.addEventListener("click", init);
   btn.addEventListener("click", toggleRecording);
   // More if wanted.
</script>

非常感谢。我发现它不起作用。请查看我的问题更新,了解它应该如何工作。如果您知道如何做,请给我示例。 - Nikolaus

0
如果您想在按下按钮后使代码生效,应该删除 onload 事件,因为这会使代码在页面加载后才生效。
您可以创建第二个函数并将其放置在其中,例如:
function secondFunction(){
    // Put Code inside here
}

toggleRecording(button) 函数中,你可以这样调用:
function toggleRecording(button) {
    // .. the existing code
    secondFunction();
}

如果你想让第二个被调用,把它放在现有代码上面。
你也可以这样做: <button type="submit" onclick="toggleRecording();init();" data-run="0"></button> 但是你仍然需要移除 onload 事件,并像上面那样将其包装在一个函数中。
你还可以这样做(推荐): <button id="record" type="submit" onclick="toggleRecording()" data-run="0"</button> 代码:
var button = document.getElementById( 'record' );

var button.onclick = function(e){
     toggleRecording(e);
     secondFunction();
}

此外,如果您不想在页面加载时执行它,可以再次删除onload事件。
最后的示例选择具有ID record的按钮元素(我已将其添加到您的标记中),并在其上添加了一个onclick = function(){}onclick事件,当然会在“onclick”调用时被调用。
最后但并非最不重要的是:不要只是复制代码,尝试理解它,这样您就可以轻松自己解决问题 :)

非常感谢。我发现它不起作用。请查看我的问题更新,了解它应该如何工作。如果您知道如何做,请给我示例。 - Nikolaus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接