How to increment progressively the margin left using DOM - javascript

I have an image of a black cat
I want to progressively increase its width and also make the image moving from left to right increasing its own left margin.
I can't understand why the width is increased and the margin-left shows NaN value.
Down here the Html :-
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Cat Walk</title>
</head>
<body>
<img id="cat-gif" style="position:absolute;" src="http://www.anniemation.com/clip_art/images/cat-walk.gif">
<script src="main.js"></script>
</body>
Down here the function to make move the cat:-
var catWalk = function() {
var cat = document.getElementById("cat-gif");
cat.setAttribute('width', cat.width+10); //THIS WORKS
cat.setAttribute('marginLeft', cat.marginLeft+10); //THIS DOES NOT WORK!
}
//Call to the function
window.setInterval(catWalk, 500);

try using the following:
cat.style.marginLeft = (parseInt((cat.style.marginLeft) || parseInt(window.getComputedStyle(cat).marginLeft))) + 10 + 'px';
instead of cat.setAttribute('marginLeft', cat.marginLeft+10); there is no attribute marginLeft by default on your Element. So you gotta go by getting the computed styles and add it to your style attribute then you can access it.

Margin left is not a attribute hence it does not work in your case.
its a style property hence you need to do it differently
replace
cat.setAttribute('marginLeft', cat.marginLeft+10);
with
var p = cat.style.marginLeft; // return value in px; i.e 50px
p = p.substr(0,p.length-2); // remove px ie : 50px becomes 50
cat.style.marginLeft = (+p)+ 10 +'px' // convert p to number and add 10

Related

Move an <img> when button pressed

Here is my code that I am currently using for the function, I have made imgs move in the past using key codes but what I used a function to move it for me, the code looks like it should work there is probably just a silly error:
<!DOCTYPE html>
<html>
<head>
<title>Return To Alnerwick</title>
<style>
body
{
background-image: url("https://s-media-cache-ak0.pinimg.com/736x/e8/d6/fc/e8d6fc15671a05eeaf592f85c6dbb2db.jpg");
background-size: 1500px 1000px;
background-repeat: no-repeat;
}
img
{
position:absolute;
TOP:650px;
LEFT:750px;
width:100px;
height:100px
}
</style>
<script>
function move() {
var element = document.getElementById("char");
element.style.left = parseInt(element.style.left) - 90 + 'px';
}
</script>
</head>
<body>
<img id="char"src="/New Piskel (5).gif">
<button onclick="move();">move</button>
</body>
</html>
It's because you are using a stylesheet. When using a stylesheet, you have get the computed styles:
function move() {
var element = document.getElementById("char");
var style = window.getComputedStyle(element);
console.log("Current value: " + style.left);
element.style.left = (parseInt(style.left) - 90) + 'px';
}
See a working fiddle: https://jsfiddle.net/vgb7tc03/1/
Also getComputedStyle reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle
In your move function, you are referencing element.style.left. This is the element's inline style property. That inline style property is not defined in your markup at all.
You are defining the LEFT property in your css (not inline). What you will need to do is either reference the LEFT css property from your function, or set the left property inline in your element instead of in CSS.
Your problem is that element.style.left won't return its position. There are a couple of solutions:
1) You know that your image is already 750px from the left so you can just go
var img_left=750;
at the beginning of your script tag and then go
img_left=img_left-90;
element.style.left = img_left + "px";
in your function.
2) if you want to get the position of the element, you would go
element.getBoundingClientRect().left;
instead of element.style.left so the whole line would be
element.style.left=(element.getBoundingClientRect().left-90)+"px";

Javascript CSS DIV Float

