How to move a div with javascript - javascript

I am definitely new to Javascript.My goal is to build two divs and animate the child just by using Javascript.But there is some kind of problem in my function, and despite this being a trivial task I couldn’t find anything.
So, these are my buttons and my divs(I’m just trying to figure out how the start button works, then I am going to deal with the others
//create elements
const start = document.createElement('button');
const reset = document.createElement('button');
const stop = document.createElement('button');
const parent = document.createElement("div");
const child= document.createElement("div");
document.body.append(parent);
parent.append(child);
document.body.append(start);
document.body.append(reset);
document.body.append(stop);
// style
parent.style.width = "200px";
parent.style.height = "200px";
child.style.width = "20px";
child.style.height = "20px";
child.style.background = "green"
parent.style.background = "red";
start.innerHTML = "start";
reset.innerHTML = "reset";
stop.innerHTML = "stop";
and this is my useless function which doesn’t look right
/functions and listeners
var g =setInterval(move(),2000);
function move(){
var pos = 0;
if (pos == 200) {
clearInterval(g);
}
else {
pos++;
child.style.top = pos + "px";
child.style.left = pos + "px";
}
}
start.addEventListener("click",move());
any kind of tip or advice is appreciated =)

You have several problems:
The pos variable needs to be declared outside of the function that
uses it so that its value won't be lost when the function runs and
then can be used when the function runs additional times.
The start button's click event handler should be where the interval
timer is started, otherwise it begins immediately.
Both setInterval() and .addEventListener() take
function references - - you do not invoke a function in
their arguments (unless that function returns a function and that
returned function is what you want to reference). So, neither should
have () after the function name.
Your parent and child elements need to be positioned so that they are
not in the normal document flow, otherwise setting a top or left
CSS property won't do anything.
Don't use .innerHTML when you aren't working with HTML strings as
.innerHTML has security and performance implications. When you just
have text to work with, use .textContent.
See other comments inline:
//create elements
const start = document.createElement('button');
const reset = document.createElement('button');
const stop = document.createElement('button');
const parent = document.createElement("div");
const child= document.createElement("div");
document.body.append(parent);
parent.append(child);
document.body.append(start);
document.body.append(reset);
document.body.append(stop);
/* Use CSS classes instead of inline styles */
parent.classList.add("parent");
child.classList.add("child");
start.textContent = "start";
reset.textContent = "reset";
stop.textContent = "stop";
//functions and listeners
var timer = null;
var pos = 0;
function move(){
// Since it's the top and left of the child that are being set, we
// need to subtract the width of the box from the size of the parent
// so that the child doesn't end with its top and left outside of the
// parent.
if (pos == 180) {
clearInterval(timer);
} else {
pos++;
child.style.top = pos + "px";
child.style.left = pos + "px";
}
}
start.addEventListener("click", function() {
// The timer should start when the button is clicked
timer = setInterval(move,20);
});
reset.addEventListener("click", function() {
clearInterval(timer); // Stop the timer so motion stops
pos = 0;
child.style.top = pos+ "px";
child.style.left = pos + "px";
});
/* The child needs to be taken out of the normal document flow so it can be
explicitly positioned, but we want it to be relative to the parent it is
inside of, so the parent also has to be positioned explicitly. */
.parent { position:relative; width: 200px; height:200px; background-color:red; }
.child { position:relative; width: 20px; height:20px; background-color:green; }

Related

When anywhere on the body is clicked, different sentences should pop up in the mouse location

I'm trying to create an interactive website where the user is able to click on any section of a blank screen and the text will show up in that exact position where the user clicks. It would be greatly appreciated if anyone knows how to do this. Every time the user clicks, a new sentence appears and there's only so many times you can click the page.
var quotes = ["quote1", "quote2"];
var current = 0;
function changeQuote() {
if (current >= quotes.length) current = 0;
document.getElementById("paragraph").innerHTML(quotes[current]);
current++;
}
document.body.onclick = changeQuote;
This is what I started with but this doesn't seem to working, would I need an EventListener and how would I go about this?
document.addEventListener('click', (e) => {
const {
clientX,
clientY
} = e; //get the click position
//create the div
const div = document.createElement('div');
//set its text
div.innerText = 'some text';
//set its position and position style
div.style.position = "absolute";
div.style.left = clientX + 'px';
div.style.top = clientY + 'px';
document.body.append(div);//add div to the page
})

Draggable JS element not recentering on button click

