I am using this code:
$('.my_img').mousemove(function(e){
$('.mycls').css("left",e.pageX-20+"px");
$('.mycls').css("top",e.pageY-10+"px");
});
then...
<div class="mycls">I Move</div>
then...
<img class="my_img" src="myimg.png" />
My problem is that if I add any div's above these divs the position changes and mycls is no longer at mouse position.
So if I was to add to extra div's after the body like this:
<div>ONE</div>
<div>TWO</div>
...then the rest of the code...I will lose the position :o/
Any ideas on how to sort this?
Since e.pageX and e.pageY values are relative to the entire page, your code shouldn't be affected by adding new elements. If you set top and left to an element, it defines its distance from the top and left of the page.
The only case where it could be problematic is if you have position:relative set on any parent elements of the mycls div. Remove that position:relative, so that top and left refer to the entire page and not the parent element.
simply add a CSS position:absolute; to your movable element .mycls
var img = document.getElementById("my_img");
var cls = document.getElementById("mycls");
img.onmousemove = function(e){
cls.style.left = e.clientX-20 + "px";
cls.style.top = e.clientY-10 + "px";
};
#mycls {
background-color: rgba(255,255,255,0.8);
position: fixed;
left: 0;
top: 0;
font-family: sans-serif;
padding: 10px;
border-radius: 5px;
border: 1px solid rgba(0,0,0,0.8);
}
#my_img {
width: 420px;
height: 200px;
background-color: #333; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="my_img">
<div id="mycls">
Your message here
</div>
</div>
Here's an example of how I have done this in the past ... importantly
the div that is moving is a child of the container so that a any mousemove events it triggers are bubbled to the parent for handling
Related
I am trying to make a JavaScript game and I need a CSS object with an animation to move in place of an object I originally made using JavaScript. Basically, what I want to happen is have my "sword" CSS object move with my player object when I have it Unsheathed. I have been looking for a while and they only give me a result as to were it will be when the page is loaded. I need the sword to always be moving with the player. If my code is needed, tell me, and I will provide it. If you have any questions, feel free to ask. I am pretty new so go easy on the terrible JavaScript that may be provided.
PLEASE USE AN EXAMPLE RELATED TO MY CODE!
if you don't I probably wont understand what is going on....
Thank You in Advance
Focusing the the following element of your example I am only going to address CSS here...
....
<div class="player"></div>
<div id="swordl"></div>
<div id="swordr"></div>
....
To move #swordl and #swordr along with .player you can take advantage of a feature of the CSS position attribute.
When a containing element has CSS position: relative; children of that element with the CSS position: absolute; are positioned with reference to the top-left corner of the parent.
In the following example #player would be the parent, and #swordl and #swordr would be the children...
....
<div id="player">
<div id="swordl"></div>
<div id="swordr"></div>
</div>
....
/* CSS */
#player {
position: relative;
}
#swordl, #swordr {
position: absolute;
}
#swordl {
left: 4px;
top: 2px;
}
#swordr {
left: 12px;
top: 2px;
}
Note the change of class to id in 'player'
Now, whenever you animate the position of #player the two #swords will maintain their position relative to the top-left corner of their containing parent element: you will not have to animate the position of #swords explicitly.
Hope that helps. ;)
CSS position # MDN
You can use the transistion. I have included a couple examples. One example is just JavaScript, the other is not just JavaScript.
//Get Element By Id of 'movingdiv'
var div = document.getElementById('movingdiv');
//Create the timeout (not required)
setTimeout(function() {
//Change the style.top to 50%, You can also do this in px
div.style.top = '50%';
//Change the style.top to 50%, You can also do this in px
div.style.left = '50%';
//Add the transform so it can be centered in the viewport
div.style.transform = 'translate(-50%,-50%)';
//Add the timeout below in milliseconds.
}, 1000)
#movingdiv {
width: 100px;
height: 100px;
background: black;
position: absolute;
top: 10px;
left: 10px;
transition: all 2s;
}
<div id='movingdiv'></div>
//Create a div
var div = document.createElement('div');
//Give the div some style. IMPORTANT: notice the transition
div.style = 'width: 100px; height: 100px; background: black; position: absolute; top: 10px; left: 10px; transition: all 2s;';
//Append the div to the body
document.body.appendChild(div);
//Create a timeout for the div to move
setTimeout(function() {
//Change the style.top to 50%, You can also do this in px
div.style.top = '50%';
//Change the style.top to 50%, You can also do this in px
div.style.left = '50%';
//Add the transform so it can be centered in the viewport
div.style.transform = 'translate(-50%,-50%)';
//Add the timeout below in milliseconds.
}, 1000)
I have a html element which is displayed when a button is clicked. It‘s kinda like a popup. I want to check if it’s in the ViewPort of the browser and then place it inside the ViewPort . Is there a right way to achieve that?
At the moment I’m checking the height of the ViewPort and compare it to the point where the element will be attached to. So I do something like this:
If(window.innerHeight > yPointWhereElementIsAttachedTo + heightOfElement) //attach element;
But what is the right way to do it?
This can be achieved by using position: fixed; on an element with positioning.
For example:
.fixed {
position: fixed;
width: 300px;
height: 100px;
background: red;
left: 10px;
top: 40px;
}
.wrapper {
min-height: 4000px;
}
<div class="wrapper">
<div class="fixed">
I am fixed in the viewport
</div>
</div>
You could use scrollIntoView() if a more dynamic approach is required.
var elmnt = document.getElementById("content");
elmnt.scrollIntoView();
https://www.w3schools.com/jsref/met_element_scrollintoview.asp
I have HTML like this:
<div class="cont">
<!-- some elements -->
<div class="child fixed">Child</div>
</div>
child is with position fixed (class fixed). Inside cont there are another elements, which make it with higher height than child.
I have scroll event on document:
$(document).scroll(function(e) { ... }
I want when some1 scroll and child is at the bottom of cont to remove fixed class.
How can I detect on scroll (document scroll) that some element is at the bottom of some parent element (I mean when bottom of the child is in the same position as its parent cont.) ?
Edit
#devlincarnate this is not "how to check is it last child" question.
Sometimes you just don't need JS. This is what I'd do, using CSS position: sticky - if I got your question (and problem) right...
* { margin: 0;box-sizing: border-box; }
body { border: 10px dashed #000; }
#footer { background: #0fb; height: 150vh;}
#cont { background: #0bf; height: 200vh;}
#child { background: #f0b; height: 20vh;
position: sticky;
top: 0;
}
<div id="cont">
<div id="child">CHILD FIXED.... and magical</div>
CONTENT...
</div>
<div id="footer">FOOTER</div>
el.scrollIntoViewIfNeeded() scrolls to el if it's not inside of the visible browser area. In general it works fine but I'm having problems with using it with a fixed header.
I made an example snippet: (The method doesn't work in Firefox, so neither does the demo) https://jsfiddle.net/ahugp8bq/1/
In the beginning all three colored divs are displayed below the fixed header. But if you click "second" and then "first", the beginning of #first will be behind the header, which I don't want.
The problem seems to be that the position of #otherContainer (its padding-top) is pretty much ignored when scrolling up.
Actually, this is quite simple if you use the consistent and supported getBoundingClientRect().top + body.scrollTop way - all you now have to do is reduce the header from it, so just get it and calculate its height.
var header = document.getElementById('container')
var clicks = document.querySelectorAll('#container li');
var content = document.querySelectorAll('#otherContainer > div');
// Turn the clicks HTML NodeList into an array so we can easily foreach
Array.prototype.slice.call(clicks).forEach(function(element, index){
element.addEventListener('click', function(e){
e.preventDefault();
// Set the scroll to the top of the element (top + scroll) minus the headers height
document.body.scrollTop = content[index].getBoundingClientRect().top + document.body.scrollTop - header.clientHeight;
});
});
#container {
position: fixed;
background: yellow;
width: 100%;
height: 50px;
}
ul li {
display: inline;
cursor: pointer;
}
#otherContainer {
padding-top: 60px
}
#first, #second, #third {
height: 500px
}
#first {
background: red
}
#second {
background: green
}
#third {
background: blue
}
<div id="container">
<ul>
<li id="jumpToFirst">first</li>
<li id="jumpToSecond">second</li>
<li id="jumpToThird">third</li>
</ul>
</div>
<div id="otherContainer">
<div id="first"></div>
<div id="second"></div>
<div id="third"></div>
</div>
I have a .wall div with a some .toy divs inside it. I want to arrange the toys inside the wall. float:left property has done it for me nicely.
Now the problem is I want to add position:absolute for the toy divs to make it draggable later. How can I do this either via Javascript or via CSS?
Applying position:absolute, all toys will come to the top left corner of the wall overlying and hiding each other.
The width and height of the wall is constant but the width and height of the toys is variable, also the number of toy divs is dynamic and as the number increases toys need to arrange as rows.
Any suggessions will be helpful, please note the I can not avoid the use of position:absolute for dragging.
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<style>
body{
text-align:center;
}
.clearfix{
clear:both;
}
.wall {
border: 5px solid #cde;
margin:auto;
width:200px;
padding:10px;
}
.toy{
background-color: #BBCCEE;
border:1px solid #8899BB;
margin:5px;
width: auto;
padding:5px;
float:left;
}
.tall{
padding-top:10px;
}
</style>
<script>
$(document).ready(function() {
$('.toy').each(function(index) {
var position = $(this).offset();
var prevPosition = $(this).prev().offset();
$(this).css({
//top: position.top,
//left:position.left,
//position:'absolute',
});
});
});
</script>
<div class='wall'>
<div class='toy'>T1</div>
<div class='toy'>T2</div>
<div class='toy'>T3333333</div>
<div class='toy'>T4</div>
<div class='toy'>T5</div>
<div class='toy tall'>T6</div>
<div class='toy'>T7</div>
<div class='toy'>T8</div>
<div class='clearfix'></div>
</div>
Here is the code at JSBin.
Add
position:relative
To the wall div
I am working on a website that does exactly that (sorry for the non-english stuff):
http://moveit.canassa.com/cartao/4/
The link is now broken but here is a jsFiddle that shows what I am talking about:
http://jsfiddle.net/canassa/Z9N3L/
The "toy" div is using a position absolute:
.toy{
width: 100px;
height: 25px;
position: absolute;
z-index: 0;
}
The problem with the position absolute is that the toy will be relative to page and not the "wall" container, in order to fix that you must make the wall container relative:
#wall{
position: relative;
overflow: hidden;
}
The overflow:hidden is also a nice trick that I found. It makes the draggable objects go "under" the wall container.
There is no big secret to make it draggable, using jQuery:
// Creates a toy div inside the wall
$(MV.wallId).append('<div class="toy" id="' + this.getId() + '"></div>');
box = this.getBox(); // return the "toy" that I've just created.
$('#' + this.getId()).draggable(); // make it draggable
This would be a lot easier if you just used the jQueryUI .draggable(). It doesn't require the elements to be positioned.
If you're dead set on using this plugin, then you have the right idea. Let the elements flow into place and then calculate their position and set position: absolute and whatever the left and top end up being at runtime.
Set the .wall to be position: relative. Then:
var tPos;
$('.toy').each(function(index) {
tPos = $(this).position();
$(this).css({
left: tPos.left,
top: tPos.top
});
};
$('.toy').css({
position: absolute
});
The height of the .wall and the width of each .toy collapse when the toys are absolutely positioned but you can just add a few more lines to get/set their width and height in the above .each loops.
This obviously doesn't work if new toys can be added dynamically without a page reload as you suggest. To handle that you could switch them back to position: relative, add the new one, get the position of the new one in the flow, then set the position and switch back to position: absolute. Any elements that had been dragged out of place would be gaps in the flow, but I don't see any easy way around that.
the element in that the absolute should be positioned, must have the style position:relative.
(must be a parent of the target element)
The container div for every .toy must have position:relative set. That way, the position 0 for its children elements becomes its top left corner. Like this:
<div class="parent">
<div class="child">Blah.</div>
<div class="child">Blah.</div>
</div>
And:
.parent {
position: relative;
}
.child {
position: absolute;
left: 10px; /* This is 10 pixels from the parents left side */
top: 10px; /* This is 10 pixels from the parents top side */
}
Good luck.