I've been trying to create a small algorithm that adds a class attr to a specific element if the mouse reaches the X plain half of the browser or more.
I am also going to provide you with a screenshot where I need to use this kind of application.
http://tinypic.com/view.php?pic=2ur101d&s=8#.VVsOR0ai2Uk
As you can see in the image above, if the poster is too far on the right the div that appears on hover stretches out of the browser.
Thats why i need to add that class to move it a bit when the mouse reaches that distance on X.
Here's what i've tried so far but the if condition that I applied does not work.
<!DOCTYPE html>
<html>
<head>
<script>
function readMouseMove(e) {
var result_x = document.getElementById('x_result');
var result_y = document.getElementById('y_result');
result_x.innerHTML = e.clientX;
result_y.innerHTML = e.clientY;
var distance = window.innerWith;
var math = distance / 2;
if (e.clientX >= math) {
result_x.setAttribute('class', 'special');
}
}
document.onmousemove = readMouseMove;
</script>
<style>
.special {
color: red;
}
</style>
</head>
<body>
<h1>Document that reads mouse movement</h1>
<h2 id="x_result">0</h2>
<h2 id="y_result">0</h2>
</body>
</html>
I just refactored your condition, there was a spelling mistake:
if(e.clientX >= window.innerWidth / 2) {
result_x.setAttribute('class','special');
}

Javascript Styles not applying

I'm creating a Pure JS scroll to Top button. I'm writing a function to gather the window height and with, then write the appropriate margins to the scroll button, to keep it in a fixed position outside of the container(container is the 901 in marginx variable). However, when I load the page, the function isn't applying any of the margins to the "scroll" element, and I have no errors.
my code:
<head>
<script>
function displayScrollTop(){
var w=window,
d=document,
e=d.documentElement,
g=d.getElementsByTagName('body')[0],
x=w.innerWidth||e.clientWidth||g.clientWidth,
y=w.innerHeight||e.clientHeight||g.clientHeight;
var marginy = 60-y; //margin-top value
var marginx = "-" + (x-901)/2 - 60;
//image is floated right, this creates a negative margin left to pull to center.
The width of the window - 901 (width of the container)/2 to get the side
margins, - 60 (width of button)
document.getElementById('scroll').style.marginTop = marginy;
document.getElementById('scroll').style.marginLeft = marginx;
}
</script>
</head>
<body onload="displayScrollTop();">
<div id="scroll">
<a onclick="scrollToTop(500);"><img src="images/scrolltotopbutton.png" /></a>
</div>
<div id="container">
</div>
</body>
Any ideas?
You'll need to specify that the margin values are in px, by appending "px" to them.

how to perfectly overlap two (identical) elements?

Inside a position:relativeelement box, I have
a absolutely positioned element parent at top:0 with a couple of static p and h1..h6inside. Those may all have different margin/padding values.
a few absolutely positioned elements where element name and content matches exactly one of the elements from above list #1.
The goal is to set the y-value of the 2nd element such that it exactly overlaps with the corresponding one from the set in 1. .
I've taken this approach (using closure, but anything could be used really), starting with an Array of elements contentfor generating list #1:
goog.dom.removeChildren(parent);
for (var i=0; i<content.length; i++) {
offsets.push(parent.offsetHeight);
goog.dom.appendChild(parent, content[i]);
}
return offsets;
Then, using the values from offsets:
var matchedElm = source[i].cloneNode(true);
goog.style.setStyle(matchedElm, {"top": offsets[i] + "px"});
goog.dom.appendChild(box, matchedElm);
Now this works for various paddings and margin=0, but fails when margins are non-0 on the p and h1..6. I have also tried "scrollHeight" but nothing seems to take into account margins.
I've then tried getting offsetTop directly from the rendered elements in list #1, but this seems to yield exact same results as above procedure to fill offsets.
How can I make the overlap work? I'm looking for a native javascript or closure-library solution.
What you are looking for may be goog.style.getPageOffset and because your overlapping element is absolutely positioned with a top setting you may have to deduct the top margin of the element you want to overlap using goog.style.getMarginBox. Here is some sample code:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
</head>
<body>
<div id="game" data-something="hello"></div>
<script type="text/javascript" src="js/goog/base.js"></script>
<script type="text/javascript">
goog.require("goog.dom");
goog.require("goog.style");
</script>
</body>
<div id="contentToOverLap" style="position:absolute;top:30px;left:30px">
<h1 style="margin:10px;padding:2px">h1 10px mar and 2px pad</h1>
</div>
<div id="overlappingContent" style="display:inline">
<h1 style="color:red;margin:15px;padding:2px;position:absolute">
h1 15px mar and 2px pa
</h1>
</div>
<script type="text/javascript">
(function () {
var pH = goog.dom.$("contentToOverLap").children[0];
var cH = goog.dom.$("overlappingContent").children[0];
var box = goog.style.getPageOffset(pH);
console.log("box is:", box);
var mar = goog.style.getMarginBox(cH);
console.log("mar is:", mar);
var t = box.y - mar.top;
var l = box.x - mar.left;
goog.style.setStyle(cH, { "top": t + "px", "left": l + "px" });
})();
</script>
</html>

