Basically one of my scripts work but the other one doesn't. I am trying to customize the play button functions with javascript but whenever I try to load the script it seems like the script has no effect on the video.
I have checked the code itself and even went back to the index.html to see if I made any errors with the tags. I also found out after inspecting the script is not there but it's declared in the index.html.
index.html
<div class="container">
<div class="c-video">
<video class="video" src="stranding.mp4"></video>
<div class="controls">
<div class="orange-bar"></div>
<div class="orange-juice"></div>
<div class="buttons">
<button id="play-pause"></button></div>
</div>
</div>
</div>
<script src="script.js"></script>
<script src="alert.js"></script>
________________________________________________________________________
var video = document.querySelector("video");
var juice = document.querySelector("orange-juice");
var btn = document.getElementById("play-pause");
function togglePlayPause() {
if(video.paused){
btn.className = "pause";
video.play();
} else {
btn.className = "play";
video.pause();
}
}
btn.onclick = funtion() {
togglePlayPause();
};
________________________________________________________
stye.css
.buttons button.play:before {
content: "\fo4b";
}
.buttons button.pause:before {
content: "\f04c";
}
.orange-bar{
height: 10px;
top: 0;
left: 0;
width: 100%;
}
.orange-juice{
height: 10px;
background-color: silver;
}
I want the script to cause the video to play/pause but it doesn't.
You are incorrectly taking the reference of the Play/Pause button.
Instead of:
document.getElementById(".play-pause");
use
document.getElementById("play-pause");
You are using the "." class selector in document.getElementsById
var btn = document.getElementById(".play-pause");
Without seeing the HTML and knowing exactly what is going on, try
var btn = document.getElementById("play-pause");
Related
Hello everybody I have this code that I have made alone.
function appearafter() {
document.getElementById("buttonappear").style.display = "block";
document.getElementById("button").style.display = "block";
document.getElementById("hinzufuegen").style.display = "none";
function myFunction() {
var itm = document.getElementById("myList2").lastChild;
var cln = itm.cloneNode(true);
document.getElementById("myList1").appendChild(cln);
}
function allFunction() {
myFunction();
appearafter();
}
#button {
display: none;
}
#buttonappear {
display: none;
}
#test {
width: 300px;
height: 300px;
background-color: red;
}
<!DOCTYPE html>
<html>
<body>
<button id="hinzufuegen" onclick="allFunction()">ADD</button>
<div id="myList1">
<button id="button" onclick="">DELETE</button>
<div id="myList2">
<div id="test">
</div>
</div>
</div>
<button onclick="allFunction()" id="buttonappear">ADD</button>
</body>
</html>
What I want to make is that the red square whenever you are clicking on the ADD button it will be a clone and when you click on the DELETED button that the clone is deleted. Can somebody help me, please?
In addition to missing } as was mentioned in the comments, there was a not-so-obvious problem with finding the <div> to clone. The lastChild was actually a text node containing the \n (newline), after the <div>. It's better to search for <div> by tag:
var itm = document
.getElementById('myList2')
.getElementsByTagName('div')[0];
Since there's only one <div> we can use the zero index to find this first and only one.
And for delete function you can use a similar approach and get the last <div> and remove it.
function appearafter() {
document.getElementById("buttonappear").style.display = "block";
document.getElementById("button").style.display = "block";
document.getElementById("hinzufuegen").style.display = "none";
}
function myFunction() {
var itm = document.getElementById("myList2").getElementsByTagName("div")[0];
var cln = itm.cloneNode(true);
document.getElementById("myList1").appendChild(cln);
}
function deleteFunction() {
var list1 = document.getElementById("myList1");
var divs = Array.from(list1.getElementsByTagName("div"));
// If the number of divs is 3, it means we're removing the last
// cloned div, hide the delete button.
if (divs.length === 3) {
document.getElementById("button").style.display = "none";
}
var lastDivToDelete = divs[divs.length - 1];
list1.removeChild(lastDivToDelete);
}
function allFunction() {
myFunction();
appearafter();
}
#button {
display: none;
}
#buttonappear {
display: none;
}
#test {
/* make it smaller so it's easier to show in a snippet */
width: 30px;
height: 30px;
background-color: red;
}
<button id="hinzufuegen" onclick="allFunction()">ADD</button>
<div id="myList1">
<button id="button" onclick="deleteFunction()">DELETE</button>
<div id="myList2">
<div id="test"></div>
</div>
</div>
<button onclick="allFunction()" id="buttonappear">ADD</button>
I'm trying to use the <audio> tag, and I want to have as many tracks playing as I add. But now they play at the same time, can I somehow make them play sequentially?
<audio id="audio1" preload="" autoplay="" loop="" type="audio/mp3" src="music/mus1.mp3"></audio>
<audio id="audio2" preload="" autoplay="" loop="" type="audio/mp3" src="music/mus.mp3"></audio>
<div id="pp" style="cursor: pointer;" onclick="pVid();"><img src="img/heart.png"></div>
<script type="text/javascript">
function pVid() {
var audio1 = document.getElementById("audio1");
var audio2 = document.getElementById("audio2");
audio1.paused ? audio1.play() : audio1.pause();
audio2.paused ? audio2.play() : audio2.pause();
}
</script>
I found one solution, it works but not the way I want
var sounds = new Array(new Audio("music/mus1.mp3"), new Audio("music/mus.mp3"));
var i = -1;
pVid();
function pVid() {
i++;
if (i == sounds.length) return;
sounds[i].addEventListener('ended', pVid);
sounds[i].play();
}
Here everything just plays right away, but I want to be able to play the tracks myself through the button and pause at any time. This is done in the first version, but there all the tracks play at the same time
Use audio events as much as possible. We can use freesound.org for testing.
let sounds = new Array(new Audio("https://freesound.org/data/previews/46/46992_514283-lq.mp3"),
new Audio("https://freesound.org/data/previews/610/610823_13156161-lq.mp3"),
new Audio("https://freesound.org/data/previews/92/92005_1499847-lq.mp3"), new Audio("https://freesound.org/data/previews/46/46992_514283-lq.mp3"),
new Audio("https://freesound.org/data/previews/610/610823_13156161-lq.mp3"),
new Audio("https://freesound.org/data/previews/92/92005_1499847-lq.mp3"));
let current = random(0);
let paused = true;
// set event handlers on all audio objects
for (let s of sounds) {
s.addEventListener('ended', ended);
s.addEventListener('play', play);
s.addEventListener('pause', pause);
}
updateVolume()
// handle button click
function playPause() {
if (paused) {
sounds[current].play();
btn.innerText = 'pause';
paused = false;
} else {
sounds[current].pause();
btn.innerText = 'play';
paused = true;
}
}
function ended(e) {
document.getElementById(current + '').classList.remove('playing');
document.getElementById(current + '').classList.remove('paused');
/*i++;
if (i >= sounds.length) //loop
i = 0;
*/
current = random(current); // shuffle
paused = true;
playPause();
}
function play() {
document.getElementById(current + '').classList.add('playing');
document.getElementById(current + '').classList.remove('paused');
}
function pause() {
document.getElementById(current + '').classList.add('paused');
document.getElementById(current + '').classList.remove('playing');
}
function random(i) {
let next = i;
while (next == i)
next = Math.floor(Math.random() * sounds.length);
return next;
}
function updateVolume() {
for (let s of sounds) {
s.volume = volume.value;
}
}
#list {
margin-top: 1rem;
border: 1px solid gray;
width: 100px;
}
#controls {
position: fixed;
right: 2rem;
top: 1rem;
width: 50px;
}
#volume {
width: 150px;
height: 20px;
transform-origin: 75px 75px;
transform: rotate(-90deg) translateY(50%);
}
.playing {
background-color: lightblue;
}
.paused {
background-color: wheat;
}
<Button id=btn onClick='playPause()'>play</Button>
<div id=list>
<div id='0'>Guitar</div>
<div id='1'>Drum</div>
<div id='2'>Violin</div>
<div id='3'>Guitar</div>
<div id='4'>Drum</div>
<div id='5'>Violin</div>
</div>
<div id=controls>
<label for="volume">Volume</label><br>
<input id=volume type="range" id="volume" name="volume" min="0" max="1" step='.1' value='.5' onInput='updateVolume()'>
</div>
I don't know why no one mentioned the onended event
<audio id="aud1" onended="playaud2()" src="whatever.mp3"> <!--first audio-->
<audio id="aud2" src="whatever.mp3"> <!--second audio-->
<script>
//the onended event calls a function when the audio finishes playing
function playaud2() {
document.getElementById("aud2").play()}
</script>
As simple :)
Audio files
For testing, I used a few free sound-effects audio files from https://www.freesoundeffects.com.
To make it work in all browsers it is recommended by w3c to use the <audio>-tag with <source> tags.
Solution
I added some arbitrary sound files and buttons. The buttons will reset all the audios that are currently playing then play the sounds in the data-track attributes.
data-track syntax:
track-a // will play track a
track-a;track-b // will play track a followed by track b
track-a+track-b // will play track a and b simultaniously
track-a+track-b;track-c // as above but add track c to the end
You could do something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
audio {
display: block;
}
</style>
<script defer type="application/javascript">
let activeTimeout;
function init(player) {
player.innerHTML = `play ${player.dataset.label}`;
player.addEventListener('click', clickHandler);
}
function reset(audio) {
clearTimeout(activeTimeout);
audio.pause();
audio.currentTime = 0;
}
function dequeue(tracks) {
console.log("Queue:", tracks);
if (tracks.length >= 1) {
const track = tracks.pop();
const multiTrack = track.split('+');
let maxDuration = 0;
multiTrack.forEach((it) => {
const audio = document.querySelector(`[data-audio="${it}"]`);
maxDuration = Math.max(maxDuration, audio.duration);
audio.play();
});
activeTimeout = setTimeout(() => {
dequeue(tracks);
}, maxDuration * 1000);
}
}
function clickHandler(e) {
const allAudios = document.querySelectorAll('[data-audio]');
const trackAttr = this.dataset.track;
const tracks = trackAttr.split(';');
if (tracks) {
allAudios.forEach(reset);
dequeue(tracks.reverse()); // reverse to make the pop-operations faster
} else {
console.log('No track defined!');
}
}
window.addEventListener('load', function() {
const players = document.querySelectorAll('[data-player]');
players.forEach((it) => init(it));
});
</script>
</head>
<body>
<audio data-audio="applause" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_426807.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<audio data-audio="bark" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_89478.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<audio data-audio="chirp" controls="controls" preload="preload">
<source src="https://www.freesoundeffects.com/files/mp3_89489.mp3" type="audio/mp3"></source><!-- replace with your audio file -->
</audio>
<button data-player data-label="bark!" data-track="bark" />
<button data-player data-label="chirp!" data-track="chirp" />
<button data-player data-label="applause!" data-track="applause" />
<button data-player data-label="applause then bark!" data-track="applause;bark" />
<button data-player data-label="bark then chirp then bark again!" data-track="bark;chirp;bark" />
<button data-player data-label="applause then chirp!" data-track="applause;chirp" />
<button data-player data-label="applause with chirp then bark!" data-track="applause+chirp;bark" />
</body>
</html>
Yes, you can check if you have an element with a simple truthy/falsy check:
if (!slider) return;
Any mentorship or guidance would be most welcomed.
I am trying to make a vanilla JS carousel and I am so close to realising my objective to build one.
However; I cannot seem to get the prev or next buttons to move the carousel backwards or forwards. The buttons "work" they go up and down in value; they do not change the style. I can see that console logging the values.
I've tried passing the function back onto itself - however, I cannot think of a way of initialising the start frame; if that is the best way.
Adding the slideIndex value into the style rule doesn't work. What I get is if you keep on pressing "prev" for example; eventually, another frame randomly pops up below.
Any help would be very much welcomed.
On a side note - is there a better way to work with variable scoping; without everything requiring this?
'use strict';
function carousel(n) {
this.slideIndex = n;
this.slides = document.querySelectorAll('.homepage_carousel_wrapper .homepage_carousel');
[...this.slides].forEach(function(x) {
x.style.display = 'none';
});
this.slides[this.slideIndex-1].style.display = "flex";
this.prev = function(n) {
this.slideIndex += n;
if (this.slideIndex < 1) {
this.slideIndex = this.slides.length;
}
console.log(`${this.slideIndex}`);
this.slides[this.slideIndex].style.display = "flex";
}
this.next = function(n) {
this.slideIndex += n;
if (this.slideIndex > this.slides.length) {
this.slideIndex = 1;
}
console.log(`${this.slideIndex}`);
this.slides[this.slideIndex].style.display = "flex";
//carousel(this.slideIndex)
}
};
window.addEventListener('load', function() {
const hp_carousel = new carousel(3);
let carouselPrev = document.getElementById('carousel_prev');
carouselPrev.addEventListener('click', function(e){
hp_carousel.prev(-1);
e.preventDefault();
e.stopPropagation();
}, false);
let carouselNext = document.getElementById('carousel_next');
carouselNext.addEventListener('click', function(e){
hp_carousel.next(1);
e.preventDefault();
e.stopPropagation();
}, false);
});
.homepage_carousel:nth-child(1) {
background-color: red;
width: 100%;
height: 200px;
}
.homepage_carousel:nth-child(2) {
background-color: blue;
width: 100%;
height: 200px;
}
.homepage_carousel:nth-child(3) {
background-color: green;
width: 100%;
height: 200px;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>carousel</title>
</head>
<body>
<a id='carousel_prev'>prev</a>
<a id='carousel_next'>next</a>
<div class='homepage_carousel_wrapper'>
<div class='homepage_carousel'>
<h1>Frame 1</h1>
</div>
<div class='homepage_carousel'>
<h1>Frame 2</h1>
</div>
<div class='homepage_carousel'>
<h1>Frame 3</h1>
</div>
</div>
</body>
</html>
I have made some modifications to the HTML and CSS, and have rewritten most of the JavaScript.
Main Modifications
HTML
Changed the controls from links to buttons.
Moved the controls inside the carousel.
CSS
Removed repeated CSS.
JavaScript
Added spacing to make the code more readable.
Added a few comments to make the code easier to understand.
Modified the carousel constructor to allow multiple carousels to be made.
Moved the control event listeners inside the carousel constructor.
Replaced the prev() and next() functions with a changeSlide() function.
'use strict';
window.addEventListener('load', function() {
const hpCarousel = new carousel('homepage_carousel', 3);
});
function carousel(id, index) {
// Set slide index and get slides
this.slideIndex = index;
const carousel = document.getElementById(id);
this.slides = [...carousel.getElementsByClassName('slide')];
// Get controls and add event listeners
const prev = carousel.getElementsByClassName('prev')[0];
const next = carousel.getElementsByClassName('next')[0];
prev.addEventListener('click', () => {
this.changeSlide(-1);
});
next.addEventListener('click', () => {
this.changeSlide(1);
});
// Functions for managing slides
this.hideAll = function() {
this.slides.forEach(function(slide) {
slide.style.display = 'none';
});
}
this.show = function() {
this.hideAll();
this.slides[this.slideIndex - 1].style.display = 'flex';
}
this.changeSlide = function(amount) {
this.slideIndex += amount;
this.slideIndex = (this.slideIndex > this.slides.length) ? 1 :
(this.slideIndex < 1) ? this.slides.length : this.slideIndex;
this.show();
}
// Show the specified slide
this.show();
}
.slide {
width: 100%;
height: 200px;
}
.slide:nth-child(1) {
background-color: red;
}
.slide:nth-child(2) {
background-color: blue;
}
.slide:nth-child(3) {
background-color: green;
}
<div id='homepage_carousel'>
<button class='prev'>prev</button>
<button class='next'>next</button>
<div>
<div class='slide'>
<h1>Frame 1</h1>
</div>
<div class='slide'>
<h1>Frame 2</h1>
</div>
<div class='slide'>
<h1>Frame 3</h1>
</div>
</div>
</div>
How to add event delegation to dynamically created divs, to change property of the target div? I've tried several suggestions that I found for event delegation but none of them work. I think I'm making some mistakes but I don't know how to fix.
I am trying to develop a file thumbnail list interface with HTML and JavaScript. I made a method that draws thumbnails dynamically from an Array. And now I want to add some functions to manipulate the thumbnails, ex. changing border color of the item(div) when it is clicked.
First I tried loop-method to add event listeners to the divs, but it didn't work well. And now I learned that event delegation is better way to add event listeners to dynamically created elements. But the problem is that though I'v tried codes but they didn't work at all.
I think I am making some mistakes or mis-using methods but I don't know what is the problem.
JavaScript
function drawThumbnails(area, list){
var j
var createdList = []
for (j=0; j<list.length; j++){
var thmb = document.getElementById("fileThumb");
var name = document.getElementById("itemName");
var date = document.getElementById("itemDate");
var thmbimg = document.getElementById("fileThumbImage");
var thmbicon = document.getElementById("file_icon_thumb");
name.innerHTML=list[j][0];
date.innerHTML=list[j][1];
if (list[j][2] == "folder"){
thmbimg.src = "thmb_folder.png";
thmbicon.style.display = "none";
}
else {
if (list[j][2] == "img"){
thmbimg.src=getthmbimgsample();
}
else{
thmbimg.src = getThmbimg(list[j][2]);
}
thmbicon.style.display = "block";
thmbicon.src = getThmbicon(list[j][2]);
}
var cln = thmb.cloneNode(true);
cln.style.display = "block";
document.getElementById(area).append(cln);
createdList.push(cln);
}
thmbLists.push(createdList);
}
drawThumbnails("folderArea", folders);
drawThumbnails("fileArea", files);
document.getElementById("folderArea").addEventListener('click',function(e){
if(e.target && e.target.className == "fileThumb"){
e.target.style.borderColor = "#408CFF";
}
});
HTML
<body>
<div class = "contentArea" id="contentArea">
<div class = "thumbArea" id="folderArea">
<div class = "fileThumb" id="fileThumb">
<img src="icon_thumb_folder.png" class="fileThumb_normal" id="fileThumbImage">
<div class="fileName">
<img src="icon_thumb_file.png" style="width: 20px;" id="file_icon_thumb">
<div class="fileNameLine" id = "itemName">File/FolderName</div>
<div class="fileNameDate" id="itemDate">Date</div>
</div>
</div>
</div>
<div class = "contentAreaSectionHeader">
<input type="checkbox" id="chTest2" name="chTest2">
<label for="chTest2"><span>Files</span></label>
</div>
<div class = "thumbArea" id="fileArea">
</div>
</body>
CSS
.fileThumb{
width: 213px;
height: 183px;
border-radius: 2px;
border-style: solid;
border-width: 1px;
border-color: #EEEEEE;
text-align: center;
position: relative;
float:left;
margin: 18px;
display: none;
overflow: hidden;
}
Trying to figure out how to switch from one to two images then back to one with an onlick.
So far I have below which works no problem for switching to one image and back to original image. Ultimately I'm trying to get the first onclick event to be two images vertically and then click again back to the first single image.
var play = false;
function toggle() {
var image = document.getElementById('image')
var scan = document.getElementById('scan');
play = !play;
if (play) {
image.src = "pause.png";image.width="182";image.height="182";image.border="0";
scan.play();
}
else {
image.src = "play.png";image.width="182";image.height="182";image.border="0";
scan.pause();
}
}
and in body:
<img onclick="toggle()" id="image" src="play.png" alt="image" width="182" height="182" style="margin:auto; position:absolute; top: 0; right: 0; bottom: 0; left: 0; border: 0;">
This should work fine except, take out the width, height and border from the javascript, they're not changing so why have it there and risk some browsers freaking out on them?
I just put this together real quick to test and it works a treat.. I've commented out scan.play and pause of course but I'm assuming you've checked the console in your browser to see if those are throwing any errors?
I took the <a> out and used style cursor=pointer instead for the click-able element as well.. either way works but this is neater and works from ie6 I think, ie7+ definately.
edit: removed source block didn't achieve goal of question
After discussion in comment there's heaps of ways to do it, and I'd probably use jQuery but since you're not here's one not
<!doctype html>
<html>
<head>
<script type="text/javascript">
var play = true;
function toggle() {
//var scan = document.getElementById('scan');
var playpause = document.getElementById('playpause');
var btnplay = playpause.getElementsByClassName('play');
var btnpause = playpause.getElementsByClassName('pause');
play = !play;
if (play) {
btnplay[0].className = 'btn play active';
btnpause[0].className = 'btn pause';
//scan.play();
}
else {
btnplay[0].className = 'btn play';
btnpause[0].className = 'btn pause active';
//scan.pause();
}
}
</script>
<style>
.btn {
width: 182px;
height: 182px;
cursor: pointer;
position: absolute;
visibility: hidden;
}
.btn.active { visibility: visible; }
.btn.play { background: url('play.png') no-repeat 0 0; }
.btn.pause {
background: url('pause.png') no-repeat 0 0;
padding: 182px 0 0 0;
}
</style>
</head>
<body>
<div id="playpause">
<div class="btn play active" onclick="toggle()">
</div>
<div class="btn pause" onclick="toggle()">
<img src="other.png" alt="other" />
</div>
</body>
</html>