Add a button for random playback of tracks in the player - javascript

I want to add a small player to my site to listen to music. I found a beautiful example that I liked and want to change and finish it a little.
Specifically, I want to add a button here to randomly play tracks.
To start, I add this button to the html:
<button type="submit" id="btn-random">
<i class="fas fa-random"></i>
</button>
Next, I add a check to the next track switching function, if the random button has an active class, then the tracks will play randomly:
else if (to == 'next') {
stop();
if (document.getElementById("btn-random").classList.contains("active")) {
let songs = document.getElementById("sourceUrl").length - 1;
let randomSong = Math.floor(Math.random() * songs) + 1;
} else {
currentSong = (++currentSong)%playlist.length;
}
playpause();
}
Next, it remains to make sure that when you click on the random button, the active class turns on and off. To do this, I make a onclick function for this button and implement it:
<button type="submit" id="btn-random" onclick="random()">
<i class="fas fa-random"></i>
</button>
//
var randomTrack = false;
function random() {
if (randomTrack) {
document.getElementById('btn-random').classList.add("active");
randomTrack = false;
}
else {
document.getElementById('btn-random').classList.remove("active");
randomTrack = true;
}
}
But in the end, when the random button has an active class and I try to switch the song, instead of a random track, the current track plays in a circle.
What could be the problem?
var song = new Audio;
var isStopped = true;
var currentSong = 0;
var playlist = [];
var playlistVisible = false;
var randomTrack = false;
function skip(to) {
if (to == 'prev') {
stop();
currentSong = (--currentSong)%playlist.length;
if (currentSong < 0) {
currentSong += playlist.length;
}
playpause();
}
else if (to == 'next') {
stop();
if (document.getElementById("btn-random").classList.contains("active")) {
let songs = document.getElementById("sourceUrl").length - 1;
let randomSong = Math.floor(Math.random() * songs) + 1;
} else {
currentSong = (++currentSong)%playlist.length;
}
playpause();
}
}
function playpause() {
if (!song.paused) {
song.pause();
document.getElementById("glow").classList.add("disable-animation");
}
else if (playlist.length == 0){
togglePlaylist();
}
else {
if (isStopped) {
song.src = playlist[currentSong];
}
song.play();
songFile = playlist[currentSong].split("/");
songName = document.getElementById("songName");
songName.innerHTML = songFile[songFile.length - 1].split('.').slice(0, -1).join('.');
document.getElementById("glow").classList.remove("disable-animation");
isStopped = false;
}
}
function random() {
if (randomTrack) {
document.getElementById('btn-random').classList.add("active");
randomTrack = false;
}
else {
document.getElementById('btn-random').classList.remove("active");
randomTrack = true;
}
}
function stop() {
song.pause();
document.getElementById("glow").classList.add("disable-animation");
song.currentTime = 0;
document.getElementById("seek").value = 0;
isStopped = true;
document.getElementById("songName").innerHTML = "playing track..";
}
function setPos(pos) {
song.currentTime = pos;
}
function mute() {
if (song.muted) {
song.muted = false;
document.getElementById('mute').className = "fa fa-volume-up";
}
else {
song.muted = true;
document.getElementById('mute').className = "fa fa-volume-off";
}
}
function setVolume(volume) {
song.volume = volume;
}
function togglePlaylist() {
if (playlistVisible) {
document.getElementById('playlist').className = "hide";
document.getElementById('player').className = "";
playlistVisible = false;
}
else {
document.getElementById('player').className = "hide";
document.getElementById('playlist').className = "";
playlistVisible = true;
}
}
function addList() {
sourceUrl = document.getElementById('sourceUrl').value;
sourceUrl.split(",").forEach((file) => {
fileUrl = file.trim();
if (fileUrl != "" && playlist.indexOf(fileUrl) == -1) {
parent = document.getElementById('list');
listItem = document.createElement('div');
listItem.setAttribute('class','list-item');
wrapper = document.createElement('div');
wrapper.setAttribute('class','wrap-text');
span = document.createElement('span');
songFile = fileUrl.split("/");
span.innerHTML = songFile[songFile.length - 1].split('.').slice(0, -1).join('.');
wrapper.appendChild(span);
listItem.appendChild(wrapper);
btn = document.createElement('button');
btn.setAttribute('onclick','removeList(this)');
btn.innerHTML = '×';
listItem.appendChild(btn);
parent.appendChild(listItem);
playlist.push(fileUrl);
}
});
document.getElementById('sourceUrl').value = '';
}
function removeList(item) {
index = playlist.indexOf(item.parentElement.firstChild.innerText);
if (index != -1){
playlist.splice(index,1);
item.parentElement.remove();
}
}
song.addEventListener('error', function(){
stop();
document.getElementById("songName").innerHTML = "error loading audio";
});
song.addEventListener('timeupdate', function() {
curtime = parseInt(song.currentTime,10);
document.getElementById('seek').max = song.duration;
document.getElementById('seek').value = curtime;
});
song.addEventListener("ended", function() {
song.pause();
song.currentTime = 0;
document.getElementById('seek').value = 0;
if ((currentSong + 1) >= playlist.length) {
currentSong = 0;
}
else {
currentSong++;
}
stop();
song.src = playlist[currentSong];
playpause();
});
var input = document.getElementById("sourceUrl");
input.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
addList();
}
});
// This area of code is only for preview purposes only
document.getElementById('sourceUrl').value = ["https://www.bensound.com/bensound-music/bensound-summer.mp3",
"https://www.bensound.com/bensound-music/bensound-anewbeginning.mp3",
"https://www.bensound.com/bensound-music/bensound-littleidea.mp3",
"https://www.bensound.com/bensound-music/bensound-cute.mp3",
"https://www.bensound.com/bensound-music/bensound-memories.mp3"];
addList();
document.getElementById("glow").classList.remove("disable-animation");
// Code for preview ends here
* {
box-sizing: border-box;
}
html {
background: #000000;
}
html,
body,
.container {
height: 100%;
margin: 0;
font-family: Arial, Helvetica, sans-serif;
white-space: nowrap;
user-select: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
}
.container {
display: flex;
align-items: center;
justify-content: center;
}
.glow {
position: absolute;
width: 300px;
height: 300px;
background: linear-gradient(0deg, #000000, #262626);
border-radius: 50%;
}
.glow::before,
.glow::after {
content: "";
position: absolute;
top: -2px;
left: -2px;
background: linear-gradient(
45deg,
#ebc6df,
#ebc6c9,
#e1c6eb,
#c6c9eb,
#c6e8eb,
#e373fb,
#f787e6,
#cb87f7,
#87a9f7,
#87f7ee
);
background-size: 400%;
max-width: calc(300px + 4px);
max-height: calc(300px + 4px);
width: calc(300px + 4px);
height: calc(300px + 4px);
z-index: -1;
animation: animate 20s linear infinite;
border-radius: 50%;
}
.disable-animation::before,
.disable-animation::after {
animation-play-state: paused;
}
.glow::after {
filter: blur(28px);
}
#player,
#playlist {
width: 243px;
height: 212px;
text-align: center;
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#songName {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 30px;
}
.playlist-btn {
width: 243px;
margin-top: 30px;
text-align: center;
position: relative;
left: 50%;
transform: translateX(-50%);
}
.hide {
display: none;
}
#list {
height: 118px;
max-height: 118px;
margin-top: 16px;
font-size: 12px;
overflow-x: hidden;
overflow-y: scroll;
color: #fff;
text-align: left;
padding-left: 8px;
border: 2px solid #262626;
border-radius: 5px;
}
.list-item {
line-height: 30px;
height: 30px;
margin-top: 4px;
}
.list-container button {
width: 30px;
padding: 0;
float: right;
margin-right: 4px;
}
.add-list {
padding: 4px 6px;
}
.wrap-text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 190px;
display: inline-block;
}
#sourceUrl {
background: none;
padding: 8px;
border: 2px solid #1f1f1f;
border-radius: 47px;
outline: none;
color: white;
height: 30px;
width: 192px;
}
#sourceUrl:active,
#sourceUrl:focus {
border: 2px solid #0088ff;
}
.text {
color: #ffffff;
display: block;
}
button {
background: #000000;
color: #ffffff;
background: linear-gradient(0deg, #000000, #262626);
font-size: 14px;
border: none;
outline: none;
padding: 0px 15px;
width: 55px;
height: 30px;
line-height: 30px;
border-radius: 32px;
}
button:hover {
box-shadow: 0 0 8px 0px #ffffff61;
}
button:active {
box-shadow: inset 0 0 6px 0px #ffffff61;
}
#seek,
#volume {
-webkit-appearance: none;
border: 1px solid #000000;
height: 5px;
vertical-align: middle;
border-radius: 20px;
background-color: #232323;
outline: none;
}
#seek::-webkit-slider-thumb,
#volume::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
border: 1px solid #000000;
border-radius: 10px;
background: #ffffff;
}
#seek {
display: block;
width: 230px;
}
.scrollbar::-webkit-scrollbar {
max-width: 5px;
max-height: 5px;
}
.scrollbar::-webkit-scrollbar-thumb {
border-radius: 10px;
background: #333;
}
.scrollbar::-webkit-scrollbar-thumb:hover {
box-shadow: inset 0 0 1px 1px #5c6670;
}
.scrollbar::-webkit-scrollbar-track:hover {
border: 1px solid #000000;
border-radius: 20px;
background-color: #232323;
}
#keyframes animate {
0% {
background-position: 0 0;
}
50% {
background-position: 400% 0;
}
100% {
background-position: 0 0;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" rel="stylesheet" type="text/css">
<div class="container">
<div id="glow" class="glow disable-animation">
<div id="player">
<span class="text">iu player</span>
<br>
<span id="songName" class="text">playing track..</span>
<br>
<div class="playback_controls">
<button onclick="skip('prev')">
<i class="fa fa-fast-backward"></i>
</button>
<button onclick="playpause()">
<i class="fa fa-play"></i><i class="fa fa-pause"></i>
</button>
<button onclick="stop()">
<i class="fa fa-stop"></i>
</button>
<button onclick="skip('next')">
<i class="fa fa-fast-forward"></i>
</button>
</div>
<br>
<div id="seekbar">
<input type="range" oninput="setPos(this.value)" id="seek" value="0" max="">
</div>
<br>
<div class="volume_controls">
<button onclick="mute()">
<i id="mute" class="fa fa-volume-up"></i>
</button>
<input type="range" id="volume" oninput="setVolume(this.value)" min="0" max="1" step="0.01" value="1">
</div>
</div>
<div id="playlist" class="hide">
<span class="text">iu playlist</span>
<div class="list-container">
<div id="list" class="scrollbar"></div>
<div class="add-list">
<input id="sourceUrl" type="text" placeholder="enter audio url" />
<button onclick="addList()">+</button>
</div>
</div>
</div>
<div class="playlist-btn">
<button id="btn-random" onclick="random()">
<i class="fas fa-random"></i>
</button>
<button onclick="togglePlaylist()">
<i id="playlist-btn" class="fa fa-list"></i>
</button>
</div>
</div>
</div>

You are never reading your randomSong variable.
Just set currentSong to Math.floor(Math.random() * playlist.length) in that case:
if (
document.getElementById("btn-random").classList.contains("active")
) {
currentSong = Math.floor(Math.random() * playlist.length);
} else {
currentSong = ++currentSong % playlist.length;
}
playpause();

Related

javascript pause() restarts audio instead of pausing it?

I am coding a (mp3) sample/jingle/sound player button.
The top row has 2 control buttons and a volume slider, pressing the section below will play the sound.
The first control button toggles loop mode on off (this is functioning as expected)
The second control button is supposed to toggle "play/pause" mode.
If play/pause mode is "on" and you press the button a second time (while it is playing) it should pause, the when you press a 3rd time should resume playing but instead currently, it restarts from the begining on second press. Where did I go wrong?
function playsound() {
var audiox = document.getElementById('playerx');
audiox.src = "http://glentertainment.keybit.co.uk/audiop2/22%20Air%20Horn%20Single.mp3";
var playmode = document.getElementById('playpauseorrapidpressonoff').innerText;
if (playmode != "off") {
if (audiox.paused) {
audiox.play()
} else {
audiox.pause()
}
} else {
audiox.play();
}
}
function setvolume() {
document.getElementById('playerx').volume = document.getElementById('ssvolume').value;
}
function playmodebuttonpressed() {
onoffcheck = document.getElementById('playpauseorrapidpressonoff').innerText;
if (onoffcheck != "off") {
document.getElementById('playpauseorrapidpress').style.backgroundColor = "grey";
document.getElementById('playpauseorrapidpressonoff').innerText = "off";
} else {
document.getElementById('playpauseorrapidpress').style.backgroundColor = "black";
document.getElementById('playpauseorrapidpressonoff').innerText = "on";
}
}
function repeatbuttonpressed() {
onoffcheck = document.getElementById('repeatbuttonpressed').innerText;
if (onoffcheck != "off") {
document.getElementById('loop').style.backgroundColor = "grey";
document.getElementById('repeatbuttonpressed').innerText = "off";
document.getElementById('playerx').loop = false;
} else {
document.getElementById('loop').style.backgroundColor = "black";
document.getElementById('repeatbuttonpressed').innerText = "on";
document.getElementById('playerx').loop = true;
}
}
.ssvolume {
transform: scale(0.8);
width: 60px;
position: absolute;
top: 0;
right: 0;
display: inline-block;
margin: 0;
padding: 0;
}
.singlesoundcontainer {
width: 100px;
height: 100px;
box-shadow: inset 0px 1px 0px 0px #a4e271;
background: linear-gradient(to bottom, #89c403 5%, #77a809 100%);
background-color: #89c403;
border: 1px solid #74b807;
border-radius: 5px;
display: block;
position: relative;
}
.singlesamplercontrols {
width: 100px;
height: 20px;
background-color: transparent;
border-radius: 5px 5px 0 0;
border: 0.1px solid black;
}
.ssrepeatbutton {
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: -4px;
padding: 0px;
background-color: grey;
display: inline-block;
width: 20px;
cursor: pointer;
}
.ssrepeatbutton:hover {
background-color: black;
}
.singlesamplertrigger {
width: 90px;
height: 69px;
cursor: pointer;
padding: 5px;
color: black;
border-radius: 0 0 5px 5px;
display: inline-block;
overflow: hidden;
background-color: transparent;
font-family: Arial;
font-weight: bold;
text-decoration: none;
text-shadow: 0px 1px 0px #528009;
font-size: 11.5px;
line-height: 10px;
border-bottom: 0.1px solid black;
border-left: 0.1px solid black;
border-right: 0.1px solid black;
-webkit-user-select: none;
/* Safari */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
/* IE10+/Edge */
user-select: none;
/* Standard */
}
<div class="singlesoundcontainer">
<div class="singlesamplercontrols">
<img class="ssrepeatbutton" id="loop" onClick="repeatbuttonpressed();" src="https://www.bossdj.net/sampledeck/images/repeat-icon.png">
<span id="repeatbuttonpressed" style="display:none;">off</span>
<img class="ssrepeatbutton" id="playpauseorrapidpress" onClick="playmodebuttonpressed();" src="https://www.bossdj.net/sampledeck/images/playpausemode-icon.png">
<span id="playpauseorrapidpressonoff" style="display:none;">off</span>
<input class="ssvolume" type="range" id="ssvolume" min="0" max="1" value="1" step="0.01" onInput="setvolume();">
</div>
<div class="singlesamplertrigger" onClick="playsound();" id="singlesampler">Air Horn (Single)</div>
</div><br />
<!--Below audio element will be hidden in final code-->
<audio id="playerx" style="display: block; width: 280px" src="#" controls></audio>
You should initialise the src of the audio tag only once, and then just toggle the play/pause.
window.addEventListener('DOMContentLoaded', () => {
var audiox = document.getElementById('playerx');
audiox.src = "http://glentertainment.keybit.co.uk/audiop2/22%20Air%20Horn%20Single.mp3";
})
function playsound() {
var audiox = document.getElementById('playerx');
var playmode = document.getElementById('playpauseorrapidpressonoff').innerText;
if (playmode != "off") {
if (audiox.paused) {
audiox.play()
} else {
audiox.pause()
}
} else {
audiox.play();
}
}

jQuery - Image Uploader run parameter only if has class

I need this below image uploader to: only run the hasAlpha() parameter if:
form.uploader is a descendant of .checkalpha.
Otherwise I need the uploader to work without checking alpha for every instance of the form.uploader that isn't a descendant of .checkalpha.
In the snippet example:
The first uploader isn't a descendant of .checkalpha and needs to allow image uploads without checking hasAlpha
The second uploader is a descendant of .checkalpha and needs to allow image uploads with checking hasAlpha
$(function() {
$(".file-drag").click(function(event) {
$(this).siblings(".file-upload").click();
});
function ekUpload(item) {
var form = $(this).find("form.uploader"),
fileSelect = $(this).find(".file-upload"),
fileDrag = $(this).find(".file-drag"),
submitButton = $(this).find(".submit-button");
function Init() {
$(document).on("change", "form", function(e) {
fileSelectHandler(e);
});
// Is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
if (isAdvancedUpload) {
$(document)
.on(
"drag dragstart dragend dragover dragenter dragleave",
"form",
function(e) {
// fileDragHover(e);
e.preventDefault();
e.stopPropagation();
}
)
.on("dragover dragenter", "form", function(e) {
e.preventDefault();
e.stopPropagation();
$(e.target).addClass("is-dragover");
})
.on("dragleave dragend drop", "form", function(e) {
e.preventDefault();
e.stopPropagation();
$(e.target).removeClass("is-dragover");
})
.on("drop dragover", "body", function(e) {
e.preventDefault();
e.stopPropagation();
})
.on("drop", "form", function(e) {
e.preventDefault();
e.stopPropagation();
fileSelectHandler(e);
});
}
}
}
function fileDragHover(e) {
e.stopPropagation();
e.preventDefault();
e.target.className =
e.type === "dragover" ? "hover" : "modal-body file-upload";
}
async function fileSelectHandler(e) {
var theForm = $(e.target).parent("form.uploader");
var files = e.target.files || e.originalEvent.dataTransfer.files;
// Process all File objects
for (let i = 0; i < files.length; i++) {
const f = files[i];
if (await hasAlpha(f)) {
console.log("Selected image is transparent");
parseFile(f, theForm);
uploadFile(f, theForm);
} else {
console.log("Selected image is not transparent");
$(theForm)
.closest(".checkalpha")
.find(".response, .error-image")
.removeClass("hidden");
$(theForm).find(".file-image, .start").addClass("hidden");
output(
'<strong class="warning">Image background is not transparent</strong>'
);
}
}
}
// Output
function output(msg) {
// Response
var m = $(item).find(".message");
m.html(msg);
}
function hasAlpha(file) {
return new Promise((resolve, reject) => {
let hasAlpha = false;
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
img.crossOrigin = "Anonymous";
img.onerror = reject;
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
.data;
for (let j = 0; j < imgData.length; j += 4) {
if (imgData[j + 3] < 255) {
hasAlpha = true;
break;
}
}
resolve(hasAlpha);
};
img.src = URL.createObjectURL(file);
});
}
function parseFile(file, thisForm) {
console.log(file.name);
output("<strong>" + encodeURI(file.name) + "</strong>");
// var fileType = file.type;
// console.log(fileType);
var imageName = file.name;
var isGood = /\.(?=svg|jpg|png|jpeg)/gi.test(imageName);
if (isGood) {
$(thisForm).find(".start, .notimage").addClass("hidden");
$(thisForm)
.closest(".checkalpha")
.find(".response")
.addClass("hidden");
$(thisForm).find(".error-image").addClass("hidden");
$(thisForm)
.find("label.has-advanced-upload")
.removeClass("has-advanced-upload");
$(thisForm)
.find(".file-image")
.removeClass("hidden")
.attr("src", URL.createObjectURL(file));
} else {
$(thisForm).find(".error-image").removeClass("hidden");
$(thisForm)
.closest(".checkalpha")
.find(".response, .file-image")
.addClass("hidden");
$(thisForm).find(".file-upload-form").trigger("reset");
$(thisForm)
.find('label[for="file-upload"]')
.addClass("has-advanced-upload");
}
}
function uploadFile(file, thisForm) {
var xhr = new XMLHttpRequest(),
fileSizeLimit = 1024; // in MB
if (xhr.upload) {
// Check if file is less than x MB
if (file.size <= fileSizeLimit * 1024 * 1024) {
// File received / failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
// Everything is good!
console.log("everything is good");
}
};
// Start upload
xhr.open(
"POST",
$(thisForm).find(".file-upload-form").attr("action"),
true
);
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send(file);
} else {
output("Please upload a smaller file (< " + fileSizeLimit + " MB).");
}
}
}
// Check for the various File API support.
if (window.File && window.FileList && window.FileReader) {
Init();
} else {
document.getElementById("file-drag").style.display = "none";
}
}
var isAdvancedUpload = (function() {
var div = document.createElement("div");
return (
("draggable" in div || ("ondragstart" in div && "ondrop" in div)) &&
"FormData" in window &&
"FileReader" in window
);
})();
if (isAdvancedUpload) {
$(".file-drag").addClass("has-advanced-upload");
}
$(".uploader").each(function() {
ekUpload(this);
});
});
#import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css);
#import url("https://fonts.googleapis.com/css?family=Roboto");
body {
padding: 2rem;
background: #f8f8f8;
}
img.error-image {
max-height: 160px;
}
.uploader {
display: block;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 600px;
}
.uploader label {
float: left;
clear: both;
width: 100%;
padding: 2rem 1.5rem;
text-align: center;
background: #fff;
border-radius: 7px;
border: 3px solid #eee;
transition: all 0.2s ease;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
}
.uploader label.has-advanced-upload {
background-color: white;
outline: 2px dashed lightgrey;
outline-offset: -10px;
}
.uploader label:hover {
border: 3px solid #454cad;
box-shadow: inset 0 0 0 6px #eee;
}
.uploader label.is-dragover,
.uploader label.is-dragover:hover {
background-color: #eef;
}
.uploader label:hover {
border: 3px solid #454cad;
box-shadow: inset 0 0 0 6px #eee;
}
.uploader label:hover .start i.fa {
-webkit-transform: scale(0.8);
transform: scale(0.8);
opacity: 0.3;
}
.uploader .start {
float: left;
clear: both;
width: 100%;
pointer-events: none;
}
.uploader .start.hidden {
display: none;
}
.uploader .start i.fa {
font-size: 50px;
margin-bottom: 1rem;
transition: all 0.2s ease-in-out;
}
.uploader .response {
float: left;
clear: both;
width: 100%;
}
.uploader .response.hidden {
display: none;
}
.uploader .response .messages {
margin-bottom: 0.5rem;
}
.uploader .file-image {
display: inline;
pointer-events: none;
margin: 0 auto 0.5rem auto;
width: auto;
height: auto;
max-width: 180px;
}
.uploader .file-image.hidden {
display: none;
}
.uploader .notimage {
display: block;
float: left;
clear: both;
width: 100%;
}
.uploader .notimage.hidden {
display: none;
}
.uploader progress,
.uploader .progress {
display: inline;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 180px;
height: 8px;
border: 0;
border-radius: 4px;
background-color: #eee;
overflow: hidden;
}
.uploader .progress[value]::-webkit-progress-bar {
border-radius: 4px;
background-color: #eee;
}
.uploader .progress[value]::-webkit-progress-value {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader .progress[value]::-moz-progress-bar {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader input[type="file"] {
display: none;
}
.uploader div {
margin: 0 0 0.5rem 0;
color: #5f6982;
}
.uploader .btn {
display: inline-block;
margin: 0.5rem 0.5rem 1rem 0.5rem;
clear: both;
font-family: inherit;
font-weight: 700;
font-size: 14px;
text-decoration: none;
text-transform: initial;
border: none;
border-radius: 0.2rem;
outline: none;
padding: 0 1rem;
height: 36px;
line-height: 36px;
color: #fff;
transition: all 0.2s ease-in-out;
box-sizing: border-box;
background: #454cad;
border-color: #454cad;
cursor: pointer;
}
.uploader input[type="file"],
.hidden {
display: none;
}
input[type="file"].hidden {
display: block;
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.warning {
color: red;
font-weight: bold;
}
canvas {
position: absolute;
top: -2000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Upload -->
<div class="">
<form class="file-upload-form uploader">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img class="file-image hidden" src="#" alt="Preview">
<img class="error-image hidden" src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="message"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>
<div class="checkalpha">
<form class="file-upload-form uploader">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img class="file-image hidden" src="#" alt="Preview">
<img class="error-image hidden" src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="message"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>
Check if doesn't have parent .checkalpha using .closest
if (theForm.closest('.checkalpha').length === 0 || await hasAlpha(f)) {
$(function() {
$(".file-drag").click(function(event) {
$(this).siblings(".file-upload").click();
});
function ekUpload(item) {
var form = $(this).find("form.uploader"),
fileSelect = $(this).find(".file-upload"),
fileDrag = $(this).find(".file-drag"),
submitButton = $(this).find(".submit-button");
function Init() {
$(document).on("change", "form", function(e) {
fileSelectHandler(e);
});
// Is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
if (isAdvancedUpload) {
$(document)
.on(
"drag dragstart dragend dragover dragenter dragleave",
"form",
function(e) {
// fileDragHover(e);
e.preventDefault();
e.stopPropagation();
}
)
.on("dragover dragenter", "form", function(e) {
e.preventDefault();
e.stopPropagation();
$(e.target).addClass("is-dragover");
})
.on("dragleave dragend drop", "form", function(e) {
e.preventDefault();
e.stopPropagation();
$(e.target).removeClass("is-dragover");
})
.on("drop dragover", "body", function(e) {
e.preventDefault();
e.stopPropagation();
})
.on("drop", "form", function(e) {
e.preventDefault();
e.stopPropagation();
fileSelectHandler(e);
});
}
}
}
function fileDragHover(e) {
e.stopPropagation();
e.preventDefault();
e.target.className =
e.type === "dragover" ? "hover" : "modal-body file-upload";
}
async function fileSelectHandler(e) {
var theForm = $(e.target).parent("form.uploader");
var files = e.target.files || e.originalEvent.dataTransfer.files;
// Process all File objects
for (let i = 0; i < files.length; i++) {
const f = files[i];
if (theForm.closest('.checkalpha').length === 0 || await hasAlpha(f)) {
console.log("Selected image is transparent");
parseFile(f, theForm);
uploadFile(f, theForm);
} else {
console.log("Selected image is not transparent");
$(theForm)
.closest(".checkalpha")
.find(".response, .error-image")
.removeClass("hidden");
$(theForm).find(".file-image, .start").addClass("hidden");
output(
'<strong class="warning">Image background is not transparent</strong>'
);
}
}
}
// Output
function output(msg) {
// Response
var m = $(item).find(".message");
m.html(msg);
}
function hasAlpha(file) {
console.log('hasAlpha');
return new Promise((resolve, reject) => {
let hasAlpha = false;
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const img = new Image();
img.crossOrigin = "Anonymous";
img.onerror = reject;
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
.data;
for (let j = 0; j < imgData.length; j += 4) {
if (imgData[j + 3] < 255) {
hasAlpha = true;
break;
}
}
resolve(hasAlpha);
};
img.src = URL.createObjectURL(file);
});
}
function parseFile(file, thisForm) {
console.log(file.name);
output("<strong>" + encodeURI(file.name) + "</strong>");
// var fileType = file.type;
// console.log(fileType);
var imageName = file.name;
var isGood = /\.(?=svg|jpg|png|jpeg)/gi.test(imageName);
if (isGood) {
$(thisForm).find(".start, .notimage").addClass("hidden");
$(thisForm)
.closest(".checkalpha")
.find(".response")
.addClass("hidden");
$(thisForm).find(".error-image").addClass("hidden");
$(thisForm)
.find("label.has-advanced-upload")
.removeClass("has-advanced-upload");
$(thisForm)
.find(".file-image")
.removeClass("hidden")
.attr("src", URL.createObjectURL(file));
} else {
$(thisForm).find(".error-image").removeClass("hidden");
$(thisForm)
.closest(".checkalpha")
.find(".response, .file-image")
.addClass("hidden");
$(thisForm).find(".file-upload-form").trigger("reset");
$(thisForm)
.find('label[for="file-upload"]')
.addClass("has-advanced-upload");
}
}
function uploadFile(file, thisForm) {
var xhr = new XMLHttpRequest(),
fileSizeLimit = 1024; // in MB
if (xhr.upload) {
// Check if file is less than x MB
if (file.size <= fileSizeLimit * 1024 * 1024) {
// File received / failed
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4) {
// Everything is good!
console.log("everything is good");
}
};
// Start upload
xhr.open(
"POST",
$(thisForm).find(".file-upload-form").attr("action"),
true
);
xhr.setRequestHeader("X-File-Name", file.name);
xhr.setRequestHeader("X-File-Size", file.size);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.send(file);
} else {
output("Please upload a smaller file (< " + fileSizeLimit + " MB).");
}
}
}
// Check for the various File API support.
if (window.File && window.FileList && window.FileReader) {
Init();
} else {
document.getElementById("file-drag").style.display = "none";
}
}
var isAdvancedUpload = (function() {
var div = document.createElement("div");
return (
("draggable" in div || ("ondragstart" in div && "ondrop" in div)) &&
"FormData" in window &&
"FileReader" in window
);
})();
if (isAdvancedUpload) {
$(".file-drag").addClass("has-advanced-upload");
}
$(".uploader").each(function() {
ekUpload(this);
});
});
#import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css);
#import url("https://fonts.googleapis.com/css?family=Roboto");
body {
padding: 2rem;
background: #f8f8f8;
}
img.error-image {
max-height: 160px;
}
.uploader {
display: block;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 600px;
}
.uploader label {
float: left;
clear: both;
width: 100%;
padding: 2rem 1.5rem;
text-align: center;
background: #fff;
border-radius: 7px;
border: 3px solid #eee;
transition: all 0.2s ease;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
}
.uploader label.has-advanced-upload {
background-color: white;
outline: 2px dashed lightgrey;
outline-offset: -10px;
}
.uploader label:hover {
border: 3px solid #454cad;
box-shadow: inset 0 0 0 6px #eee;
}
.uploader label.is-dragover,
.uploader label.is-dragover:hover {
background-color: #eef;
}
.uploader label:hover {
border: 3px solid #454cad;
box-shadow: inset 0 0 0 6px #eee;
}
.uploader label:hover .start i.fa {
-webkit-transform: scale(0.8);
transform: scale(0.8);
opacity: 0.3;
}
.uploader .start {
float: left;
clear: both;
width: 100%;
pointer-events: none;
}
.uploader .start.hidden {
display: none;
}
.uploader .start i.fa {
font-size: 50px;
margin-bottom: 1rem;
transition: all 0.2s ease-in-out;
}
.uploader .response {
float: left;
clear: both;
width: 100%;
}
.uploader .response.hidden {
display: none;
}
.uploader .response .messages {
margin-bottom: 0.5rem;
}
.uploader .file-image {
display: inline;
pointer-events: none;
margin: 0 auto 0.5rem auto;
width: auto;
height: auto;
max-width: 180px;
}
.uploader .file-image.hidden {
display: none;
}
.uploader .notimage {
display: block;
float: left;
clear: both;
width: 100%;
}
.uploader .notimage.hidden {
display: none;
}
.uploader progress,
.uploader .progress {
display: inline;
clear: both;
margin: 0 auto;
width: 100%;
max-width: 180px;
height: 8px;
border: 0;
border-radius: 4px;
background-color: #eee;
overflow: hidden;
}
.uploader .progress[value]::-webkit-progress-bar {
border-radius: 4px;
background-color: #eee;
}
.uploader .progress[value]::-webkit-progress-value {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader .progress[value]::-moz-progress-bar {
background: linear-gradient(to right, #393f90 0%, #454cad 50%);
border-radius: 4px;
}
.uploader input[type="file"] {
display: none;
}
.uploader div {
margin: 0 0 0.5rem 0;
color: #5f6982;
}
.uploader .btn {
display: inline-block;
margin: 0.5rem 0.5rem 1rem 0.5rem;
clear: both;
font-family: inherit;
font-weight: 700;
font-size: 14px;
text-decoration: none;
text-transform: initial;
border: none;
border-radius: 0.2rem;
outline: none;
padding: 0 1rem;
height: 36px;
line-height: 36px;
color: #fff;
transition: all 0.2s ease-in-out;
box-sizing: border-box;
background: #454cad;
border-color: #454cad;
cursor: pointer;
}
.uploader input[type="file"],
.hidden {
display: none;
}
input[type="file"].hidden {
display: block;
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.warning {
color: red;
font-weight: bold;
}
canvas {
position: absolute;
top: -2000px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Upload -->
<div class="">
<form class="file-upload-form uploader">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img class="file-image hidden" src="#" alt="Preview">
<img class="error-image hidden" src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="message"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>
<div class="checkalpha">
<form class="file-upload-form uploader">
<input class="file-upload" type="file" name="fileUpload" accept="image/*" />
<label for="file-upload" class="file-drag">
<img class="file-image hidden" src="#" alt="Preview">
<img class="error-image hidden" src="https://cdn3.iconfinder.com/data/icons/online-states/150/Snooze-512.png">
<div class="start">
<i class="fa fa-download" aria-hidden="true"></i>
<div>Select a file or drag here</div>
<div class="notimage hidden">Please select an image</div>
</div>
<div class="response hidden">
<div class="message"></div>
</div>
</label>
</form>
<div class="filename"></div>
<canvas></canvas>
</div>

echo on button class

I'm trying to build a multi step selector which has multiple combinations in every slide. for example hou have btn1, btn2 and btn3. Every button will display other content in the next slide.
It's an inpage multistep slider so I can't use onClick, submit input or something like that.
as you can see in the code below, I'm trying to get an echo on the name or value of the button who has been clicked in the slide before.
var currentSlide = 0,
$slideContainer = $('.slide-container'),
$slide = $('.slide'),
slideCount = $slide.length,
animationTime = 300;
function setSlideDimensions () {
var windowWidth = $(window).width();
$slideContainer.width(windowWidth * slideCount);
$slide.width(windowWidth);
}
function generatePagination () {
var $pagination = $('.pagination');
for(var i = 0; i < slideCount; i ++){
var $indicator = $('<div>').addClass('indicator'),
$progressBarContainer = $('<div>').addClass('progress-bar-container'),
$progressBar = $('<div>').addClass('progress-bar'),
indicatorTagText = $slide.eq(i).attr('data-tag'),
$tag = $('<div>').addClass('tag').text(indicatorTagText);
$indicator.append($tag);
$progressBarContainer.append($progressBar);
$pagination.append($indicator).append($progressBarContainer);
}
$pagination.find('.indicator').eq(0).addClass('active');
}
function goToNextSlide () {
if(currentSlide >= slideCount - 1) return;
var windowWidth = $(window).width();
currentSlide++;
$slideContainer.animate({
left: -(windowWidth * currentSlide)
});
setActiveIndicator();
$('.progress-bar').eq(currentSlide - 1).animate({
width: '100%'
}, animationTime);
}
function goToPreviousSlide () {
if(currentSlide <= 0) return;
var windowWidth = $(window).width();
currentSlide--;
$slideContainer.animate({
left: -(windowWidth * currentSlide)
}, animationTime);
setActiveIndicator();
$('.progress-bar').eq(currentSlide).animate({
width: '0%'
}, animationTime);
}
function postitionSlides () {
var windowWidth = $(window).width();
setSlideDimensions();
$slideContainer.css({
left: -(windowWidth * currentSlide)
}, animationTime);
}
function setActiveIndicator () {
var $indicator = $('.indicator');
$indicator.removeClass('active').removeClass('complete');
$indicator.eq(currentSlide).addClass('active');
for(var i = 0; i < currentSlide; i++){
$indicator.eq(i).addClass('complete');
}
}
setSlideDimensions();
generatePagination();
$(window).resize(postitionSlides);
$('.next').on('click', goToNextSlide);
$('.previous').on('click', goToPreviousSlide);
#charset "UTF-8";
*, html, body {
font-family: "TrebuchetMS", trebuchet, sans-serif;
}
* {
box-sizing: border-box;
}
h1, h2 {
text-align: center;
}
h1 {
font-size: 24px;
line-height: 30px;
font-weight: bold;
}
h2 {
font-size: 18px;
line-height: 25px;
margin-top: 20px;
}
button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 0;
padding: 14px 50px;
border-radius: 4px;
background-color: #37B595;
color: #FFFFFF;
text-transform: capitalize;
font-size: 18px;
line-height: 22px;
outline: none;
cursor: pointer;
transition: all 0.2s;
}
button:hover {
background-color: #1A7F75;
}
button.previous {
background-color: #A2ACAF;
}
button.previous:hover {
background-color: #5A5F61;
}
.full-width-container {
width: 100%;
min-width: 320px;
}
.sized-container {
max-width: 900px;
width: 100%;
margin: 0 auto;
}
.slide-container {
position: relative;
left: 0;
overflow: hidden;
}
.slide {
float: left;
}
.slide .sized-container {
padding: 75px 25px;
}
.button-container {
border-top: 1px solid black;
overflow: hidden;
padding-top: 30px;
}
.button-container button {
float: right;
margin-left: 30px;
}
.pagination-container {
margin-top: 120px;
}
.pagination {
width: 100%;
text-align: center;
padding: 0 25px;
}
.indicator {
width: 25px;
height: 25px;
border: 4px solid lightgray;
border-radius: 50%;
display: inline-block;
transition: all 0.3s;
position: relative;
}
.indicator .tag {
position: absolute;
top: -30px;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
color: lightgray;
white-space: nowrap;
}
.indicator.active, .indicator.complete {
border-color: #37B595;
}
.indicator.active .tag, .indicator.complete .tag {
color: #37B595;
}
.indicator.complete:after {
content: "✓";
position: absolute;
color: #37B595;
left: 4px;
top: 3px;
font-size: 14px;
}
.progress-bar-container {
width: 10%;
height: 4px;
display: inline-block;
background-color: lightgray;
position: relative;
top: -10px;
}
.progress-bar-container:last-of-type {
display: none;
}
.progress-bar-container .progress-bar {
width: 0;
height: 100%;
background-color: #37B595;
}
<div class="pagination-container full-width-container">
<div class="sized-container">
<div class="pagination"></div>
</div>
</div>
<div class="viewport full-width-container">
<ul class="slide-container">
<li class="slide" data-tag="Basic Info">
<div class="sized-container">
<h1>Slide1.</h1>
<input class="next" name="next" type="button" value="next" />
</div>
</li>
<li class="slide" data-tag="Expertise">
<div class="sized-container">
<h1>Slide2.</h1>
</div>
</li>
</ul>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
Can someone please help me out!

Buttons added after page load are not recognized in EventListener

My EventListener isn't targeting elements added after the page initially loads. I originally thought it might have been the order I have it in but I changed where the code is located and tried nesting it within the area the new div is created but it either breaks the color change as a whole or the original issue continues.
My final thought was maybe I need to add an EventListener to update the elems variable. I was unsuccessful in finding something to guide me.
If you click the original 4 squares they load, but after using the "Add a Square!" button the added divs dont behave the same.
//Turn div red if clicked
var elems = document.getElementsByClassName("square");
Array.from(elems).forEach(v => v.addEventListener('click', function() {
if (this.style.backgroundColor !== "red") {
this.style.backgroundColor = "red";
} else {
this.style.backgroundColor = "#1E1E1E";
}
}));
//Slider
var slider = document.getElementById("range");
var output = document.getElementById("value");
output.innerHTML = slider.value;
slider.oninput = function() {
var parent = document.getElementById("parent");
output.innerHTML = this.value;
parent.style.width = this.value + "%";
}
//Add Div
function addDiv(parent_div) {
var div = document.createElement("div");
var parent = document.getElementById(parent_div);
if (parent) {
parent.appendChild(div);
}
}
var button = document.getElementById("addsquare");
if (button) {
button.addEventListener("click", function() {
// change dynamically your new div
addDiv('parent', {
'class': 'square'
});
});
}
#parent {
margin: 0 auto;
min-width: 200px;
max-width: 94.2%;
width: 25%;
border: 1px dashed grey;
overflow: hidden;
}
#parent>div {
float: left;
margin: 1px;
width: calc(50px - 2px);
height: calc(50px - 2px);
background-color: #1E1E1E;
}
input,
button {
margin: 0;
}
.controls {
border: 1px solid black;
padding: 10px;
margin-bottom: 10px;
}
.controls>h2 {
margin: 0;
padding: 0;
text-align: center;
}
#addsquare {
padding: 8px;
margin-bottom: 5px;
}
.slidewrap {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 25%;
height: 25px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
<div class="controls">
<h2>Controls</h2>
<button id="addsquare">Add a Square!</button>
<div class="slidewrap">
<input type="range" min="25" max="100" value="25" class="slider" id="range">
<div>Game zone is set to: <span id="value"></span>%</div>
</div>
</div>
<div id="parent">
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
</div>
You need to add the event listener to the dynamically created divs:
button.addEventListener("click", function() {
// change dynamically your new div
var newDiv = addDiv('parent', { 'class': 'square' });
newDiv.addEventListener('click', squareClickHandler)
});
squareClickHandler is just the old anonymous function you used to change the square color.
//Turn div red if clicked
var elems = document.getElementsByClassName("square");
Array.from(elems).forEach(v =>
v.addEventListener('click', squareClickHandler));
function squareClickHandler() {
if (this.style.backgroundColor !== "red") {
this.style.backgroundColor = "red";
} else {
this.style.backgroundColor = "#1E1E1E";
}
}
//Slider
var slider = document.getElementById("range");
var output = document.getElementById("value");
output.innerHTML = slider.value;
slider.oninput = function() {
var parent = document.getElementById("parent");
output.innerHTML = this.value;
parent.style.width = this.value + "%";
}
//Add Div
function addDiv(parent_div) {
var div = document.createElement("div");
var parent = document.getElementById(parent_div);
if (parent) {
parent.appendChild(div);
}
return div;
}
var button = document.getElementById("addsquare");
if (button) {
button.addEventListener("click", function() {
// change dynamically your new div
var newDiv = addDiv('parent', {
'class': 'square'
});
newDiv.addEventListener('click', squareClickHandler)
});
}
#parent {
margin: 0 auto;
min-width: 200px;
max-width: 94.2%;
width: 25%;
border: 1px dashed grey;
overflow: hidden;
}
#parent>div {
float: left;
margin: 1px;
width: calc(50px - 2px);
height: calc(50px - 2px);
background-color: #1E1E1E;
}
input,
button {
margin: 0;
}
.controls {
border: 1px solid black;
padding: 10px;
margin-bottom: 10px;
}
.controls>h2 {
margin: 0;
padding: 0;
text-align: center;
}
#addsquare {
padding: 8px;
margin-bottom: 5px;
}
.slidewrap {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 25%;
height: 25px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
<div class="controls">
<h2>Controls</h2>
<button id="addsquare">Add a Square!</button>
<div class="slidewrap">
<input type="range" min="25" max="100" value="25" class="slider" id="range">
<div>Game zone is set to: <span id="value"></span>%</div>
</div>
</div>
<div id="parent">
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
</div>
I would solve this with event delegation instead of binding the event to each single element. This means you bind the listener to the parent or any other ancestor element and then do what you want to the event.target instead.
//Turn div red if clicked
var elems = document.getElementsByClassName("square");
var parent = document.getElementById("parent");
parent.addEventListener('click', (event) => {
let target = event.target;
if (target.style.backgroundColor !== "red") {
target.style.backgroundColor = "red";
} else {
target.style.backgroundColor = "#1E1E1E";
}
});
//Slider
var slider = document.getElementById("range");
var output = document.getElementById("value");
output.innerHTML = slider.value;
slider.oninput = function() {
var parent = document.getElementById("parent");
output.innerHTML = this.value;
parent.style.width = this.value + "%";
}
//Add Div
function addDiv(parent_div) {
var div = document.createElement("div");
var parent = document.getElementById(parent_div);
if (parent) {
parent.appendChild(div);
}
}
var button = document.getElementById("addsquare");
if (button) {
button.addEventListener("click", function() {
// change dynamically your new div
addDiv('parent', {
'class': 'square'
});
});
}
#parent {
margin: 0 auto;
min-width: 200px;
max-width: 94.2%;
width: 25%;
border: 1px dashed grey;
overflow: hidden;
}
#parent>div {
float: left;
margin: 1px;
width: calc(50px - 2px);
height: calc(50px - 2px);
background-color: #1E1E1E;
}
input,
button {
margin: 0;
}
.controls {
border: 1px solid black;
padding: 10px;
margin-bottom: 10px;
}
.controls>h2 {
margin: 0;
padding: 0;
text-align: center;
}
#addsquare {
padding: 8px;
margin-bottom: 5px;
}
.slidewrap {
width: 100%;
}
.slider {
-webkit-appearance: none;
width: 25%;
height: 25px;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
<div class="controls">
<h2>Controls</h2>
<button id="addsquare">Add a Square!</button>
<div class="slidewrap">
<input type="range" min="25" max="100" value="25" class="slider" id="range">
<div>Game zone is set to: <span id="value"></span>%</div>
</div>
</div>
<div id="parent">
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
</div>

Debugging a calendar app on javascript

Here is some pastebin (don't want to put my code in the internet for ever) to build a cool calendar :
var today = new Date(); // The current server date
var displayedMonth = new Date(today.getTime())
var mois = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"];
var jour = ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"];
function initialSetup(date){
addEventListener();
buildCalendar(date);
}
function buildCalendar(date){
$(".currentMonth").text(mois[date.getMonth()]);
$(".currentYear").text(date.getFullYear());
if($(".itemsCalendar").length == 0){
$(".calendar:first").append('<table class="itemsCalendar"><thead><tr></tr></thead>');
for(var cpt = 1; cpt <= jour.length-1;cpt++)
$(".calendar > table > thead > tr").append('<th>'+jour[cpt].substring(0,3)+'</th>');
$(".calendar > table > thead > tr").append('<th>'+jour[0].substring(0,3)+'</th>');
}
// Set the days in the calendar
return populateCalendar(date);
}
function populateCalendar(date){
var itsToday = null;
var appendLocation = null;
var sendResult = false;
if($(".itemsCalendar > tbody").length == 0){
$(".itemsCalendar").append('<tbody class="dates"></tbody>');
appendLocation = ".dates";
}else{
$(".calendar").append('<tbody class="tempCalendar"></tbody>');
appendLocation = ".tempCalendar";
sendResult = true;
}
if(date.getMonth() == today.getMonth() && date.getYear() == today.getYear() ){ // If is it the same day than today, buid as follow
itsToday = 'class="today"'
// date = today;
date.setDate(today.getDate()); // copy the date of today
}
$(appendLocation).append("<tr><td><span "+itsToday+">"+date.getDate()+"</span></td></tr>");
var currentDay = date.getDay();
for(var cpt = date.getDate()-1; cpt>=1;cpt--){ // For each day before
currentDay > 0 ? currentDay-- : currentDay = 6; // Negate 1 day
currentDay == 0 ? $(appendLocation).prepend("<tr></tr>"):null; // Add a line in needed
$(appendLocation+" > tr:first").prepend("<td><span>"+cpt+"</span></td>");
}
fillCalendar(date, currentDay, true, appendLocation);
currentDay = date.getDay();
for(var cpt = date.getDate()+1; cpt<=dayInMonth(date);cpt++){ // For each day after
currentDay < 6 ? currentDay++ : currentDay = 0;// Increase 1 day
currentDay == 1 ? $(appendLocation).append("<tr></tr>"):null; // Add a line if needed
$(appendLocation+" > tr:last").append("<td><span>"+cpt+"</span></td>");
}
fillCalendar(date, currentDay, false, appendLocation);
if(sendResult){
var ret = $(".tempCalendar").html();
$(".tempCalendar").remove();
return ret;
}
}
function dayInMonth(date){
if(date.getMonth() == 1) if(isBissextile(date.getYear())) return 29; else return 28;
if(date.getMonth()%2 == 0) if(date.getMonth() <= 6) return 31; else return 30; else if(date.getMonth() <= 6) return 30; else return 31;
}
function isBissextile(year){
if(year%4 != 0) return false; else if((year%100 == 0) && (year%400 != 0)) return false; else return true;
}
function fillCalendar(date, day, isBefore, where){
var complete;
if(isBefore){
if(day == 1) return; else complete = false;
date.setMonth(date.getMonth()-1);
var cpt = dayInMonth(date);
do{
day != 0 ? day-- : day = 6; // Negate 1 day
$(where+" > tr:first").prepend("<td><span class='notInTheMonth'>"+cpt+"</span></td>");
cpt--;
day == 1 ? complete = true : null;
}while(!complete);
date.setMonth(date.getMonth()+1);
}else{
if(day == 0) return; else complete = false;
var cpt = 1;
do{
day == 6 ? day = 0 : day++; // Increase 1 day
$(where+" > tr:last").append("<td><span class='notInTheMonth'>"+cpt+"</span></td>");
cpt++;
day == 0 ? complete = true : null;
}while(!complete);
}
}
function addEventListener(){
$(".previousMonth").click(function(e){
e.stopPropagation();
displayedMonth.setMonth(displayedMonth.getMonth()-1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
$(".nextMonth").click(function(e){
e.stopPropagation();
displayedMonth.setMonth(displayedMonth.getMonth()+1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
$(".previousYear").click(function(e){
e.stopPropagation();
displayedMonth.setFullYear(displayedMonth.getFullYear()-1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
$(".nextYear").click(function(e){
e.stopPropagation();
displayedMonth.setFullYear(displayedMonth.getFullYear()+1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
}
function addDayEventListener(){
$(".dates").on('click', '.notInTheMonth', function() {
var selected = parseInt($(this).text());
if(selected > 15)
displayedMonth.setMonth(displayedMonth.getMonth()-1);
else
displayedMonth.setMonth(displayedMonth.getMonth()+1);
displayedMonth.setDate(selected);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
$(".dates > tr > td > span:not(.notInTheMonth)").filter(function() {
return parseInt($(this).text()) === selected;
}).addClass("today")
});
/*$(".notInTheMonth").each(function(){
$(this).click(function(e){
e.stopPropagation();
});
});*/
}
function updateCalendar(updated){
$('.dates').animate({
opacity: 0,
transform: "scale(2,1)"
},250, function(){
updated = $(updated);
$(this).empty();
$(this).html(updated);
addDayEventListener();
$('.dates').animate({opacity: 100}, 250);
});
//$(".itemsCalendar > tbody").remove();
}
function colorize(colors){
/*background: #ff3232;
background: -moz-linear-gradient(-45deg, #ff3232 0%, #ff2828 21%, #2989d8 21%, #2989d8 48%, #5aa85e 48%, #5aa85e 73%, #ffac4f 73%, #ffac4f 100%);
background: -webkit-linear-gradient(-45deg, #ff3232 0%,#ff2828 20%,#2989d8 20%,#2989d8 40%,#5aa85e 40%,#5aa85e 60%,#ffac4f 60%,#ffac4f 80%, yellow 80%,yellow 100%);
background: linear-gradient(135deg, #ff3232 0%,#ff2828 21%,#2989d8 21%,#2989d8 48%,#5aa85e 48%,#5aa85e 73%,#ffac4f 73%,#ffac4f 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff3232', endColorstr='#ffac4f',GradientType=1 );*/
}
initialSetup(today);
* {
font-family: 'Open Sans', sans-serif;
}
div,
ul,
li {
list-style-type: none;
}
.planner {
width: 66%;
margin: 100px auto;
box-shadow: 0 0 40px rgba(0, 0, 0, 0.5);
border-radius: 5px;
overflow: hidden;
min-width: 280px;
}
.calendar {
padding: 10px;
background-color: #333333;
min-width: 260px;
transition: 250ms;
}
.calendar-header {
color: #a7a7a7;
margin: 0;
padding: 0;
text-align: justify;
line-height: 0px;
font-size: 0px;
}
.calendar-header span,
.calendar-header a {
display: inline-block;
font-size: 36px;
font-weight: 200;
text-align: center;
line-height: 36px;
}
.calendar-header a:hover {
color: #98cd60;
cursor: pointer;
}
.calendar-header::after {
content: '';
display: inline-block;
width: 100%;
}
table {
width: 100%;
padding: 10px;
color: #9d9d9d;
min-width: 240px;
}
tbody{
overflow: hidden;
max-height: 180px;
}
th {
font-weight: normal;
font-size: 14px;
color: #5b5b5b;
}
td {
font-weight: normal;
font-size: 12px;
text-align: center;
}
td > span {
display: inline-block;
text-align: center;
padding: 3px;
margin: 0px;
width: 20px;
height: 20px;
line-height: 20px;
}
td > span:hover {
font-weight: bold;
}
td > span.active {
border: 2px solid #98cd60;
border-radius: 30px;
}
.schedule {
margin: 0;
}
.tabs {
margin: 0;
padding: 0;
text-align: justify;
line-height: 0px;
font-size: 0px;
background-color: #6b6b6b;
}
.tabs .tab {
display: inline-block;
width: 33.3333%;
background-color: #6b6b6b;
text-align: center;
color: #333333;
margin: 0;
padding: 0;
border: 0px none;
line-height: 38px;
font-size: 14px;
transition: background 0.2s;
}
.tabs .tab.active {
background-color: #999999;
color: #ffffff;
font-weight: 600;
}
.tabs .tab.active:hover {
background-color: #999999;
}
.tabs .tab:hover {
background-color: #777777;
}
.tabs .tab a {
color: inherit;
text-decoration: none;
}
.tabs::after {
content: '';
width: 100%;
display: inline-block;
}
.schedule-list {
padding: 20px;
margin-left: 37px;
border-left: 2px solid #cccccc;
display: block;
}
.schedule-item {
display: block;
margin-bottom: 50px;
padding: 0;
clear: both;
min-height: 100px;
overflow: visible;
}
.schedule-item:last-child {
margin-bottom: 10px;
min-height: 30px;
}
.schedule-item .time {
display: block;
float: left;
margin-left: -41px;
width: 36px;
height: 36px;
border: 2px solid #cccccc;
background-color: #ffffff;
color: #cccccc;
border-radius: 40px;
text-align: center;
padding: 0px;
line-height: 25px;
}
.schedule-item .time span {
font-size: 12px;
height: 10px;
margin: auto;
display: block;
}
.schedule-item .description {
display: block;
float: left;
width: 305px;
margin-top: 10px;
margin-left: 10px;
color: #fd9a4a;
font-size: 14px;
overflow: visible;
}
.schedule-item .description .description-content {
margin-top: 5px;
}
.schedule-item .description .description-content p {
font-size: 12px;
margin: 0;
color: #c5c5c5;
}
.schedule-item .description .description-content .contact-list {
margin: 0;
margin-top: 10px;
padding: 0;
}
.schedule-item .description .description-content .contact-list .contact {
overflow: hidden;
display: block;
float: left;
margin: 0;
padding: 0;
border: 2px solid rgba(152, 205, 96, 0.25);
border-radius: 60px;
width: 56px;
height: 56px;
text-decoration: none;
text-align: center;
margin-right: 10px;
transition: all 0.2s;
}
.schedule-item .description .description-content .contact-list .contact img {
width: 60px;
height: 60px;
}
.schedule-item .description .description-content .contact-list .contact:hover {
border: 2px solid #98cd60;
}
.schedule-item .description .description-content .contact-list .contact.add-contact {
color: #98cd60;
font-size: 20px;
line-height: 60px;
}
.schedule-item .description .description-content .contact-list .contact.add-contact a {
color: inherit;
text-decoration: none;
}
.schedule-item .description .description-content .contact-list .contact.add-contact:hover {
background-color: rgba(152, 205, 96, 0.25);
}
.schedule-item.free .time {
border: 2px solid #98cd60;
}
.schedule-item.free .description .description-header {
background-color: #ffffff;
color: #c5c5c5;
display: block;
float: left;
}
.schedule-item.free .description .description-content {
margin-left: 5px;
margin-top: 0;
content: '';
width: 215px;
display: block;
float: right;
background-image: url(https://dl.dropboxusercontent.com/u/2915418/filler.png);
background-repeat: no-repeat;
background-position: right center;
}
footer {
margin-top: 30px;
color: #c5c5c5;
display: block;
text-align: center;
}
footer a {
color: #98cd60;
text-decoration: none;
}
.today{
background-color: #7D7D7D;
color: #98CD60;
border-radius: 30px;
width: 20px;
height: 20px;
}
.notInTheMonth{
background-color: #272727;
border-radius: 30px;
color: #444444;
}
.headerWrapper{
color: #a7a7a7;
border-bottom: 1px solid #484848;
margin: 0;
padding: 0;
text-align: justify;
line-height: 0px;
font-size: 0px;
padding: 10px 0px;
}
.headerWrapper::after {
content: '';
display: inline-block;
width: 100%;
}
.itemsCalendar{
display: block;
max-height: 225px;
}
.itemsCalendar thead, .dates tr, .tempCalendar tr{
display: table;
width: 100%;
table-layout: fixed;
}
.tempCalendar{
display: none;
}
<html>
<head>
<title>Calendrier</title>
<meta charset="utf-8" />
<link href="http://netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.min.css" rel="stylesheet">
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700,800' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
</head>
<body>
<div class="planner">
<div class="calendar">
<div class="calendar-header">
<div class="headerWrapper">
<a class="btn btn-prev previousYear">
<i class="icon-angle-left"></i>
</a>
<span class="currentYear">July</span>
<a class="btn btn-next nextYear">
<i class="icon-angle-right"></i>
</a>
</div>
<div class="headerWrapper">
<a class="btn btn-prev previousMonth">
<i class="icon-angle-left"></i>
</a>
<span class="currentMonth"></span>
<a class="btn btn-next nextMonth">
<i class="icon-angle-right"></i>
</a>
</div>
</div>
</div>
</div>
</body>
</html>
js/calendar.js
index.html
css/style.css
When clicking on notInTheMonth classed elements, there will be problems (too much day in the output, more than one month passed etc...)
To trigger the first time the click event listener, you have to pass one month or one year before. After that, it will enable the click event on the notInTheMonth day (element with background dark grey and text grey, who refer to a non-in-month day.
Frequently, the problem occurs on the second or third time we click in a notInTheMonth element.
I can't correct my trouble, so can you please help me ?

Categories

Resources