I've been trying to move a red box 20px on mouseover. But instead of adding 20px to the current position it just goes to position "20px".
I got the idea for this here: Move an image with the arrow keys using JavaScript
But it's not working for me :/
Thanks!
<html>
<head>
<meta charset="UTF-8">
<style>
#element {
position: absolute;
left:100px;
top:100px;
height: 140px;
width: 60px;
background-color: red;
}
</style>
</head>
<body>
<div id="element"></div>
<script>
window.addEventListener('load', function () {
boxElement = document.getElementById('element');
if (boxElement) {
boxElement.addEventListener('mouseover', function () {
boxElement.style.left += 20 + 'px';
});
}
});
</script>
</body>
</html>
boxElement.style.left returns a string which looks like "123px".
The first time you execute
boxElement.style.left += 20 + 'px';
it will be fine, since boxElement.style.left will be an empty string. But the second time, you are trying to set style.left to 20px20px (string concatenation!), so the browser simply ignores the new value, and keep the old one, 20px.
You have to parse the position out of the value first, using parseInt and then add to it:
var left = boxElement.style.left;
boxElement.style.left = (parseInt(left, 10) + 20) + 'px';
The other problem is that boxElement.style.left won't return the initial value which was inherited from the CSS class. For that you can use getComputedStyle and set it once before you bind the event handler:
var boxElement.style.left =
window.getComputedStyle(boxElement,null).getPropertyValue("left");
If you read the code of the linked question properly, you can see that that's exactly what was done there:
element.style.left = parseInt(element.style.left) - 5 + 'px';
You're adding a string "20px" to an empty string, which is effectively setting the style property of the boxElement to "left: 20px", overriding the stylesheet.
You could get the current computed style of the element each time and add to it, or you could keep a closure-scoped variable with the position, like this:
window.addEventListener('load', function () {
var x=window.getComputedStyle(boxElement,null).getPropertyValue("left");
boxElement = document.getElementById('element');
if (boxElement) {
boxElement.addEventListener('mouseover', function () {
x+=20;
boxElement.style.left = x + 'px';
});
}
});
Related
I have below code already and working well to scroll down to the ID ('expressRate') on page loading. But with change of requirement the page should scroll down to a point 50 pixels above the div ID 'expressRate'. Any help would be appreciated.
$location.hash('expressRate');
$anchorScroll();
try this javascript code after you scroll to the tag 'expressRate'
window.location('#expressRate');
window.scrollBy(0,-50);
//get the element
var $expressRate = $('#expressRate');
//get the vertical distance of the element from the top of the page
var verticalPositionOfElement = $expressRate.offset().top;
//added a timeout just so you could see the start and then the
//adjustment
setTimeout(function () {
//scroll the window down the element distance, minus whatever
$(window).scrollTop(verticalPositionOfElement - 50);
}, 1000);
html, body {
min-height: 5000px;
}
#expressRate {
min-height: 200px;
margin-top: 1000px;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="expressRate">
window.scroll(0,findPos(document.getElementById("expressRate")) - 50);
function findPos(obj) {
var curtop = 0;
if (obj.offsetParent) {
do {
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return [curtop];
}
}
You don't need the framework for something so simple, you can use getBoundingClientRect() on the element you are trying to scroll to. Let's say:
The Element.getBoundingClientRect() method returns the size of an element and its position relative to the viewport.
Let's say that: result = b.getBoundingClientRect();
It will give you element's box in DOM related things but you really wanna only one thing: result.x coordinate representing x coordinate in pixels keeping in mind the VIEWPORT.
Now you can simply use window.scrollTo() to that element's x coordinate -50px to scroll where you wanted.
HTML:
<button id="but" onClick="scrol()">SCROLL TO 50px before</button>
<div id="a"><span id="b">WHERE AM I?</span></div>
<div id="tall"> </div>
<pre></pre>
CSS:
#but { position: fixed; }
#a { padding:16px; position: absolute; top:300px;}
#b { background:yellow;}
#tall { height:2000px }
JS:
function scrol(){
var b = document.querySelector('#b');
window.scrollTo(b.x, b.y - 200)
}
Voila, a 2-liner vanilla solution :)
For a quick demo, Please look at this Fiddle: http://jsfiddle.net/58gzv79h/1/
NOTE: In Fiddle, the solution is a bit bigger to show you how unlike other things in result, the X does not change from the time document was loaded.
I'm new using JS and I'm having troubles with a simple action:
First div is 50% width
I'm looking to subtract from its width the 50% of a Second div using JS.
Would be like:
a_div width = 50% - ( 50% width of b_div)
I've tried this but it's not working
$(document).ready(function(){
$("#h-prev").css({'width':($(".swiper-slide-prev").innerWidth())}).css('width:'-$(".swiper-slide-prev").width() * .50);
});
Get the parent width divided by 2 and subtract the other element width divided by 2
var $el = $("#h-prev"),
parentWidth = $el.parent().width(),
otherWidth = $(".swiper-slide-prev").width(),
newWidth =(parentWidth/2) - (otherWidth/2)
$el.width( newWidth );
I don't know exactly if this is what you are looking for, but I've written up this demo in plain javascript: https://jsfiddle.net/tubL1qxr/2/
var a = document.getElementById('a'), // element a
b = document.getElementById('b'), // element b
h = document.getElementById('h'); // button
h.addEventListener('click', changeSize);
function changeSize() {
a.style.width = ((window.innerWidth / 100 *50) - (b.offsetWidth /100*50)) + 'px';
}
You would quite obviously, have to modify it to fit your code.
This takes the first and the second divs width, then subtracts half of the second divs width from the first div's width (which is 50% initially).
Is this what you meant:
$(document).ready(function(){
var secondDivWidth = parseInt($('#second-div').css('width'));
var firstDivWidth = parseInt($('#first-div').css('width'));
$('#first-div').css('width', firstDivWidth - secondDivWidth/2);
// Example purposes only
console.log("Width before change (50%): " + firstDivWidth);
console.log("Width after change: " + $('#first-div').css('width'));
})
#first-div {
border: black solid 1px;
height: 100px;
width:50%;
}
#second-div {
border: red solid 1px;
height: 100px;
width: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first-div">
</div>
<div id="second-div">
</div>
You have syntax errors:
jQuery css() functions works in 2 ways, accept object or 2 parameters:
1) css('attr', value)
2) css({'attr':value})
So you can correct this 'width:' and put this 'width': and put in {}
Result will be following:
$(document).ready(function() {
$("#h-prev").css({
'width': ($(".swiper-slide-prev").innerWidth())
}).css({'width':- $(".swiper-slide-prev").width() * .50});
});
In case of giving only one parametter you can use second option and code will be following
$(document).ready(function() {
$("#h-prev").css('width', ($(".swiper-slide-prev").innerWidth())).css('width', -$(".swiper-slide-prev").width() * .50);
});
So now syntax is correct, and if you will put here your code with snippet I will be able to help you with functionality.
This is how I detect the top margin of a div and increase/decrease it:
var oldm = $("#bdi").css("margin-top").replace("px", "");
var addm = 1;
$("#bdi").css({
'margin-top': '-='+addm+'px'
})
But I need to do the same with background position.
detect the actual top position of a background image
increase/decrease the top margin of a background image
For example:
background-position: center 5px;
How do I detect "5px" and increase/decrease it?
Thanks
You can get it using background-position-y like this :
var bgPositionY = ($("#bdi").css('background-position-y'))
var addPos = 5;
$("#bdi").css({
'background-position-y': '-='+addPos+'px'
})
https://jsfiddle.net/IA7medd/aLkok1n4/
You don't need jQuery for this...
var el = document.getElementById('bdi'),
currentYPosition = getComputedStyle(el)['backgroundPositionY'],
increment = 1,
newYPosition = 'calc(' + currentYPosition + ' + ' + increment + 'px)';
// Set new backgroundPositionY
el.style.backgroundPositionY = newYPosition;
The use of calc() above ensures the value is properly incremented, even if a percentage position value is used.
As of jQuery 1.6, .css() accepts relative values similar to .animate(). Relative values are a string starting with += or -= to increment or decrement the current value. Link
For example like this
$("div").css("background-position-x", "+=10px");
$("div").css("background-position-Y", "-=10px");
If you want to do other operation on css value use this
$("div").css("background-position-x", function(index) {
return index * 10;
});
You can see demo at bottom
$("#increaseX").click(function(){
$("#image").css("background-position-x", "+=10px");
});
$("#decreaseX").click(function(){
$("#image").css("background-position-x", "-=10px");
});
$("#increaseY").click(function(){
$("#image").css("background-position-y", "+=10px");
});
$("#decreaseY").click(function(){
$("#image").css("background-position-y", "-=10px");
});
#image {
width: 100px;
height: 100px;
background-image: url("https://assets.servedby-buysellads.com/p/manage/asset/id/28536");
background-position: 0px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image"></div>
<button id="increaseX">increaseX</button>
<button id="decreaseX">decreaseX</button>
<br />
<button id="increaseY">increaseY</button>
<button id="decreaseY">decreaseY</button>
Firefox doesn't support background-position-x and background-position-y. If you want to do your target work in firefox, see jsfiddle
You can
If you're using jQuery, the simplest option is to use incremental notation inline:
$("#bdi").css('background-position-y', '+=5px');
(This is a follow-up on my previous question if anybody is interested in the background story for entertainment purposes. It will probably not help you understand this question.)
Here are two elements <aside> and <main> who have got their width and height via JavaScript so that their combined width is the width of your screen (note that their display is inline-block). If you run this code in your web browser (a maximized browser so that the width of your browser equals the width of your screen) you might note that the body surprisingly does not properly fit the elements:
<!DOCTYPE html>
<html>
<body>
<aside></aside><!-- comment to remove inline-block whitespace
--><main></main>
<script>
var h = screen.height/100;
var w = screen.width/100;
var e = document.getElementsByTagName("aside")[0].style;
e.display = "inline-block";
e.backgroundColor = "lightblue";
e.width = 14*w + "px";
e.height = 69*h + "px";
e.marginRight = 0.5*w + "px";
e = document.getElementsByTagName("main")[0].style;
e.display = "inline-block";
e.backgroundColor = "green";
e.width = 85.5*w + "px";
e.height = 69*h + "px";
e = document.getElementsByTagName("body")[0].style;
e.margin = e.padding = "0";
e.backgroundColor = "black";
</script>
</body>
</html>
If you however give the JavaScript a delay, the elements are rendered properly. This suggests that the body somehow "needs time" to figure out its correct width:
<script>
setTimeout(function() {
[...]
}, 200);
</script>
It is also possible to give the body the specified width of screen.width instead of introducing the delay, by adding the following line. This supports the previous guess that the body does not immediately know its correct width (unless specified):
<script>
[...]
e.width = 100*w + "px";
</script>
Even though I have taken the freedom to throw wild guesses to explain this, I do not actually have a clue to what is going on.
Why are the elements not placed properly in the first place, and why do these two solutions work?
(Note: It is also possible to fix this by setting the whitespace of the body to nowrap with e.whiteSpace = "nowrap";, but I suspect this does not do the same thing as the other two. Instead of creating space for the elements inside the body, this simply forces the elements to be next to each other even though there is not enough room in the body.)
You should wait for the DOM to be available before running your code, see here: pure JavaScript equivalent to jQuery's $.ready() how to call a function when the page/dom is ready for it. That is possibly why setTimeout works. Also you should assign seperate variable names for your different elements.
// self executing function before closing body tag
(function() {
// your code here
// the DOM will be available here
})();
Is there a reason you are using Javascript and not CSS to accomplish this task? I suggest giving your elements css ids ie id="aside", then set your css styles:
html,body {
width: 100%;
height: 100%;
}
#aside {
display:inline-block;
position: relative;
float: left;
width: 14%;
height: 69%;
background: blue;
}
#main {
display:inline-block;
position: relative;
float: left;
width: 86%;
height: 31%;
background: azure;
}
I'm a beginner in JavaScript, and trying to make a simple script that pushes a box using the mouse pointer, but unfortunately it isn't working for some reason, I hope you can help me out.
(This script is really primitive, only pushes the box from the left till now).
index.html :
<html>
<head>
<title>Chase the box</title>
<style>
body {
}
.css-box{
width : 100px;
height : 100px;
margin : auto;
background-color : blue;
}
</style>
</head>
<body>
<div id="box" class="css-box"></div>
<script type="text/javascript" src="script.js"></script>
</body>
script.js :
var box = document.getElementById("box");
var pushBox = function(e){
if(e.pageX == box.offsetLeft){
box.style.left = box.style.left + 1 + "px";
}
};
document.addEventListener("mousemove" , pushBox);
A JQuery version but accomplishes the same as you're trying to do
http://jsfiddle.net/3mxC3/1/
The main problem I can see with your script is that e.pageX == box.offsetLeft would mean that it's only going to be triggered when the pageX is exactly the offsetLeft.
The mousemove event won't be firing every pixel so this approach won't work. The easiest way to accomplish it is to set the mousemove onto the actual box instead (so it'll only fire if the user mouse overs the box)
Secondly, setting the left attribute on the box was doing nothing as the left/right-ness was being set by the margin: auto. Changing this to position: absolute makes it actually pay attention to the left attribute.
box.style.left is a string. And in JavaScript if you do string + int the int will be type casted to a string and you get string + string. For instance, if box.style.left is 10px you get:
'10px' + 1 + 'px'
int typecasted to string
'10px' + '1' + 'px'
create one string
'10px1px'
And that will be the value of box.style.left. That isn't what you want...
To solve this you can use parseInt(), which parses a string into an int:
box.style.left = parseInt(box.style.left) + 1 + "px";
And your if is only matching when the X position of the cursor is exactly the same pixel as box.offsetLeft. That's almost impossible, I don't know what you are trying to do with that if?
At least, box.style.left has no value the first time. You need to set the value at first to 0 and then use the event.
A working example will be: http://jsfiddle.net/WouterJ/enLwh/ (please note that I have added position: relative; because we can't use the left property on the current position)
Some more tips, since you are new to JS:
If you do something like this:
X = X + 12;
You can short that up as:
X += 12;
You need to set a CSS position property other than static to the element so CSS left property can work.
.css-box{
position: absolute;
width : 100px;
height : 100px;
margin : auto;
background-color : blue;
}
Lastly you are better off adding stuff onload instead of having the script live in the body
Here is a script that lives in the head of the page, the rest of the issues are already solved by other ppl here
var pushBox = function(e){
if(e.pageX >= box.offsetLeft){
box.style.left = (parseInt(box.style.left,10) + 1) + "px";
}
},box;
window.onload=function() {
box = document.getElementById("box");
document.addEventListener("mousemove" , pushBox);
}