Unable to change video attr. How to fix it? - javascript

I was working on a menu to change my videojs source and it works partly. I can change my video source with $video_obj.src but i unable to change my tags like nonHD or even classes style .vjs-poster.
something I forgot?
$("ul.dl-menu a").click(function() {
var $myClass = $(this).attr("class");
var $target = $(this).attr("id");
var $content_path = "~path~/media-video/";
var $thumbs = "~path~/media-video/thumbs/";
if ($myClass === "library") {
var $vid_obj = videojs("div_video");
var $video_div = "div_video";
}
else {
var $vid_obj = videojs("div_video_awards");
var $video_div = "div_video_awards";
}
$vid_obj.ready(function() {
$($video_div+'.poster').hide();
$($video_div+'_html5_api').hide();
$vid_obj.pause();
$($video_div+'video source:nth-child(1)').attr("src",$content_path+'mp4/'+$target+'.mp4');
$vid_obj.src({ type: "video/mp4", src: $content_path+'mp4/'+$target+'.mp4' });
$($video_div+'video').attr("src",$content_path+'mp4/'+$target+'.mp4');
$($video_div).attr("nonHD",$content_path+'mp4/'+$target+'.mp4');
$($video_div).attr("HD",$content_path+'mp4-720p/'+$target+'.mp4');
$($video_div+'video').attr("HD",$content_path+'mp4-720p/'+$target+'.mp4');
$($video_div+'video').attr("nonHD",$content_path+'mp4/'+$target+'.mp4');
$($video_div+'.vjs-poster').attr("style", 'background-image: url('+$thumbs+$target+'.jpg);');
$($video_div+'.vjs-tech').attr("poster",$thumbs+$target+".jpg").show();
$($video_div).attr('poster',$thumbs+$target+'.jpg');
$($video_div).removeClass('vjs-playing').addClass('vjs-paused');
var css = document.createElement("style");
css.type = "text/css";
css.innerHTML = ".vjs-control.vjs-HD-button { color: silver; font-weight:normal; text-shadow: 0 0 5em #fff;}";
document.body.appendChild(css);
HD1 = false;
$vid_obj.load();
$($video_div+'_html5_api').show();
setTimeout(function(){
$vid_obj.play();
}, 0);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video id="div_video" class="video-js vjs-sublime-skin vjs-big-play-centered" width="auto" height="auto" poster="http://video-js.zencoder.com/oceans-clip.png" HD="http://video-js.zencoder.com/oceans-clip.mp4" nonHD="http://video-js.zencoder.com/oceans-clip.mp4" controls>
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type="video/mp4">
</video>
<div id="dl-menu" class="dl-menuwrapper">
<button class="dl-trigger">Menu</button>
<ul class="dl-menu">
<li><a class="library" href="javascript:;" id="MBHD0790-03">Into the Woods</a></li>
<li><a class="library" href="javascript:;" id="MBHD0790-04">Kingsman</a></li>
</ul>
</div>

Well, given this:
$($video_div+'video').attr("nonHD",$content_path+'mp4/'+$target+'.mp4');
you'd be doing
$('video_divvideo').attr(....);
There's no #, so javascript will be looking for a tag like <video_divvideo> in the dom, which of course doesn't exist.
Maybe you want
$('#' +$video_div).attr(...);
instead?

Related

How to perform jquery script only once?

I use the isInViewport script to play the video on scroll, but it doesn't look very good because it happens multiple times. Please tell how to limit the triggering of animation or video playback to literally once. Tried to add with one() and true/false but the code didn't work (I still green in jquery).
<div class="block"><span>Video below</span></div>
<div class="block video-block">
<video class="video" loop="loop" width="640" controls="controls" muted>
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.mp4" type="video/mp4" />
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.ogv" type="video/ogv" />
<source src="http://denis-creative.com/wp-content/uploads/2018/01/video.webm" type="video/webm" />
</video>
</div>
<div class="block"><span>Video above</span></div>
.block{
height: 100vh;
font-size: 60px;
text-align: center;
display: flex;
}
.block > *{
margin: auto;
display: inline-block;
max-width: 100%;
}
// Plugin isInViewport
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("jquery"),require("window")):"function"==typeof define&&define.amd?define("isInViewport",["jquery","window"],n):n(e.$,e.window)}(this,function(e,n){"use strict";function t(n){var t=this;if(1===arguments.length&&"function"==typeof n&&(n=[n]),!(n instanceof Array))throw new SyntaxError("isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions");return n.forEach(function(n){"function"!=typeof n?(console.warn("isInViewport: Argument(s) passed to .do/.run should be a function or an array of functions"),console.warn("isInViewport: Ignoring non-function values in array and moving on")):[].slice.call(t).forEach(function(t){return n.call(e(t))})}),this}function o(n){var t=e("<div></div>").css({width:"100%"});n.append(t);var o=n.width()-t.width();return t.remove(),o}function r(t,i){var a=t.getBoundingClientRect(),u=a.top,c=a.bottom,f=a.left,l=a.right,d=e.extend({tolerance:0,viewport:n},i),s=!1,p=d.viewport.jquery?d.viewport:e(d.viewport);p.length||(console.warn("isInViewport: The viewport selector you have provided matches no element on page."),console.warn("isInViewport: Defaulting to viewport as window"),p=e(n));var w=p.height(),h=p.width(),v=p[0].toString();if(p[0]!==n&&"[object Window]"!==v&&"[object DOMWindow]"!==v){var g=p[0].getBoundingClientRect();u-=g.top,c-=g.top,f-=g.left,l-=g.left,r.scrollBarWidth=r.scrollBarWidth||o(p),h-=r.scrollBarWidth}return d.tolerance=~~Math.round(parseFloat(d.tolerance)),d.tolerance<0&&(d.tolerance=w+d.tolerance),l<=0||f>=h?s:s=d.tolerance?u<=d.tolerance&&c>=d.tolerance:c>0&&u<=w}function i(n){if(n){var t=n.split(",");return 1===t.length&&isNaN(t[0])&&(t[1]=t[0],t[0]=void 0),{tolerance:t[0]?t[0].trim():void 0,viewport:t[1]?e(t[1].trim()):void 0}}return{}}e="default"in e?e.default:e,n="default"in n?n.default:n,/**
* #author Mudit Ameta
* #license https://github.com/zeusdeux/isInViewport/blob/master/license.md MIT
*/
e.extend(e.expr[":"],{"in-viewport":e.expr.createPseudo?e.expr.createPseudo(function(e){return function(n){return r(n,i(e))}}):function(e,n,t){return r(e,i(t[3]))}}),e.fn.isInViewport=function(e){return this.filter(function(n,t){return r(t,e)})},e.fn.run=t});
//# isInViewport
// Play Video
$(function() {
var $video = $('.video');
var $window = $(window);
$window.scroll(function() {
if ($video.is(":in-viewport")) {
$video[0].play();
} else {
$video[0].pause();
}
});
});
You could add a var to check if the video is still playing (for example is_playing) and check it with an inner if:
$(function() {
var $video = $('.video');
var $window = $(window);
var is_playing = false;
$window.scroll(function() {
if ($video.is(":in-viewport")) {
if (!is_playing) {
is_playing = true;
$video[0].play();
}
} else {
$video[0].pause();
}
});
});

eventListener to alter between two elements

What I want is whenever I mouseover on an element for it to set the style of video to display: none; and then the img to display: block;
Here's my code:
Javascript
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("container").addEventListener("mouseenter", function(event) {
alternate(event);
});
document.getElementById("container").addEventListener("mouseout", function(event) {
alternate(event);
});
function alternate(e) {
var target = e.target || e.srcElement;
if (target) {
if (target.nodeName == "IMG") {
target.querySelector(".video").style.display = "block";
target.querySelector(".img").style.display = "none";
} else if (target.nodeName == "VIDEO") {
target.querySelector(".video").style.display = "none";
target.querySelector(".img").style.display = "block";
}
}
}
});
HTML
<div id="container">
<li>
<div>
<video class="video" src="./test.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="./test.jpg"></img>
</div>
</li>
<li>
<div>
<video class="video" src="./test.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="./test.jpg"></img>
</div>
</li>
</div>
Essentially what I am trying to achieve is whenever I mouseout from the video, put the image back and then back from. video: hidden, image:shown to video:shown, image:hidden.
I did manage to get something working by using the target.previousSibling technique but it didn't work 100%,
Hopefully I formatted this question right, thank you for reading. Any help is really appreciated.
You could achieve this with pure CSS. A very simple approach would be:
.hover-toggle {
position: relative;
}
.hover-toggle .video {
/* Use absolute positioning to place video along-side image */
position: absolute;
top: 0;
left: 0;
/* Set video to be transparent by default */
opacity: 0;
}
/* When hovering the transparent video, cause it to become opaque */
.hover-toggle .video:hover {
opacity: 1;
}
<div class="hover-toggle">
<video class="video" src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="https://via.placeholder.com/320x176" />
</div>
<div class="hover-toggle">
<video class="video" src="https://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" muted autoplay></video>
<img class="img" src="https://via.placeholder.com/320x176" />
</div>
mouseenter and mouseleave are the proper events to use.
If you use <li> then you must use <ol> or <ul> as the parent.
Register the events to each <li>
const items = document.querySelectorAll('li');
for (let item of items) {
item.addEventListener('mouseenter', alternate);
item.addEventListener('mouseleave', alternate);
}
Define the event handler using e.target and .matches('li') to insure that the events only apply to <li>. Then use e.type to insure that only mouseenter and mouseleave` events apply.
const tgt = e.target;
const evt = e.type;
if (tgt.matches('li')) {
if (evt === 'mouseenter') {
...
else if (evt === 'mouseleave') {
...
}
The reason why target.previousSibling worked some of the time is because display: none removes elements from the flow thereby not being recognized as a sibling. Try assigning a class that has visibility and z-index properties and alternate that class between events.
tgt.children[0].classList.add('on');
tgt.children[1].classList.remove('on');
// and vice versa
BTW <img> tags are void elements (no end tag </img>)
const items = document.querySelectorAll('li');
for (let item of items) {
item.addEventListener('mouseenter', alternate);
item.addEventListener('mouseleave', alternate);
}
function alternate(e) {
const tgt = e.target;
const evt = e.type;
if (tgt.matches('li')) {
if (evt === 'mouseenter') {
tgt.children[0].classList.add('on');
tgt.children[1].classList.remove('on');
} else if (evt === 'mouseleave') {
tgt.children[1].classList.add('on');
tgt.children[0].classList.remove('on');
} else {
return false;
}
}
return false;
}
li {
position: relative;
height: 135px;
}
li * {
visibility: hidden;
position: absolute;
z-index: -1;
top: 0;
left: 0;
}
.on {
visibility: visible;
z-index: 1;
}
<ul>
<li>
<video src='https://storage04.dropshots.com/photos6000/photos/1381926/20170326/005610.mp4' muted autoplay loop width='240' height='135'></video>
<img class='on' src='https://branditprintit.com/wp-content/uploads/2017/04/logo-degin-logo-design-design-art-free.png' width='240' height='135'>
</li>
<li>
<video src='https://storage04.dropshots.com/photos6000/photos/1381926/20170326/005609.mp4' muted autoplay loop width='240' height='135'></video>
<img class='on' src='https://branditprintit.com/wp-content/uploads/2017/04/logo-degin-logo-design-design-art-free.png' width='240' height='135'>
</li>
</ul>

Change video of video tag on scroll

I have a video tag say
<div class="phone" align="center">
<div class="phone-inner">
<video width="100%" height="100%" autoplay="" loop="" muted id="phonevideo">
<source src="vid/1.mp4" type="video/mp4">
</video>
</div>
</div>
I want to change the video when page scrolls and each time div changes like fueled.com. Say I have six divisions like
<div id="first></div>
<div id="two"></div>
<div id="three"></div>
<div id="four"></div>
<div id="five"></div>
<div id="six"></div>
When div 2 comes into view the video should change and when div 3 or 4 comes into view video should change again to something else. Here is my code which needs to be modified according to it.
$(window).scroll(function() {
var topDivHeight = $("#first").height();
var DivTop = $("#sixth").position().top;
var viewPortSize = $(window).height();
var triggerAt = 450;
var triggerHeight = (topDivHeight - viewPortSize) + triggerAt;
var test1 = (topDivHeight - viewPortSize) + 650;
var count = 0;
var number = jQuery.grep(mainTops, function(n, i) {
if (n < $(window).scrollTop())
{
count++;
}
});
$('.nav ul li a').css("color", "#fff");
$('.nav ul li a#nav'+count ).css("color", "#f60");
if($(window).scrollTop() >= triggerHeight && $(window).scrollTop() < DivTop) {
$('.phone').css('visibility', 'visible').fadeIn();
if($(window).scrollTop() >= test1){
$('#phonevideo').html('<source src="vid/2.mp4" type="video/mp4">'); // tried using this method but its not working here. Some other method needed here.
}
} else {
$('.phone').fadeOut();
}
});
Try this code:
$('#phonevideo').find("source").attr("src", "https://www.w3schools.com/tags/movie.mp4");
$('#phonevideo').get(0).load();
You can change source attribute like $('#phonevideo').find("source").attr("src","videosource")
and after changing source you need to load video $('#phonevideo').get(0).load()
You cannot directly replace the HTML as you do using function .html(), accordingly to the HTML specification
Dynamically modifying a source element and its attribute when the
element is already inserted in a video or audio element will have no
effect.
But what you can try as suggested by the document is to change what is playing, just use the src attribute on the media element directly and use function .load();
A working example below:
var btn = document.getElementById('btn'),
player = document.getElementById('phonevideo'),
source = document.getElementById('src');
btn.addEventListener('click', function(event) {
player.pause();
source.src = 'http://html5demos.com/assets/dizzy.mp4'; // change video
player.load(); // load it
});
<div class="phone" align="center">
<div class="phone-inner">
<video width="100%" height="100%" autoplay="" loop="" muted id="phonevideo">
<source id="src" src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4" type="video/mp4">
</video>
</div>
</div>
<button id="btn" type="button">Change Video!</button>
Using jQuery as on your example (not tested):
var player = $('#phonevideo');
player.find("source").attr("src", "http://html5demos.com/assets/dizzy.mp4");
player[0].load();
I've optimized your code. I have added a class to your divs and used the data attribute. Here is a working jsfiddle.
<div class="phone" align="center">
<div class="phone-inner">
<video width="100%" height="100%" autoplay="" loop="" muted id="phonevideo">
<source src="vid/1.mp4" type="video/mp4">
</video>
</div>
</div>
<div id="first" class="view" data-vid-src="vid/1.mp4"></div>
<div id="two" class="view" data-vid-src="vid/2.mp4"></div>
<div id="three" class="view" data-vid-src="vid/3.mp4"></div>
<div id="four" class="view" data-vid-src="vid/4.mp4"></div>
<div id="five" class="view" data-vid-src="vid/5.mp4"></div>
<div id="six" class="view" data-vid-src="vid/6.mp4"></div>
To see some result I have added some css:
.phone {
position: fixed;
height: 200px;
width: 120px;
background: white;
top: 50%;
left: 50%;
margin-top: -100px;
margin-left: -60px;
}
.view {
height: 500px;
}
#first {
background: red;
}
#two {
background: yellow;
}
#three {
background: green;
}
#four {
background: blue;
}
#five {
background: pink;
}
#six {
background: black;
}
And now the jQuery part.
function getCurrentElement(pos) {
var len = $('.view').length;
var i = 0;
var old_pos;
var ele_pos;
var old_ele;
var return_ele;
$('.view').each(function(){
i++;
offset = $(this).offset();
ele_pos = offset.top;
if(pos == ele_pos) {
return_ele = $(this);
return;
}
else if(ele_pos > pos && old_pos < pos) {
return_ele = old_ele;
return;
}
else if(ele_pos < pos && i == len) {
return_ele = $(this);
return;
}
old_pos = ele_pos;
old_ele = $(this);
});
return return_ele;
}
var old_ele = null;
$(window).scroll(function() {
var cur_pos = $(window).scrollTop();
current_element = getCurrentElement(cur_pos);
if(old_ele != null) {
if(current_element.attr('id') != old_ele.attr('id')) {
$('#phonevideo source').attr('src',current_element.attr('data-vid-src'))
}
}
old_ele = current_element;
});
I hope this code will help you. :)

jQuery: Multiple audio player buttons

I would like to make 4 play buttons which plays mp3 audio. The play function is working every 4 buttons, but unfortunately the pause is not working for either of them. Maybe the pause condition is wrong?
<div class="audio-button">
<audio src="media/test.mp3"></audio>
</div>
<div class="audio-button">
<audio src="media/test2.mp3"></audio>
</div>
<div class="audio-button">
<audio src="media/test3.mp3"></audio>
</div>
<div class="audio-button">
<audio src="media/test4.mp3"></audio>
</div>
$(document).ready(function() {
var playing = false;
$('.audio-button').click(function() {
$(this).toggleClass("playing");
var song = $(this).find('audio').attr('src');
var audio = new Audio(song);
if (playing == false) {
audio.play();
playing = true;
} else {
audio.pause();
playing = false;
}
});
});
You need to grab the audio element directly from the button as a child and interact with that. You do not need to clone the Audio object using a constructor.
$(document).ready(function() {
var playing = false;
// Add file names.
$('.audio-button').each(function() {
var $button = $(this);
var $audio = $button.find('audio');
$($('<span>').text($audio.attr('src'))).insertBefore($audio);
});
// Add click listener.
$('.audio-button').click(function() {
var $button = $(this);
var audio = $button.find('audio')[0]; // <-- Interact with this!
// Toggle play/pause
if (playing !== true) {
audio.play();
} else {
audio.pause();
}
// Flip state
$button.toggleClass('playing');
playing = !playing
});
});
.fa.audio-button {
position: relative;
display: block;
width: 12em;
height: 2.25em;
margin-bottom: 0.125em;
text-align: left;
}
.fa.audio-button:after {
position: absolute;
right: 0.8em;
content: "\f04b";
}
.fa.audio-button.playing:after {
content: "\f04c";
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="fa audio-button">
<audio src="media/test.mp3"></audio>
</button>
<button class="fa audio-button">
<audio src="media/test2.mp3"></audio>
</button>
<button class="fa audio-button">
<audio src="media/test3.mp3"></audio>
</button>
<button class="fa audio-button">
<audio src="media/test4.mp3"></audio>
</button>
do you want to stop the other three when one is clicked?
If so you can try:
$(document).ready(function () {
$('.audio-button').click(function (e) {
var button = $(e.target).closest('.audio-button');
var audio = button.find('audio');
var audioDom = audio.get(0);
$('audio[data-is-playing]').not(audio).each(function (i, currentAudioDom) {
var currentButton = $(currentAudioDom).closest('.audio-button');
currentButton.removeClass('playing');
currentButton.removeAttr('data-is-playing');
currentAudioDom.$audio.pause();
});
button.addClass('playing');
audio.attr('data-is-playing', '');
audioDom.$audio = audioDom.$audio || new Audio(audio.attr('src'));
audioDom.$audio.play();
});
});
Fix:
Actually I'm not sure if the audio element is an Audio Object in itself, if so, you can call the play/pause directly on the audioDom/currentAudioDom elements and forget about the $audio thing...

Place Div on top of video using javascript

I have several kinds of videos, like this
<video id='abd' height="200" width="200" ></video>
<embed id='bcd' height="200" width="200" ></embed>
<object id='cde' height="200" width="200" ></object>
I have calculated target position like this
<script>
var vid=document.getElementById('abd');
var width = vid.offsetWidth;
var height = vid.height;
var x = width/2+ 'px';
var y = height - 12+'px';
var div = '<div>Heloo</div>';
</script>
Now i want to put a div at position (x,y).
How can i do this. div is stored in var div, Is there any way to do this perfectly,
Your help will be greatful
Thanks
You can do this using pure CSS - no JS required!
The HTML
<div id="video-container">
<iframe width="420" height="315" src="//www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen> </iframe>
<div class="video-overlay">
Overay Content
</div>
</div>
The CSS
#video-container {
position:relative;
width:420px;
}
.video-overlay {
position:absolute;
top:50px;
right:50px;
background:#000;
color:#FFF;
}
See it in action
http://jsfiddle.net/y28Zs/
try this
http://jsfiddle.net/miquelcamps/BJN8x/3/
html
<video id="embed" width="200" height="200" controls>
<source src="http://vjs.zencdn.net/v/oceans.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
javascript
var vid = document.getElementById('embed');
var width = vid.width;
var height = vid.height;
var x = vid.offsetLeft;
var y = vid.offsetTop;
var div = '<div class="overlay" style="height:'+height+'px;width:'+width+'px;left:'+x+'px;top:'+y+'px;">Hello</div>';
document.body.innerHTML += div;
css
.overlay{
position:absolute;
background:red;
z-index:99;
}
Please check is it what you want :
<div id="adds">
<video id='abd' height="200" width="200" style="border:2px solid" ></video>
</div>
Javascript ----
vid=document.getElementById('abd');
addDiv =document.getElementById('adds');
var width = vid.offsetWidth;
var height = vid.height;
var x = width/2+ 'px';
var y = height - 12+'px';
var newDiv = document.createElement("div");
newDiv.innerText = "Hello....";
newDiv.style.left = "102px";
newDiv.style.top = "108px";
newDiv.style.position = "absolute";
addDiv.appendChild(newDiv);
Live demo : (http://jsfiddle.net/7EhtL/)

Categories

Resources