Initialize WaveSurfer targeting the container div

2019-03-03 05:17发布

问题:

I am trying to create waveform using wavesurfer.js for dynamically created elements using JavaScript. Here is my code:

$(document).ready(function() {
  var id = 9;

  $("#audio").append('<div class="row" id="wave' + id + '"></div>');

  $('#audio').on('DOMNodeInserted', 'div', function() {
    var selectedId = $(this).prop('id');

    console.log(selectedId);
    window['waveForm' + selectedId] = Object.create(WaveSurfer);
    window['waveForm' + selectedId].init({
      container: $(this),
      waveColor: 'violet',
      progressColor: 'purple'
    });

    window['waveForm' + selectedId].on('ready', function() {
      window['waveForm' + selectedId].play();
    });

    window['waveForm' + selectedId].load(selectedId + '.mp3');
  });
});

console.log displays the correct id of the element, so the selector seems to work, however wavesurfer.js gives the following error:

Uncaught TypeError: this.container.appendChild is not a function

回答1:

Sorry, I was at work on break before and couldn't get into it that deep.But try not to open duplicate questions it is better to update the question as we work through the issue (unless of course a totally different problem emerges)

The below is a functional fully commented implementation of what you are trying to do with a bit simpler of an approach.

Here's a copy hosted on my server to avoid the cross domain issues

jQuery

// create a global array to hold our WaveSurfers
var WaveSurfers=[];

$(document).ready(function(){
  // add your element
  // dont give any of them ids
  $("#audio").append('<div class="row needsWave"></div>');

  // call the function we will define in a second
  // pass in the path to your file
   addWaveSurfer('http://dodsoftware.com/sotests/wavesurfer/minecraftrap.mp3');
});

function addWaveSurfer(path){
    // create instance of WaveSurfer
    var tempWavesurferObject = Object.create(WaveSurfer);
        // initialize the object 
        // ".needsWave:last" gets the last element with the class "needsWave"
        // which will be the element we just added
    tempWavesurferObject.init({
            container: $( ".needsWave:last" )[0],// "[0]" gets the DOM element from the jQuery object
            waveColor: 'violet',
            progressColor: 'purple'
          });
        tempWavesurferObject.on('ready', function () {
            tempWavesurferObject.play();
        });
        tempWavesurferObject.load(path); // load the file we passed in
    // add the WaveSurfer to the global array so we can keep up with it
    WaveSurfers.push(tempWavesurferObject);

    // below shows how to access the WaveSurfers later by stoping the playback after a few seconds
     setTimeout(function(){
          var last = WaveSurfers.length-1; // get index of last WaveSurfer element
          WaveSurfers[last].stop();
     }, 10000);

}

Html

<script src="https://cdn.rawgit.com/katspaugh/wavesurfer.js/master/dist/wavesurfer.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="audio"></div>


回答2:

From the github of wavesurfer.js, the container parameter in the init function is described as following:

CSS-selector or HTML-element where the waveform should be drawn. This is the only required parameter.

It doesn't mention whether or not a jQuery object is accepted, so try replacing $(this) with this:

window['waveForm' + selectedId].init({
  container: this, // or container: '#audio'
  waveColor: 'violet',
  progressColor: 'purple'
});