Here's what I would like to see on my website. A table with the width of the body, and three columns: 20%, 70%, 10%. As the browser window resizes, so does the table, and so do the columns of the table change their respective width.
The left column (the 20% width one) contains a DIV element, and that contains some text:
<body style="width:100%;">
<table style="width:100%;">
<tr>
<td style="width:20%">
<div style="position:relative;">
Here goes some text. This is a lot of text and usually should wrap around inside of the DIV element.
</div>
...
</tr>
</table>
</body>
This all works just fine, wrapping and all. Now when the user scrolls the page down, the DIV element and its content scrolls up and out of the window.
What I want to do is to "fix" the DIV to the top of the browser before it leaves the visible area. When the user scrolls up again, the DIV should detach from the top of the browser and resume its normal position. The end effect is that the DIV either scrolls around inside of the visible area, or attach to the top of the browser otherwise. This is implemented with a simple Javascript callback that I attached to the onscroll event, which changes the position between fixed and relative. Works fine too.
Now the only thing that I noticed is that the width of the DIV changes! It is equal to the width of the parent TD as long as it scrolls along and as long as the DIV's position is relative. The moment the Javascript callback changes the position to fixed the width of the DIV changes and overflows into the neighboring table column.
How can I contain the dimensions of the DIV?
Thanks :)
Thanks #abelito for the hint :) Turns out that the solution is a little easier than this. I do need to change the width of the DIV element when I change its position, but since the TD has a 20% width, all I have to do is to toggle the width of the DIV between 20% and 100% depending on its position value. Here is the Javascript which works:
var div_is_sticky = false;
window.onscroll = function() {
var y = window.scrollY;
if (y >= 250) {
if (div_is_sticky) {
// Do nothing.
}
else {
var div = document.getElementById("submenudiv");
div.style.position = "fixed";
div.style.width = "20%";
div_is_sticky = true;
}
}
else if (y < 250) {
if (div_is_sticky) {
var div = document.getElementById("submenudiv");
div.style.position = "relative";
div.style.width = "100%";
div_is_sticky = false;
}
else {
// Do nothing.
}
}
}
Thanks!
Sounds like you're also going to have to take control of the width of the DIV once the position is changed to fixed. If you're using raw javascript, try changing the element.style.width to the parent's element.offsetWidth + 'px'. If you're using jquery, you should use the .width() method. Links:
https://developer.mozilla.org/en-US/docs/DOM/element.offsetWidth
http://api.jquery.com/width/
Don't forget to revert the width back to '100%' if the user scrolls back down.
Related
Heyo,
so I was wondering if it is possible to show the fade-effect of a div, if it is 20% away from the bottom within the currend screen view. So for example if you scroll down on a page and the following contentbox gets a distance of 20% of the screen-height to the bottom of the screen, the fade-in effect runs.
I want this because of the responsive function. I don't want to write a new pixel height for the fade-effect everytime the Screensize changes.
Here's the code I'm currently using:
function Scroll(){
var top = document.getElementById('div1');
var ypos = window.pageYOffset;
if (ypos > 1000){
top.style.opacity = "1";
}
else {
top.style.opacity = "0";
}
}
window.addEventListener("scroll",Scroll);
Have you looked into scroll combined with position and height? https://api.jquery.com/scroll/ and https://api.jquery.com/position/ On the scroll you could get the position of the element in question and compare to the window. http://api.jquery.com/height/ and How to get the 'height' of the screen using jquery Those should be all the tools you need.
I have a div with id "page-content", it does not have height or width, it just have a blank div.
I'm filling that div with content dynamically, so the div height is growing constantly, I'm making a chat, and i want to detect if I am at the bottom of the div or in the last 10% of the div total height, If true, scroll to the bottom
var box = $('#page-content');
if (box.scrollTop() > (box.height*0.90))
box.scrollTop(25000); // This is the top bottom
What I'm trying to do is, check if you are in the last 10% or less top bottom height of "#page-content" div (not when I'm reading "old messages" at the beginning of the Div), I have a function that appends new messages but I need to scroll down manually to see new messages...so i want to automatically scroll to the New bottom so i can see the new message :)
UPDATE:
function getChat() {
$.ajax({
type: "GET",
url: "refresh.php?lastTimeID=" + lastTimeID
}).done( function( data )
{
var jsonData = JSON.parse(data);
var jsonLength = jsonData.results.length;
var html = "";
for (var i = 0; i < jsonLength; i++) {
var result = jsonData.results[i];
html += '<span class="color-'+result.color+'"><b>'+result.usrname+'</b></span> <i class="fa fa-angle-right"></i> '+result.chattext+'<br>';
lastTimeID = result.id;
}
$('#page-content').append(html);
if(html!="")
{
// Here i need to check if the scroll position is in the bottom or in the last 10%
//then this to scroll to the top bottom (25000 is height limit)
$('.page-content').scrollTop(25000);
}
}); }
The trick is that inside the container for your messages (in your case the #page-content DIV), you can have an invisible placeholder div with some id set on to it.
In this demo JSFiddle, as you click on the anchor .addItem, after the new item is added to the container, the placeholder div is moved to the end of the container. This ensures at the same time that clicking on the .addItem brings the bottom of the container DIV into view (as it refers the id of the placeholder in its href attribute).
function scrollToBottom(container) {
// get all the child elements of the container
var children = container.children('.item');
// move the placeholder to the end of the container
$('#contentBottom').insertAfter(children.eq(children.length - 1));
}
Update
In order to determine your current scroll position, you should listen to scroll events in the container. Meanwhile, you should take into account the updated height value of the container when new messages arrive.
Check out this updated fiddle in which I'm checking if the current scroll position is beyond 60 % from the top to easily see the effect.
Note: If a new message comes when you are not scrolling, you can simply do $('.container').scrollTop(25000) in the same function/block of code that appends it to the container.
there is a trick in scrolling the page to bottom of DIV, i tried implementing it in this fiddle.
See $(window).height()+$(window).scrollTop() will always be equal to the total height(including paddings,margins) of children of the window, in our case it is equal to the $('#page-content').height()+margin/padding.
CSS:
div#page-content {
height:600px;
border:solid 1px red;
}
in our situation:
$(window).height()+$(window).scrollTop()=$('#page-content').height()+(margin/padding)=600px
so whenever we scroll it, we can attach an scroll() event to the div and easily check whether we are in in the last 10% or less top bottom height of "#page-content"
$(window).on('scroll',function(){
if($(window).height()+$(window).scrollTop()>=($('#page-content').height()*(.9))){
$(window).scrollTop($('#page-content').height()-$(window).height())
}
})
Good luck.
Since I did not make this, I don't want to take credit for it.
There is a jQuery plugin that makes anything that has a scroll bar scroll to a specific location or to an element. Since you want to scroll to a dynamic div, you can call this after you created the div and it will scroll to that location.
You can find the plugin over here.
You can find a demo of the plugin in action over here.
Hope this was what you are looking for.
-W
https://rebecca-milazzo-test.squarespace.com/featured#/btr/
I have the page meta-data set to fixed positioning, but as the users scroll, the div doesn't stop and scrolls under the thumbnails at the bottom of the page. I have researched other scripts, but they all are created to stop the div at a certain pixel height and not another element.
Any help is greatly appreciated.
You're going to want to create a function that checks the windows scroll position to see whether you've scrolled to the thumbnails section. When you've scrolled to the thumbnails section, set the fixed elements position to absolute and set its top to the windows scroll position plus the original top value. For those like myself who thought z-index would suffice, OP doesn't want the element to go either underneath the thumbnails section or above the thumbnails section on scroll.
function checkposition(){
fixedelement = document.querySelector(".project-meta");
stopelement = document.querySelector("#project-thumbs");
stoppoint = stopelement.scrollTop - fixedelement.clientHeight - parseInt(fixedelement.style.top);
if (window.scrollY >= stoppoint){
fixedelement.style.position = "absolute";
fixedelement.style.top = [defaulttophere] + window.scrollY + "px";
} else {
fixedelement.style.position = "fixed";
fixedelement.style.top = [defaulttophere];
}
}
window.addEventListener("scroll", checkposition);
Let me know if this works or not, I threw this together pretty quickly.
Please check: http://wixwebsite.seobrasov.com for reference.
My goal here is to achieve a body/wrapper div height according to the content instead of having a scrollbar for a 3500px height body on a 500px content.
I have a one page design with divs sliding in and out. There is a wrapper with overflow hidden and position relative that contains all the divs. Inside that, there are the divs having position absolute and height auto. Inside each div there are the content divs with height aut as well and they correctly expand to fit their content. It is all connected to a javascript that does the sliding. The whole thing only works if I set a fixed height to the wrapper div. Otherwise, having height auto on the wrapper or using javascript to set the wrapper div to the inner div height (which is height auto as well) makes the page not to expand & show any content AT ALL.
The first thing you would think about would be that the wrapper div does not expand height due to position absolute of the inner divs. That is only part of the problem. If I do indeed change the position to relative, it will only show part of the divs.
I have tried using javascript to set the wrapper div to take position from inner divs, but those inner divs also have height auto. And I cannot do the javascript on the content divs as there are more using the same class and having different heights, as they expand depending on content.
So the question that follows is:
Even if I achieve the wrapper div to expand height to its containing divs, wouldn't that height be the height of the biggest div? Since they are all on the same page?
Here is some code:
<div class="content-wrap">
<div class="dhome">
content
</div>
<div class="dabout">
content
</div>
etc.
.content-wrap{
overflow:hidden;
position:relative;
clear:both;
height: 3500px -> aiming for auto
}
.dhome,.dabout{
position:absolute;
right:-200%;
height:auto;
}
So far the only solution I'm seeing to this would be to place the content on different pages but I don't think that I'll manage to do the sliding.
Thanks in advance,
So I got this Javascript that does the animation:
function animate() {
var currentPageI = -1;
var pages = [
$('div.dhome'),
$('div.dabout'),
];
var viewsWidth = 1300;
var showPage = function(index){
if(index === currentPageI){return;}
var currentPage = pages[currentPageI];
if(currentPage){
currentPage.stop().animate({left: -viewsWidth})
}
var nextPage = pages[index];
nextPage
.stop()
.css({left: viewsWidth + Math.max(0,(($(window).width() - 980)/2))})
.animate({left: Math.max(0,(($(window).width() - 980)/2))})
currentPageI = index;
};
showPage(-1);
$('a.dhome').click(showPage.bind(null, 0));
$('a.dabout').click(showPage.bind(null, 1));
$(document).ready(function () {
animate();
});
First of all I have added the suggested Javascript at the end of this one and didn't do anything...after that I have added it into the animation script and used nextPage instead of the wrapper childNodes, and it still didn't do the trick. I will further look into this.
Thank you!
set an ID on the div with class="content-wrap"
var wrapper=document.getElementById(IDcontentwrap);
var childNode, childNodes=wrapper.childNodes, i, l=childNodes.length;
var maxWidth=0, maxHeight=0;
for (i=0;i<l;i++)
{
childNode=childNodes[i];
if (childNode.nodeType==1)
{
if (maxWidth<childNode.offsetWidth) maxWidth=childNode.offsetWidth;
if (maxHeight<childNode.offsetHeight) maxHeight=childNode.offsetHeight;
}
}
wrapper.style.width=maxWidth+"px";
wrapper.style.height=maxHeight+"px";
How can I assign absolute left 0px OR absolute right 0px depending on if the absolute positioned div will go outside of its container div.
I guess an easy example of what I mean is: right click in your browser, see it has that menu position to the right of where you click, well not go all the way to the right of the page, instead of going outside of the page, it stays inside of it so it's still visible.
example: (Hover over boxes)
http://jsfiddle.net/ueSNQ/1/
It sounds like you'll need to use script to work the "depending on if the absolute positioned div will go outside of its container div" bit, IE supports css expressions but you're probably after a cross browser solution.
that said it should be a simple matter of something like this
function isOverflow(parent, child){
var left = 0;
var op = child;
while(op && op != parent){
left += op.offsetLeft;
op = op.offsetParent;
}
return ((left + child.offsetWidth) > parent.offsetWidth);
}
function getHoverHandler(parent, child){
return function(){
if(isOverflow(parent, child)){
child.style.marginLeft = 'auto';
child.style.right = '0px';
child.style.left = '';
}
}
}
function attach(o,e,f){
if(o.addEventListener){
o.addEventListener(e, f, false);
}else if(o.attachEvent){
o.attachEvent('on'+e,f);
}
}
var yellowElement = document.getElementsByTagName('UL')[0];
var list= document.getElementsByTagName('LI');
for(var i = 0; i < list.length; i++){
var element = list[i];
var tip = element.getElementsByTagName('DIV')[0];
attach(element, 'mouseover', getHoverHandler(yellowElement,tip));
}
Well Friend,
Try the following steps
1. You have a container div and on right clicking on it you will need to display a div for example say div with list of menus.
2. Have the left position of the container div in a variable **contLeft** and width of the container in another variable **contWidth**
3. Assign the oncontextmenu event handler on the container div.
4. In the event handler function take the mouse x postion in a variable **mosX** and mouse y position in a variable **mosY** and you have to fix the top position of the div to be displayed as mosY and the left as mosX.
5. In order to maintain the div within the container you have to calculate the container's screen occupation as **totPos = (contLeft + contWidth)**
6. Calculate the screen occupation of the menu div as **posMenu = (mosX + width of the div)**
7. If the totPos greater than or equal to posMenu display the menu in the same top and left postion using the values of mosY and mosX
8. Else place the menu in position top = mosY and left = (mosX - width of menu div)
Hope this would solve your problem.
Well first of all if the container div has a position set than position: absolute, right: 0px or left: 0px will be positioned relatively to the container's position. Else it will be positioned to the first parentNode going up the tree from the desired div which has a position, if none is found it will be relative to the body. So you can search the first parent or grandparent container that has a position set. The question is hard to understand so if you would like to share some examples we would be glad to help.
EDIT:
In the example you posted it is exactley like in my comment, calculate the offsethWidth of the parent and the offsetWidth + left to not be overflowing if it is decrease the left or just remove left and set the right positioning. For the same effect on width and height you have to make some cases for the corners.