0

I have a container on my site where I dynamically inject new content via jQuery Ajax/XHR whenever a certain type of link is clicked.

For some pages this container holds a grid with multiple HTML5 <video> elements playing in a loop.

At a certain point I was experiencing increasing performance drops after a few XHR requests which replace content inside the container. After unmuting my videos, I recognized only through the Audio coming from my speakers that they actually keep playing, even if they are completely removed from the DOM(which means I had tons of videos playing after a few XHR replacements within my container, videos which actually aren’t in the DOManymore).

I tried a few things now, none of which seem to help:

  • Using jQuery’s .remove() on all videos before the XHR request to remove the videos from the DOM before I inject new content
  • Pausing the videos via Javascript before loading new content

This only seems to work randomly, which drives me crazy. Sometimes some or alle videos keep playing somewhere from the off, overlapping with the new video content. Also, they are not showing up in Chrome DevTool’S Network Tab …

I have the feeling that due to buffering stuff just classic DOM-querying and manipulation doesn’t work here … Any hint of what I could put into my pre-XHR request function to make sure ANY current <video> content from the DOM (and off, in the buffer and elsewhere) is really a 100% removed, in other words 'killed’?

EDIT: Here is a simplified demo of my problem, try clicking the links which exchange the content of the div with the ID #content http://www.letrip.de/html5video-problem/

You can see the Javascript by adding /js/app.js to the URL

Tobias S.
  • 3
  • 4
  • One thing I can also see from the console with using `.pause()`, or setting `src` to an empty string (a 'hack' I saw recommended somewhere) is that the newly added `video` elements seem to be `undefined` after the first XHR request. Which is odd to me, as they are newly injected, yes, however my `function` addressing them is global, thus should target them correctly (?), even if they are new to the DOM – Tobias S. Sep 21 '17 at 16:38

3 Answers3

0

Add video as a template.. and assign this template to a variable and use it, make it null when you want to remove it.

Ex. Var vdo=

Do your manipulations and then make it null

Vdo = null;

RVCoder
  • 522
  • 4
  • 14
  • I’m sorry I can only guess what you mean … But my videos are coming in as pre-rendered HTML – Tobias S. Sep 21 '17 at 15:33
  • Then once you are done, you can call video.pause and remove src property method as you said video was still playing – RVCoder Sep 21 '17 at 15:44
  • Ok, what do you actually mean by "add video as a template"? Could you give a more specific code example? Do you mean appending the video element to the DOM via JS and not having it there at all in the HTML source code? – Tobias S. Sep 21 '17 at 15:59
  • We have faced similar situation we added and removed video element dynamically.. and yes i meant appending video element using js.. – RVCoder Sep 21 '17 at 16:55
  • Thanks so far, @RashmiVishwakarma, I will give this a try as a last solution in case I can’t find out why the regular exchange of the content via Ajax does not behave as expected. – Tobias S. Sep 22 '17 at 11:32
0

change:


    var content = $(data).find('#content');
    html = content.html();
    $('#content').html(html);

to:


     var = content = $("#content",data);
     $('#content').html(content);

Best regards

UPDATE As soon as you do this: $(data) the problem will return. Try to do this to return the title:


     var titledata = data.match("(.*?)")[1];
     console.log(titledata);

Steffen Görg
  • 372
  • 1
  • 5
  • Thanks, that’s the solution that worked for me! Obviously I was having HTML content that’s no longer in the DOM after a XHR request (as expected) but somehow still has the ability to play its videos from that uncertain memory location. With your code the "old" HTML code doesn’t seem to stay in memory but is hard overwritten I suppose. – Tobias S. Sep 25 '17 at 10:45
  • Strangely enough the problem appears again after I parse my `data` object for the `` of the requested site within the same function like so: `var newTitle = $(data).filter('title').text();` and then `document.title = newTitle;` – Tobias S. Sep 25 '17 at 11:19
  • Yep, same thing :) the video on the html is set to autoplay and is represented as full functional html. As soon as you process it, the audio will play and will keep playing. Try this instead: var titledata = data.match("(.*?)")[1]; console.log(titledata); – Steffen Görg Sep 25 '17 at 15:34
  • Here is a pretty good explanation of the problem. The dom element is created but not rendered. as soon as you create it, the audio will play. https://stackoverflow.com/questions/26876256/why-are-videos-played-before-inserted-into-dom?rq=1 – Steffen Görg Sep 25 '17 at 16:00
  • I think the fastest method to deal with this problem ist to remove the autoplay attribute from the video tag. Simply add them with javascript after loading :). – Steffen Görg Sep 25 '17 at 16:09
  • This is it (the problem nailed). Will stick to keeping `autoplay` removed and manually doing `play()` and `pause()` on the videos. Thanks! – Tobias S. Sep 26 '17 at 18:10
0

Just adding what worked for me, i had couple of videos in container and even after completely removing container from the DOM, video sound kept playing.

I even tried to remove video elements from the dom before removing container, but it didn't help.

Here is what worked for me.

Step 1 - Set src property to empty string instead of removing it

This won't work -

video.removeAttribute("src");

This will work

video.src="";

Step 2 - Load video Once you have set src to empty string simply call video.load().

In short

video.src="";
video.load();
Gulam Hussain
  • 1,591
  • 10
  • 19