After discovering the difficulties of styling inputs of type range, I though it best to simply create one using css and hiding the original. I'm trying to Make a volume slider, but I don't think I fully understand how to connect onmousemove and onmousedown. I tried following the following post
How to connect onmousemove with onmousedown?
but my volumeSlider function - the javascript code that is commented out - still isn't working;
What I want is that onmousemove is only activated on onmousedown and not by simply moving the mouse.
const volume_div = document.querySelector('.volume');
const volumeBtn_div = document.querySelector('.volume-button');
function volumeClick(event) {
let x = event.offsetX;
volume_div.style.width = (Math.floor(x) + 10) + 'px';
}
/*
volumeBtn_div.onmousedown = function() {
volumeBtn_div.onmousemove = volumeSlide;
};
function volumeSlide(event) {
let x = event.offsetX;
volume_div.style.width = Math.floor(x) + 'px';
}*/
body {
background-color: #2a2a2a;
}
.volume-range {
margin-top: 80px;
height: 5px;
width: 250px;
background: #555;
border-radius: 15px;
}
.volume-range>.volume {
height: 5px;
width: 50px;
background: #2ecc71;
border: none;
border-radius: 10px;
outline: none;
position: relative;
}
.volume-range>.volume>.volume-button {
width: 20px;
height: 20px;
border-radius: 20px;
background: #FFF;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
outline: none;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Volume</title <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>
<body>
<div class="volume-range" onclick="volumeClick(event)">
<div class="volume">
<div class="volume-button"></div>
</div>
</div>
If I understand your question correctly, I think you could just set a flag onmousedown and reset it onmouseup. Something like:
let mouseIsDown = false;
volumeBtn_div.onmousedown = function() { mouseIsDown = true };
volumeBtn_div.onmouseup = function() { mouseIsDown = false };
volumeBtn_div.onmousemove = volumeSlide;
function volumeSlide(event) {
if(mouseIsDown){
let x = event.offsetX;
volume_div.style.width = Math.floor(x) + 'px';
}
}
...
In response to your comment, this similar example works in Chrome. I changed the EventListener syntax. It should get you on the right track.
<!DOCTYPE html>
<html>
<head>
<style>
div { width: 200px; height: 100px; border: 1px solid black; }
</style>
</head>
<body>
<div id="input"></div>
<p id="output"></p>
<script>
const input = document.getElementById("input");
const output = document.getElementById("output");
let mouseIsDown = false;
input.addEventListener("mouseup", up);
input.addEventListener("mousedown", down);
input.addEventListener("mousemove", slide);
function down(){ mouseIsDown = true; }
function up(){ mouseIsDown = false; }
function slide(e) {
if(mouseIsDown){
var x = e.clientX;
var pos = "pos: " + x;
output.innerHTML = pos;
}
}
</script>
</body>
</html>
Related
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container');
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = [];
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
canvas.addEventListener('mousedown', (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y);
}
})
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>testing</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons#2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
Objective - When user clicks design button, the circles are added to the canvas on mousedown event. When user clicks the edit button, they are able to move the circles around. When the design button is clicked again, user is able to continue adding circles and incrementing the number from where it was left off.
Error to resolve - When design is first clicked, I am able to successfully add circles to the canvas. If I click on edit button and move the circles around and then click on design button right after, it appends two circles on on click. Why is it appending two circles? This only happens after I click on edit.
***JAVASCRIPT***
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container')
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = []
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
canvas.addEventListener('mousedown', (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y)
}
})
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
***HTML***
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Testing</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons#2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
***CSS***
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
The issue is you're registering the mouse-down event handler in design mode every time user switches to the design mode.
However you never unregister the mouse-down event handler upon switching to edit mode.
This results in multiple event handler to be registered for canvas click event(mouse-down).
So whenever you switch back to the design mode and click upon the canvas, it fires click handler for previously registered listener as well as the newly registered listener.
Check the updated snippet
Comment lines marked with // Solution :
//Global variables
let count = 1;
let canvas = document.querySelector('#canvas');
let canvasContainer = document.querySelector('.canvas-container');
let designBtn = document.querySelector('#design-btn');
let editBtn = document.querySelector('#edit-btn');
let isDesign = false;
let isEdit = false;
let circleArray = [];
let offset = [];
//Click event listener for design button
designBtn.addEventListener('click', (event)=>{
isDesign = true;
isEdit = false;
designBtn.style.backgroundColor = '#BA4A00'
designBtn.style.color = '#17202A'
editBtn.style.backgroundColor = null;
editBtn.style.color = null
//Invoke being_design function
begin_design()
})
//Click event listener for edit button
editBtn.addEventListener('click', (event)=>{
isDesign = false;
isEdit = true;
editBtn.style.backgroundColor = '#BA4A00'
editBtn.style.color = '#17202A'
designBtn.style.backgroundColor = null;
designBtn.style.color = null
//Invoke edit_design function
edit_design()
})
//Function creates new element and then appends it to the parent div
function create_circle_element(x, y){
let circle = document.createElement('div')
const circleHeight = 40;
const circleWidth = 40;
circle.style.position = 'absolute';
circle.style.backgroundColor = 'orange';
circle.style.height = `${circleHeight}px`;
circle.style.width = `${circleWidth}px`;
circle.style.borderRadius = '50%'
circle.style.textAlign = 'center';
circle.style.lineHeight = `${circleHeight}px`;
circle.style.cursor = 'pointer';
circle.style.left = `${(x - (canvas.offsetLeft + canvasContainer.offsetLeft - window.scrollX)) - (circleWidth/2)}px`;
circle.style.top = `${(y -(canvas.offsetTop + canvasContainer.offsetTop - window.scrollY)) - (circleHeight/2)}px`
circle.textContent = `${count}`;
canvas.append(circle)
circleArray.push(circle)
count++
}
// Solution : Define a click handler
var designClickHandler = (event)=>{
if(isDesign){
mousePosition = {
x: event.clientX,
y: event.clientY
}
create_circle_element(mousePosition.x, mousePosition.y);
}
}
//Function responsible for adding circles to the canvas
//Function is invoked when design button is clicked
function begin_design(){
let mousePosition;
// Solution : Register click handler
canvas.addEventListener('mousedown', designClickHandler)
}
//Function responsible for editing the circles on the canvas i.e moving them around on mousedown/mousemove event
//Function is invoked when edit button is clicked
function edit_design(){
if(isEdit){
// Solution : unregister click handler
canvas.removeEventListener('mousedown', designClickHandler)
let mouseDown = false;
let offset = [];
let circleClickedOn = [];
//Set mouseDown to false
canvas.addEventListener('mouseup', ()=>{
mouseDown = false
})
//Loop through the newly created circles and attached 'mousedown' event to each
circleArray.forEach((circleElement)=>{
circleElement.addEventListener('mousedown', (event)=>{
mouseDown = true;
offset = [
circleElement.offsetLeft - event.clientX,
circleElement.offsetTop - event.clientY
]
circleClickedOn = [circleElement]
})
})
//Move circles around
canvas.addEventListener('mousemove', (event)=>{
if(mouseDown){
let mousePosition;
mousePosition = {
x: event.clientX,
y: event.clientY
}
circleClickedOn[0].style.left = `${offset[0] + mousePosition.x}px`
circleClickedOn[0].style.top = `${offset[1] + mousePosition.y}px`
}
})
}
}
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
position: relative;
width: 100%;
min-height: 100vh;
user-select: none;
}
.sidebar{
position: fixed;
top: 0;
left: 0;
background-color: #17202A;
width: 50px;
min-height: 100vh;
}
.sidebar .sidebar-top{
position: relative;
height: 35px;
}
.sidebar .sidebar-top #toggle-btn{
position: absolute;
display: flex;
height: 35px;
width: 100%;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
color: #808B96
}
.sidebar .sidebar-center{
position: relative;
width: 100%;
margin-top: 15px;
}
.sidebar .sidebar-center ul li{
position: relative;
height: 35px;
margin-bottom: 5px;
list-style: none;
}
.sidebar .sidebar-center ul li a{
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 35px;
text-decoration: none
}
.sidebar .sidebar-center ul li a{
font-size: 18px;
color: #808B96
}
.sidebar .sidebar-center ul li a:hover{
background-color: #2e4053
}
.canvas-container{
position: absolute;
top: 0;
width: calc(100% - 50px);
min-height: 100vh;
left: 50px;
padding: 20px;
background-color: #2E4053
}
.canvas-container #canvas{
position: relative;
width: 100%;
min-height: 100vh;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>hiveport</title>
<link rel="stylesheet" href="style.css">
<!-- Boxicons CDN Link -->
<link href='https://unpkg.com/boxicons#2.0.7/css/boxicons.min.css' rel='stylesheet'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="sidebar">
<div class="sidebar-top">
<i class='bx bx-menu' id="toggle-btn"></i>
</div>
<div class="sidebar-center">
<ul class="nav-list">
<li>
<a href="#" id="design-btn">
<i class='bx bx-pyramid'></i>
</a>
</li>
<li>
<a href="#" id="edit-btn">
<i class='bx bxs-edit-alt'></i>
</a>
</li>
</ul>
</div>
</div>
<div class="canvas-container">
<div id="canvas"></div>
<script src="script.js"></script>
</body>
</html>
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 2 years ago.
javascript noob here, I have the following pickle.
I'm trying to make a resizable div and I found this code:
var m_pos;
function resize(event) {
var parent = resize_el.parentNode;
var dx = m_pos - event.x;
m_pos = event.x;
parent.style.width = (parseInt(getComputedStyle(parent, '').width) + dx) + "px";
}
var resize_el = document.getElementById("resize");
if (resize_el) {
resize_el.addEventListener("mousedown", function(event) {
m_pos = event.x;
document.addEventListener("mousemove", resize, false);
}, false);
}
document.addEventListener("mouseup", function() {
document.removeEventListener("mousemove", resize, false);
}, false);
#update_panel {
position: fixed;
min-width: 420px;
padding-left: 4px;
height: 100%;
top: 0%;
right: 0;
background-color: #f0f0f0;
}
#resize {
background-color: #ccc;
position: absolute;
left: 0;
width: 4px;
height: 100%;
cursor: w-resize;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="update_panel">
<div id="resize"></div>
</div>
</body>
</html>
My file looks like this:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var m_pos;
function resize(event) {
var parent = resize_el.parentNode;
var dx = m_pos - event.x;
m_pos = event.x;
parent.style.width = (parseInt(getComputedStyle(parent, '').width) + dx) + "px";
}
var resize_el = document.getElementById("resize");
if (resize_el) {
resize_el.addEventListener("mousedown", function(event) {
m_pos = event.x;
document.addEventListener("mousemove", resize, false);
}, false);
}
document.addEventListener("mouseup", function() {
document.removeEventListener("mousemove", resize, false);
}, false);
</script>
<style>
#update_panel {
position: fixed;
min-width: 420px;
padding-left: 4px;
height: 100%;
top: 0%;
right: 0;
background-color: #f0f0f0;
}
#resize {
background-color: #ccc;
position: absolute;
left: 0;
width: 4px;
height: 100%;
cursor: w-resize;
}
</style>
</head>
<body>
<div id="update_panel">
<div id="resize"></div>
</div>
</body>
</html>
I'm using XAMPP localhost with Chrome. Please help me!
Move <script>....</script> block code to the end of <body>. Like this:
<body>
<div>
...
</div>
<script>
...
</script>
</body>
it should work
For an explanation of why this works see here:
Where should I put <script> tags in HTML markup?
I have a game with a character that goes to a random position whenever you click on it. Also, I made it so the game automatically goes into full-screen. However, sometimes, the character goes way off-screen and (because there are no scroll bars in full-screen) you cant get to it. The code is below.
<!doctype html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Alfa Slab One' rel='stylesheet'> <!-- add the font used -->
<script type="text/javascript">
function move() { //move the bird
const height = screen.height; //set the screen params
const width = screen.width;
const box = document.getElementById("bird"); //search for the bird
let randY = Math.floor((Math.random() * height) + 1); //randomise the coords
let randX = Math.floor((Math.random() * width) + 1);
box.style.transform = `translate(${randX}px, ${randY}px)`; //move the bird
addScore(); //add the score
}
</script>
<script type="text/javascript">
function getreqfullscreen(){ //full screen it. I cant really understand how it works
var root = document.documentElement
return root.requestFullscreen || root.webkitRequestFullscreen || root.mozRequestFullScreen || root.msRequestFullscreen
}
function startFullScreen() {
var pagebody = document.getElementById("main");
var globalreqfullscreen = getreqfullscreen();
document.addEventListener('click', function(e){
var target = e.target
globalreqfullscreen.call(pagebody)
}, false)
}
</script>
<script type="text/javascript">
var points = 0;
function addScore() { //add the score
var pointcount = document.getElementById("scoreCount"); //get the score counter
//var points = 45; --used for testing
points = points + 1; //increment the points
pointcount.innerText = "score: " + points;
//pointCounter.removeChild(pointCounter.childNodes[0]); --used for an older prototype
}
/**************************************/
function startCountdown() { //initiate the timer - starts when the <body> loads
startFullScreen(); //make it full screen
var time = 9999999999999999999999; //would be 60, but I made it infinite
setInterval(function() { //decrease every second
var timer = document.getElementById("Timer"); //get the timer
time = time - 1; //decrement the timer
timer.innerText = "time: " + time;
if(time == 0) { //if you finished
var continuE = prompt("Would you like to restart? (type Y for yes and N for no (case sensitive)).");
if(continuE == "Y") {
window.location.reload();
} else {
history.go(-1);
}
}
},1000);
}
</script>
<style>
html {
cursor: crosshair;
background-color: #00b0e6;
user-select: none;
}
#bird {
position: absolute;
background-color: #ffffff;
cursor: crosshair;
transition: all 1s ease-in-out;
}
#bird:hover {
invert: 0 0 12px #ff0000;
}
/*
span {
height:10px;ss
width:200px;
border:5px double red;
color:#ff00ff;
background-color:#00ffff;
}
*/
p {
color: #ff00ff;
background-color: #000000;
border: 5px double red;
height: 60px;
width: 85px;
margin: 10px;
font-family: "Times New Roman";
}
.restartButton {
border-radius: 999px;
background-color: #ff00ff;
color: #00fffff;
border: 10px double blue;
transition: all 1s ease-out;
margin-left: 50%;
margin-right: 50%;
position: relative;
cursor: help;
}
.restartButton:hover {
border-radius: 999px;
background-color: #ffffff;
color: #4500fff;
border: 10px solid red;
}
#scoreCount {
color: #aff823;
position: fixed;
top: 0;
width: 10px;
height: 10px;
}
#Timer {
color: #aff823;
position: fixed;
top: 0;
left: 200px;
width: 10px;
height: 10px;
}
span {
font-family: Alfa Slab One;
}
#main {
background-color: #00b0e6;
}
</style>
</head>
<body onload="startCountdown()" id="body">
<div id="main">
<div id="pointCounter"><span id="scoreCount"></span><span id="Timer"></span></div>
<input type="button" value="RESTART" onclick="window.location.reload();" class="restartButton"/>
<img src="https://art.pixilart.com/81a784782ea5697.png" alt="" height="50px" width="50px" id="bird" onclick="move();">
</div>
<noscript>
YOU DO NOT HAVE JAVASCRIPT ENABLED. PLEASE ENABLE JAVASCRIPT ELSE THIS WEB PAGE WILL NOT WORK.
</noscript>
</body>
</html>
Because of how stack overflow works, it doesn't go into full-screen.
P.S. I have made it infinite time, it's meant to only be 60 seconds.
I've found this and tried to fix it as the logic behind it is similar to what I'm trying to achieve. I've manage to get it working with minimal editing. but it isn't working as expected.
note: I have commented out the click feature as it is working fine.
What is happening
If you click on the volumeBtn and accidentally move the cursor out of the volumeRange div height or width while sliding either left or right, the mouseup event listener doesn't get executed when you stop clicking the mouse.
Like 1, after clicking the volumeBtn you cannot drag the volumeBtn left or right once it goes outside the `volumeRange' div.
There is a flicker from the zeroth position to the desired position.
What I Want to happen
If you click on the volumeBtn then stop clicking the mouse, the mouseup event should be executed even if the cursor is no longer on the volumeRange.
If you click on the volumeBtn you should be able to drag the volumeBtn left or right even if the cursor is no longer on the volumeRange.
const volume = document.querySelector('.volume');
const volumeRange = document.querySelector('.volume-range');
const volumeBtn = document.querySelector('.volume-button');
// volumeRange.addEventListener("click", volumeClick );
// function volumeClick(event) {
// let x = event.offsetX;
// volume.style.width = (Math.floor(x) + 10) + 'px';
// }
let mouseIsDown = false;
volumeBtn.addEventListener("mouseup", up);
volumeBtn.addEventListener("mousedown", down);
volumeRange.addEventListener("mousemove", volumeSlide);
function down(){ mouseIsDown = true; }
function up(){ mouseIsDown = false; }
function volumeSlide(event) {
if (mouseIsDown) {
let x = event.offsetX;
console.log(x);
volume.style.width = Math.floor(x + 10) + 'px';
}
}
body {
background-color: #2a2a2a;
}
.volume-range {
margin-top: 80px;
height: 5px;
width: 250px;
background: #555;
border-radius: 15px;
}
.volume-range>.volume {
height: 5px;
width: 50px;
background: #2ecc71;
border: none;
border-radius: 10px;
outline: none;
position: relative;
}
.volume-range>.volume>.volume-button {
width: 20px;
height: 20px;
border-radius: 20px;
background: #FFF;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
outline: none;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Volume</title <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>
<style>
</style>
<body>
<div class="volume-range">
<div class="volume">
<div class="volume-button"></div>
</div>
</div>
</body>
</html>
Why it doesn't work
This is working the way you described it because mouse events will only be fired when the mouse is inside the element that have the listeners attached.
An immediate (but not very good) solution to this will be to move the listener for "mouseup" and "mousemove" from the volumeBtn/volumeRange to the window object. This is not very good because if you will later need to remove this element, you should also remove the listeners from the window object.
Better solution
It would be better to encapsulate the slider inside another element that will give it some padding, and then put the event listeners on that "container" element. It will still stop moving when you go outside the element, but at least everything is self-contained.
This is shown in the following snippet:
const volume = document.querySelector('.volume');
const volumeRange = document.querySelector('.volume-range');
const volumeContainer = document.querySelector('.volume-container');
const volumeBtn = document.querySelector('.volume-button');
// volumeRange.addEventListener("click", volumeClick );
// function volumeClick(event) {
// let x = event.offsetX;
// volume.style.width = (Math.floor(x) + 10) + 'px';
// }
let mouseIsDown = false;
volumeContainer.addEventListener("mouseup", up);
volumeBtn.addEventListener("mousedown", down);
volumeContainer.addEventListener("mousemove", volumeSlide, true);
function down(){ mouseIsDown = true; }
function up(){ mouseIsDown = false; }
const volumeRangeWidth = volumeRange.getBoundingClientRect().width; // This will be the volume limit (100%)
function volumeSlide(event) {
if (mouseIsDown) {
let x = event.offsetX;
if (event.target.className == "volume-container") {
x = Math.floor(x);
if (x < 0) x = 0; // check if it's too low
if (x > volumeRangeWidth) x = volumeRangeWidth; // check if it's too high
volume.style.width = (x+10) + 'px';
}
}
}
body {
background-color: #2a2a2a;
}
.volume-container {
padding: 40px 0px;
margin: 0px 20px;
}
.volume-range {
height: 5px;
width: 250px;
background: #555;
border-radius: 15px;
}
.volume-range>.volume {
height: 5px;
width: 50px;
background: #2ecc71;
border: none;
border-radius: 10px;
outline: none;
position: relative;
}
.volume-range>.volume>.volume-button {
width: 20px;
height: 20px;
border-radius: 20px;
background: #FFF;
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
outline: none;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Volume</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
</head>
<style>
</style>
<body>
<div class="volume-container">
<div class="volume-range">
<div class="volume">
<div class="volume-button"></div>
</div>
</div>
</div>
</body>
</html>
Other problems
In the fiddle it is also shown how to avoid the volume to go outside the container.
I have created a simle JS slider that reacts to the click by eventListener onmousedown. But if you will run the code below, you will see, that the toddler does not stop correctly by the eventListener onmouseup if we leave the scroll zone scrollContainer with holding the left mouse button. The toddler will scroll loosely under we will click directly on the him.
What is needed - the toddler must stop when we will release the left mouse button (after end eventListener onmousedown).
I will be grateful for help.
var scrollLine = document.getElementById('scrollBar');
var scrollTog = document.getElementById('toddler');
function letsMove(event) {
var coordsHelp = getRealCoords(toddler);
var shiftX = event.pageX - coordsHelp.left;
getCoords(event);
function getRealCoords(toddler) {
var box = toddler.getBoundingClientRect();
return {
left: box.left + pageXOffset
}
};
function getCoords(event) {
var currentPosition = event.pageX - shiftX;
if (currentPosition >= 300) {
toddler.style.left = 300 + 'px';
} else if (currentPosition <= 104) {
toddler.style.left = 104 + 'px';
} else {
toddler.style.left = currentPosition + 'px';
}
};
scrollContainer.onmousemove = function(event) {
getCoords(event);
console.log();
};
toddler.ondragstart = function() {
return false;
};
toddler.onmouseup = function() {
scrollContainer.onmousemove = null;
scrollContainer.onmouseup = null;
toddler.onmouseup = null;
toddler.onmousemove = null;
return false;
};
}
toddler.addEventListener( 'mousedown', letsMove );
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
#scrollContainer {
width: 400px;
height: 200px;
border: 1px solid grey;
border-radius: 4px;
}
#scrollBar {
width: 200px;
height: 5px;
background-color: grey;
border: 1px solid grey;
border-radius: 4px;
margin-top: 24%;
margin-left: 24%;
}
#toddler {
width: 10px;
height: 25px;
position: absolute;
margin-top: -11px;
background-color: blue;
border: 1px solid grey;
border-radius: 2px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="scrollContainer">
<div id="scrollBar">
<div id="toddler"></div>
</div>
</div>
<script>
</script>
</body>
</html>
The fix for this is almost embarrassingly simple. The reason you're not getting the onmouseup fired when the mouse isn't over the "toddler" is quite literally because the mouse isn't over the "toddler". (mouse events won't fire for objects that the mouse pointer is not touching).
Simply change the listener to the entire window (in "real" code you may want to add a guard so that you're aware of which slider is expecting the mouse up).
var scrollLine = document.getElementById('scrollBar');
var scrollTog = document.getElementById('toddler');
function letsMove(event) {
var coordsHelp = getRealCoords(toddler);
var shiftX = event.pageX - coordsHelp.left;
getCoords(event);
function getRealCoords(toddler) {
var box = toddler.getBoundingClientRect();
return {
left: box.left + pageXOffset
}
};
function getCoords(event) {
var currentPosition = event.pageX - shiftX;
if (currentPosition >= 300) {
toddler.style.left = 300 + 'px';
} else if (currentPosition <= 104) {
toddler.style.left = 104 + 'px';
} else {
toddler.style.left = currentPosition + 'px';
}
};
scrollContainer.onmousemove = function(event) {
getCoords(event);
console.log();
};
toddler.ondragstart = function() {
return false;
};
/* toddler.onmouseup = function() { */
window.onmouseup = function() {
scrollContainer.onmousemove = null;
scrollContainer.onmouseup = null;
toddler.onmouseup = null;
toddler.onmousemove = null;
return false;
};
}
toddler.addEventListener('mousedown', letsMove);
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
#scrollContainer {
width: 400px;
height: 200px;
border: 1px solid grey;
border-radius: 4px;
}
#scrollBar {
width: 200px;
height: 5px;
background-color: grey;
border: 1px solid grey;
border-radius: 4px;
margin-top: 24%;
margin-left: 24%;
}
#toddler {
width: 10px;
height: 25px;
position: absolute;
margin-top: -11px;
background-color: blue;
border: 1px solid grey;
border-radius: 2px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="scrollContainer">
<div id="scrollBar">
<div id="toddler"></div>
</div>
</div>
<script>
</script>
</body>
</html>
One solution to this could be
Bind a mouseout event to a specific targetted region and as soon the mouse goes out of that region you should manually trigger or in javascript we should say dispatch event mousedown and that should be bound to the outer slider container so that having multiple sliders on a single page won't affect each other. As soon as you range out of the container the mouseout event will dispatch the toddler mousedown event.
A sample code for preventing the mouseout to trigger if a child element is hovered is taken from here, see your slider below.
var scrollContainer = document.getElementById('scrollContainer');
var scrollLine = document.getElementById('scrollBar');
var toddler = document.getElementById('toddler');
function letsMove(event) {
var coordsHelp = getRealCoords(toddler);
var shiftX = event.pageX - coordsHelp.left;
getCoords(event);
function getRealCoords(toddler) {
var box = toddler.getBoundingClientRect();
return {
left: box.left + pageXOffset
}
};
function getCoords(event) {
var currentPosition = event.pageX - shiftX;
if (currentPosition >= 300) {
toddler.style.left = 300 + 'px';
} else if (currentPosition <= 104) {
toddler.style.left = 104 + 'px';
} else {
toddler.style.left = currentPosition + 'px';
}
};
scrollContainer.onmousemove = function(event) {
getCoords(event);
console.log();
};
toddler.ondragstart = function() {
return false;
};
toddler.onmouseup = function() {
scrollContainer.onmousemove = null;
scrollContainer.onmouseup = null;
toddler.onmouseup = null;
toddler.onmousemove = null;
return false;
};
}
function makeMouseOutFn(elem) {
var list = traverseChildren(elem);
return function onMouseOut(event) {
var e = event.toElement || event.relatedTarget;
if (!!~list.indexOf(e)) {
return;
}
// handle mouse event here!
if ('createEvent' in document) {
// modern browsers, IE9+
var e = document.createEvent('HTMLEvents');
e.initEvent('mousedown', false, true);
toddler.dispatchEvent(e);
} else {
// IE 8
var e = document.createEventObject();
e.eventType = 'mousedown';
toddler.fireEvent('on' + e.eventType, e);
}
};
}
//quick and dirty BFS children traversal, Im sure you could find a better one
function traverseChildren(elem) {
var children = [];
var q = [];
q.push(elem);
while (q.length > 0) {
var elem = q.pop();
children.push(elem);
pushAll(elem.children);
}
function pushAll(elemArray) {
for (var i = 0; i < elemArray.length; i++) {
q.push(elemArray[i]);
}
}
return children;
}
toddler.addEventListener('mousedown', letsMove);
scrollContainer.addEventListener('mouseout', makeMouseOutFn(scrollContainer), true);
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<style>
#scrollContainer {
width: 400px;
height: 200px;
border: 1px solid grey;
border-radius: 4px;
}
#scrollBar {
width: 200px;
height: 5px;
background-color: grey;
border: 1px solid grey;
border-radius: 4px;
margin-top: 24%;
margin-left: 24%;
}
#toddler {
width: 10px;
height: 25px;
position: absolute;
margin-top: -11px;
background-color: blue;
border: 1px solid grey;
border-radius: 2px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="scrollContainer">
<div id="scrollBar">
<div id="toddler"></div>
</div>
</div>
</body>
</html>