How can I Animate an Element to its natural height using jQuery [duplicate]

This question already has answers here:
Animate element to auto height with jQuery
(21 answers)
Closed 7 years ago.
I'm trying to get an element to animate to its "natural" height - i.e. the height it would be if it had height: auto;.
I've come up with this:
var currentHeight = $this.height();
$this.css('height', 'auto');
var height = $this.height();
$this.css('height', currentHeight + 'px');
$this.animate({'height': height});
Is there a better way to do this? It feels like a bit of a hack.
Edit:
Here's a complete script to play with for anyone that wants to test.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>jQuery</title>
<style type="text/css">
p { overflow: hidden; background-color: red; border: 1px solid black; }
.closed { height: 1px; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"></script>
<script type="text/javascript">
$().ready(function()
{
$('div').click(function()
{
$('p').each(function()
{
var $this = $(this);
if ($this.hasClass('closed'))
{
var currentHeight = $this.height();
$this.css('height', 'auto');
var height = $this.height();
$this.css('height', currentHeight + 'px');
$this.animate({'height': height});
}
else
{
$this.animate({'height': 1});
}
$this.toggleClass('closed');
});
});
});
</script>
</head>
<body>
<div>Click Me</div>
<p>Hello - I started open</p>
<p class="closed">Hello - I started closed</p>
</body>
</html>
I permit myself to answer this thread, even if it's been answered a long time ago, cuz it just helped me.
In fact, i don't understand the first answer : why opening a half-closed element to get its height, and then closing it again ?
At the beginning, you hide the element so that just a part of it appears, right ? The best way (i believe) to do this is onready, with javascript. So, when you hide the element onready, just save the orig height in a var, so you don't have to hide(onready)-show-save height-hide to be able to toggle the elements visibility.
Look at what i did, it works perfectly :
$(document).ready(function(){
var origHeight = $("#foo").css('height');
$("#foo").css({"height" : "80px"});
$("#foo .toggle").bind("click", function(event){ toggleFoo(event, lastSearchesMidHeight); });
});
Here, when you call your toggle function, you know what is your original element height without wanking around.
I wrote it fast, hoping it could help someone in the future.
the easiest solution I found was to simply wrap the content element with a div that is limited in height and set to overflow:hidden. This truncates the inner content element to the height of the wrapping div. when the user clicks, hovers, etc. to show the full height of the content element - simply animate the wrapping div to the height of the inner content div.
I could suggest an equally-hackish solution...Clone the element, position it out of view, and get its height...then delete it and animate your original.
That aside, you could also use $.slideUp() and $.slideDown():
$this.hasClass('closed') ? $(this).slideDown() : $(this).slideUp() ;
If you need to keep a 1px line, you can apply that with a parent element:
<div style='border-top:1px solid #333333'>
<div class='toggleMe'>Hello World</div>
</div>
And apply the slidingUp/Down on the .toggleMe div.
I'd also like to chime in on this old thread, if I may, in case my solution helps anyone. My specific situation is this: I have some div's that are set with a max-height value that limits them to three lines tall, and when the user mouseovers them I want them to expand to their natural height; and when the mouse cursor leaves the div, I want them to shrink back down to the clipped, max-three-lines-tall height. I need to use the CSS max-height property, rather than height, because I have some div's that contain only one or two lines of text and I don't want them unnecessarily tall.
I tried many of the solutions in this thread, and the one that worked for me was the 'hackish suggestion' involving cloned elements suggested by Jonathan Sampson. I translated his idea into the following code. Please feel free to suggest improvements.
The functions are delegated to a parent element to handle div's created via an Ajax call. The div.overflow_expandable class has the following declaration: { max-height: 5em; overflow: hidden; }
$('#results').delegate('div.overflow_expandable', 'mouseenter', function() {
var $this = $(this);
// Close any other open divs
$('#results div.overflow_expandable').not($(this)).trigger('mouseleave');
// We need to convert the div's current natural height (which is less than
// or equal to its CSS max-height) to be a defined CSS 'height' property,
// which can then animate; and we unset max-height so that it doesn't
// prevent the div from growing taller.
if (!$this.data('originalHeight')) {
$this.data('originalHeight', $this.height());
$this.data('originalMaxHeight', parseInt($this.css('max-height')));
$this.css({ 'max-height':'none',
height: $this.data('originalHeight') });
}
// Now slide out if the div is at its original height
// (i.e. in 'closed' state) and if its original height was equal to
// its original 'max-height' (so when closed, it had overflow clipped)
if ($this.height() == $this.data('originalHeight') &&
$this.data('originalMaxHeight') == $this.data('originalHeight')) {
// To figure out the new height, clone the original element and set
// its height to auto, then measure the cloned element's new height;
// then animate our div to that height
var $clone = $this.clone().css({ height: 'auto', position: 'absolute',
zIndex: '-9999', left: '-9999px', width: $this.width() })
.appendTo($this);
$this.animate({ height: $clone.height() }, 'slow');
$clone.detach();
}
}).delegate('div.overflow_expandable', 'mouseleave', function() {
var $this = $(this);
// If the div has 'originalHeight' defined (it's been opened before) and
// if it's current height is greater than 'originalHeight' (it's open
// now), slide it back to its original height
if ($this.data('originalHeight') &&
$this.height() > $this.data('originalHeight'))
$this.animate({ height: $this.data('originalHeight') }, 'slow');
});
Found this post and end up using Greg's original 1px suggestion - works great!
Just added a callback to the animate function, to set the height of the element to 'auto' when the animation ends (in my case, the content of that specific element could change and be bigger).
$('div').click(function() {
if($('p').is(':hidden')) {
$('p').slideUp();
} else {
$('p').slideDown(function() { $('p').css('height','1px'); });
}
}
That should set the height of the p tags to be 1px once they've finished sliding.
This worked for me.
<div class="product-category">
<div class="category-name">
Cars
</div>
<div class="category-products" style="display: none; overflow: hidden;">
<div class="product">Red Car</div>
<div class="product">Green Car</div>
<div class="product">Yellow Car</div>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
$('.product-category .category-name').click(function() {
if ($(this).parent().hasClass('active')) {
$(this).parent().removeClass('active');
var height = $(this).parent().find('.category-products').height();
$(this).parent().find('.category-products').animate({ height : '0px' }, 600, function() {
$(this).parent().find('.category-products').height(height).hide();
});
} else {
$(this).parent().addClass('active');
var height = $(this).parent().find('.category-products').height();
$(this).parent().find('.category-products').height(0).show().animate({ height : height + 'px' }, 600);
}
});
});
</script>
My solution is to store in the data attribute of the close button the original size of container (could have been stored also in the container itself, if you don't use the same button to also show again the container):
$(document).ready(function(){
$('.infoBox .closeBtn').toggle(hideBox, showBox);
});
function hideBox()
{
var parent = $(this).parent();
$(this).text('Show').data('originalHeight', parent.css('height'));
parent.animate({'height': 20});
return false;
}
function showBox()
{
var parent = $(this).parent();
$(this).text('Hide');
parent.animate({
'height': $(this).data('originalHeight')
});
return false;
}
I wanted to point to this answer, which suggest setting the height to "show" with the animate() function. I had to edit my "slideUp" style animate to use height:"hide" to work with it.

Categories

Resources