mediaelement.js control sizes are wrong when clip nested in a hidden element

Posted by Martin Francis on Stack Overflow See other posts from Stack Overflow or by Martin Francis
Published on 2013-11-02T03:01:04Z Indexed on 2013/11/02 3:53 UTC
Read the original article Hit count: 318

Filed under:

It's a nasty one this.

In an audio control placed within a container element whose display property is initially set to none, the audio clip does NOT correctly size the progress bar when it is initialised. This is clear when the container's display property is changed from 'none' to '' (which is equivalent to 'static').

But who would ever do that?

I make extensive use of 'tabbed' display arrangements on community sites like this one: http://www.churchesInBracebridge.ca

Owing to the page arrangement, the audio controls which you see under 'sermons' (which at the time of writing still using Flash rather than John's excellent library here) are initially rendered in a div that is hidden.


Simplified Test case

Rather than have anyone have to wade through all of that, here's a much simplified test case: http://jsfiddle.net/sJL6T/36

Showing the effect of rendering an audio clip in a div which is initially hidden

Here's the full page source for those who'd prefer to work with it that way.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
  <title>MediaElementPlayer.js</title>
  <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script src="http://mediaelementjs.com/js/mejs-2.13.1/mediaelement-and-player.js"></script>
  <link rel="stylesheet" href="http://mediaelementjs.com/js/mejs-2.13.1/mediaelementplayer.css" />
  <script type="text/javascript">
    function toggle(id){
      document.getElementById(id).style.display=
        (document.getElementById(id).style.display=='none' ? '' : 'none');
    }
  </script>
</head>
<body>
<h1>MediaElementPlayer.js</h1>

<h2 onclick="return toggle('test1')">Initially Hidden (Click to toggle)</h2>
<div id='test1' style='display:none'>
<audio controls="controls">
  <source src="http://mediaelementjs.com/media/AirReview-Landmarks-02-ChasingCorporate.mp3" type="audio/mp3" />
</audio>
</div>

<h2 onclick="return toggle('test2')">Initially Shown (Click to toggle)</h2>
<div id='test2' style=''>
<audio controls="controls">
  <source src="http://mediaelementjs.com/media/AirReview-Landmarks-02-ChasingCorporate.mp3" type="audio/mp3" />
</audio>
</div>

<script>
$('audio').mediaelementplayer();
</script>

</body>
</html>

Possible Workarounds

Now I know that Google maps has the same quirk and there are two possible ways I've used to deal with that:

  1. Use absolute positioning in a displayed div to place the element 10,000px to the left then bring it onto the stage when we want to see it
  2. Have the map pane displayed when loading then hide it as soon as it's loaded (ugly I know, but it usually works)

However either approach would be a pain to do, as I have a lot of legacy code using the simpler div hiding method.

I know that JQuery can get the dimensions of an element event if it is hidden - someone thoughtfully fiddled that and it does work: http://jsfiddle.net/sJL6T/9

Perhaps it may be possible to modify the actual library to find correct dimensions, even if the container itself is hidden? That would be wonderful, if it can be done!

Initial experiments on mediaelement-and-player.js code

I found that when I provided a fixed value in the setControlsSize function for railWidth, I got consistent results with both controls in the test case above (and obviously I'm working with my own copy of the library to do that, not the one stored at mediaelementjs.com):

            // outer area
            rail.width(railWidth);

Change to this:

            // outer area
            railWidth=216;
            rail.width(railWidth);

Many thanks in anticipation!

Martin Francis <><

© Stack Overflow or respective owner

Related posts about mediaelement.js