I have the following JS code I am using to move something around on the screen and then when i click a button I want to move everything back to where the original element loaded. Why does my following logic not work? I have also tried subtracting the gMouseDownOffsetX and gMouseDownOffsetY still the button does not transform the image back to the orgin of where it started.
I know the button works because it does in fact change other properties I set, but not the position.
$('#clickMe').click(function(){
$(#element).css({' transform : 'translate('+ -gMouseDownX + ')' });
$(#element).css({' transform : 'translate(' + -gMouseDownY + ')' });
});
let gMouseDownX = 0;
let gMouseDownY = 0;
let gMouseDownOffsetX = 0;
let gMouseDownOffsetY = 0;
function addListeners() {
document.getElementById('cursorImage').addEventListener('mousedown', mouseDown, false);
window.addEventListener('mouseup', mouseUp, false);
}
function mouseUp() {
window.removeEventListener('mousemove', divMove, true);
}
function mouseDown(e) {
gMouseDownX = e.clientX;
gMouseDownY = e.clientY;
var div = document.getElementById('cursorImage');
//The following block gets the X offset (the difference between where it starts and where it was clicked)
let leftPart = "";
if(!div.style.left)
leftPart+="0px"; //In case this was not defined as 0px explicitly.
else
leftPart = div.style.left;
let leftPos = leftPart.indexOf("px");
let leftNumString = leftPart.slice(0, leftPos); // Get the X value of the object.
gMouseDownOffsetX = gMouseDownX - parseInt(leftNumString,10);
//The following block gets the Y offset (the difference between where it starts and where it was clicked)
let topPart = "";
if(!div.style.top)
topPart+="0px"; //In case this was not defined as 0px explicitly.
else
topPart = div.style.top;
let topPos = topPart.indexOf("px");
let topNumString = topPart.slice(0, topPos); // Get the Y value of the object.
gMouseDownOffsetY = gMouseDownY - parseInt(topNumString,10);
window.addEventListener('mousemove', divMove, true);
}
function divMove(e){
var div = document.getElementById('cursorImage');
div.style.position = 'absolute';
let topAmount = e.clientY - gMouseDownOffsetY;
div.style.top = topAmount + 'px';
let leftAmount = e.clientX - gMouseDownOffsetX;
div.style.left = leftAmount + 'px';
}
addListeners();
I found that your position is moved by setting top and left. Why not try to directly set the top and left values to the default values?
Update:
try this:
$('#clickMe').click(function(){
$("#cursorImage").css({ left: 0, top: 0});
});

How to call function every time div reaches max-height?

I want to call a function only once every time the div #blinds reach their max-height at 430px, how can I do this?
My Codepen: https://codepen.io/cocotx/pen/YzGBpVJ
window.addEventListener('mousemove', function(event) {
var blinds = document.getElementById("blinds");
blinds.style.height = event.clientY + 'px';
});
One polling way is adding the code below in your js if there are other behaviours changing the size of the element. Simply change 400 to the value you want.
var blinds = document.getElementById("blinds");
setInterval(() => {
let rect = blinds.getBoundingClientRect();
if (rect.height > 400)
console.log(" reach 400");
}, 100);
window.addEventListener('mousemove', function(event) {
var blinds = document.getElementById("blinds");
blinds.style.height = event.clientY + 'px';
// i added here the condition
if(blinds.offsetHeight > 430 /*the value you want*/){
//call your function
}
});
Notice that this doesn't work if you use blinds.style.height instead of blinds.offsetHeight, there's a difference between using these but i im still trying to figure it out.
I would suggest to clean your code:
window.addEventListener('mousemove',handler);
function handler(event){
...
if(blinds.offsetHeight >430){
//call your function
...
//and maybe remove the listener
window.removeEventListener('mousemove',handler);
}
};
EDIT: try this code
function hasReachedMax(){
var styles = getComputedStyle(blinds);
var borderBottom = styles.borderBottom.split("px")[0]; //this is to get the number of pixels
var borderTop = styles.borderTop.split("px")[0];
var maxH = styles.maxHeight.split("px")[0];
var currentDivSize = blinds.offsetHeight-borderBottom-borderTop;
return maxH == currentDivSize;
};
function resetTrigger(){
//the condition to reset your trigger, for example making the div element at least 5 px smaller than maxHeight
var styles = getComputedStyle(blinds);
var borderBottom = styles.borderBottom.split("px")[0];
var borderTop = styles.borderTop.split("px")[0];
var maxH = styles.maxHeight.split("px")[0];
var currentDivSize = blinds.offsetHeight-borderBottom-borderTop;
return maxH-currentDivSize>5;
};
//this should be part of your main code
var trigger = true;
window.addEventListener('mousemove', function(event) {
var blinds = document.getElementById("blinds");
blinds.style.height = event.clientY + 'px';
if(hasReachedMax()&&trigger){
//call your function
console.log("Im called now");
trigger=false;
}
if(resetTrigger()) trigger=true;
});

Executing a line in a conditional AND by default on start

I have this fiddle: http://jsfiddle.net/zhaem/Lyzrtefo/7/
var orangeMode = true
var isTracking = true
getMouseXY = function(e) {
if (isTracking) {
var tempX = e.pageX
var tempY = e.pageY
if (tempX < 0){tempX = 0}
if (tempY < 0){tempY = 0}
document.getElementById("circle1").style.top = (tempY - 25) + "px";
document.getElementById("circle1").style.left = (tempX - 25) + "px";
}
return true
}
document.onmousemove = getMouseXY;
var toggleTrackCircle = function() {
isTracking = !isTracking;
console.log(isTracking);
}
document.getElementById("circle1").addEventListener("click", toggleTrackCircle);
flip = function() {
orangeMode = !orangeMode;
if (orangeMode) {
document.getElementById("circle1").style.backgroundColor = "orange";
document.getElementById("circle1").addEventListener('mouseover', function() {isTracking = true;})
// When the above line is executed the circle will stick to your cursor on HOVER after clicking and setting it down.
} else {
document.getElementById("circle1").style.backgroundColor = "blue";
}
}
document.getElementById("box3").addEventListener("click", flip);
There is this one line, that when present will change the behavior of the interaction. (You can always click to stop the cursor from tracking you, but when this line is there, the circle will re-stick to it on hover, and when it's not, it will only restick on hover + click.
document.getElementById("circle1").addEventListener('mouseover', function() {isTracking = true;})
I'm trying to wrap it in some conditional logic in the flip function (which you can control by tapping the red box in the corner) so that orangeMode == it sticks on hover and not orangeMode it only re-sticks on click.
The flip function works fine for changing the color, but this event listener isn't performing like I'd want. (once you cycle through it does work but for either state and it's not running orangeMode unload.
Any help would be much appreciated.
You need to put 'isTracking=true;' inside a named function, so you can use "removeEventListener" to take the function off. That means you add this function:
var trackCircle = function() {
isTracking = true;
}
Then you reference that on click instead of the anonymous function:
circle.addEventListener('mouseover', trackCircle)
Then you simply remove that event in your else:
circle.removeEventListener('mouseover', trackCircle)
Oh, and I'd add this at the top so you don't need to keep repeating the getElementById phrase:
circle = document.getElementById("circle1");
Hope that helps. Oh, and here's the edit to your fiddle:
http://jsfiddle.net/Lyzrtefo/9/

Dynamically change div height with window resize

I wanted to change height of a div when window is resized. I know it can be done with css using height:100%; but that doesn't work on what i need. I wanted to make this happen in pure javascript without JQuery or any other framework.
Here is what i have done:
<div id="left">
<div id="inner">
</div>
</div>
CSS
#left{
margin-top:40px;
width:200px;
height:576px;
background:white;
}
#inner{
height:100%;
overflow-y:scroll;
}
JAVASCRIPT
window.onload=
window.onresize=function(){
var left=document.getElementById('left');
var window_height = window.innerheight;
if ( window_height > 600px ) { left.style.height = document.body.offsetHeight
+"px"; }
else { }
}
The div with id left has to have the same margin. I just wanted to change the height of div to match the inner window height (in px no %).
Thank You.
window.innerheight should be window.innerHeight (capital H). Note that IE doesn't support it prior to IE9.
Also note that you're comparing an element with a number here:
if ( left < window_height )
// ^--- element
You probably wanted to get the height from left instead, as that condition will never be true.
please see jsfiddle jsfiddle
try to use console.log to know what kind of value or object you dealing with
window.onload = window.onresize = function () {
var left = document.getElementById('left');
var window_height = window.innerHeight;
console.log(left.offsetHeight);
console.log(window_height);
if (left.offsetHeight < window_height) {
left.style.height = window_height + "px";
} else {}
}
set 100% first to know the exact height number, then assign back to height.
updated code updated jsfiddle
window.onload = window.onresize = function () {
var left = document.getElementById('left');
console.log(left.offsetHeight);
var window_height = window.innerHeight;
if (left.offsetHeight < window_height) {
left.style.height = '100%';
left_height=left.offsetHeight;
console.log(left_height);
left.style.height = left_height + "px";
} else {}
};
For those looking for old-school solution that uses debounce based on timeouts, here is what you can do:
function debounce(func, wait = 20, immediate = true) {
let timeout;
return function() {
const context = this,
args = arguments;
const later = function() {
timeout = null;
if (!immediate) { func.apply(context, args); }
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) { func.apply(context, args); }
};
}
function updateHeight(div, height) {
div.style.height = `${height}px`;
}
window.addEventListener('resize', debounce(() => {
const div = document.querySelector('.selector');
updateHeight(div, 50);
}));
Debounce will throttle updates down (by default update will fire every 20ms during resizing). Note you need to update updateHeight arguments and .selector to match your div.

Categories