如何从外部调用 javascript 库函数?

How can I call javascript library functions externally?

我正在开发一个处理网络音频和波形显示的应用程序。

为此,我使用了一个名为 Wavesurfer 的库,专门为此而设计。

我 运行 遇到的问题是调用播放曲目的函数。我尝试使用 jQuery 的 .click() 将其放入外部 JavaScript 脚本中,但没有成功。

所以,我决定像这样在按钮本身上尝试 onclick() 事件:

<div style="text-align: center">
  <button class="btn btn-primary" onclick="wavesurfer.playPause()">
    Play
  </button>
</div>

唯一的变化是它在控制台中告诉我,"wavesurfer is not defined.",但必须定义它,因为它仍在绘制音频波形!

最奇怪的是这段完全相同的代码在 CodePen!

中工作正常

编辑:完整代码如下:

<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/1.1.2/wavesurfer.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="C:\Users\Ryan\Desktop\wavesurfer.js"></script>
</head>
<body>
<div id="waveform"></div>

<div style="text-align: center">
  <button class="btn btn-primary" onclick="wavesurfer.playPause()">
Play
  </button>
</div>
</body>
</html>

和JavaScript:

$(document).ready(function(){
var wavesurfer = WaveSurfer.create({
    container: '#waveform',
    waveColor: 'red',
    progressColor: 'purple'
});
wavesurfer.load('https://archive.org/download/Metallica_37/Metallica-MasterOfPuppets.mp3');

});

您需要在头部导入波形 AJAX 库和 Bootstrap 作为

<script src="https://cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/1.1.2/wavesurfer.min.js"></script>

<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>

然后是 wavesurfer 对象

var wavesurfer = WaveSurfer.create({
    container: '#waveform',
    waveColor: 'grey',
    progressColor: '#ff7700',
});

// Song Goes Here!
wavesurfer.load('https://archive.org/download/Metallica_37/Metallica-MasterOfPuppets.mp3');

然后你的代码可以看起来像

<div style="text-align: center">
  <button class="btn btn-primary" onclick="wavesurfer.playPause()">
    Play
  </button>
</div>

播放歌曲 Metallica - Master of Puppets

这是一个新的 codePen

问题是什么?

您需要将 wavesurfer.js 源(来自 CDN)添加到 codePen:

//cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/1.0.52/wavesurfer.min.js

wavesuffer.js是如何一步一步工作的? (来自documentation

1-创建容器:

<div id="waveform"></div>

2-创建 wavesurfer 实例:

var wavesurfer = WaveSurfer.create({
container: '#waveform',
waveColor: 'violet',
progressColor: 'purple'
});

3-加载音频:

 wavesurfer.load('audio.wav');

变量作用域

您遇到的问题属于范围问题。

什么是作用域

javascript 中的所有变量都有作用域。如果超出范围,则无法访问变量。对于使用 var 标记声明的变量,它们的范围是声明它们的函数。在任何函数外部声明的变量都具有全局范围。全局范围意味着可以从页面上的任何位置访问该变量。

例子

var myGlobal = 10; // this is outside any function and is global
function myFunction(){
    var myFuncLoc = 20;  // this is inside the function and scoped to the function
    console.log(myFuncLoc); // >> 20  // is in scope can be displayed
    console.log(myGlobal); // >> 10  // is in scope can be displayed
    function(){
        var myFuncLoc1 = 30;
        console.log(myFuncLoc); // >> 20  // is in scope can be displayed
        console.log(myFuncLoc1); // >> 30  // is in scope can be displayed
        console.log(myGlobal); // >> 10  // is in scope can be displayed
    }
    console.log(myFuncLoc); // >> 20  // is in scope can be displayed
    console.log(myGlobal); // >> 10  // is in scope can be displayed
    // next is out of scope
    console.log(myFuncLoc1); // Throws ReferenceError: myFuncLoc1 is not defined
}
console.log(myGlobal); // >> 10  // is in scope can be displayed
    // next is out of scope
console.log(myFuncLoc); // Throws ReferenceError: myFuncLoc is not defined
console.log(myFuncLoc1); // Throws ReferenceError: myFuncLoc1 is not defined

这是一个简短的概述,还有带有标记 letconst 的块范围变量声明 { }仔细阅读范围,因为这是几乎所有编程语言的重要概念。

怎么了

所以你的问题是你有一个超出范围的变量。

$(document).ready(function(){
    // wavesurfer is scoped to this function only
    // and can not be seen in the global scope.
    var wavesurfer = WaveSurfer.create({
        container: '#waveform',
        waveColor: 'red',
        progressColor: 'purple'
    });
    wavesurfer.load('https://archive.org/download/Metallica_37/Metallica-MasterOfPuppets.mp3');

});

onclick是在全局范围内,看不到函数范围内声明的变量

<!-- can not see wavesurfer -->
<button class="btn btn-primary" onclick="wavesurfer.playPause()">

黑客修复。

要修复你可以确保 wavesurfer 是全局的

// outside any function
var wavesurfer; // declares wavesurfer as a globally scoped variable

$(document).ready(function(){
    // wavesurfer is global
    // so do not use the var token be cause if you do then you create a second
    // variable called wavesurfer inside this function
    wavesurfer = WaveSurfer.create({  
        container: '#waveform',
        waveColor: 'red',
        progressColor: 'purple'
    });
    wavesurfer.load('https://archive.org/download/Metallica_37/Metallica-MasterOfPuppets.mp3');

});

这将解决您的问题

首选修复

更好的解决方案是在 wavesurfer 具有作用域的地方添加 onclick 事件,这样可以避免污染全局作用域。

更改按钮

<!-- remove the onclick from the play button and give it an id-->
<button class="btn btn-primary" id='playButton'>

然后是代码

$(document).ready(function(){
    // function scope wavesurfer
    var wavesurfer = WaveSurfer.create({  
        container: '#waveform',
        waveColor: 'red',
        progressColor: 'purple'
    });

    wavesurfer.load('https://archive.org/download/Metallica_37/Metallica-MasterOfPuppets.mp3');

    // use only one of the following code lines

    // add the click event where wavesurfer has scope.
    playButton.addEventListener("click",function(){wavesurfer.playPause()});

    // for the purists :P
    document.getElementById("playButton").addEventListener("click", function(){wavesurfer.playPause()});

});