So I've got a table within a scrolling div. Right now, I resize the div every time the window is resized to allow the user to see as much of the table as possible.
function resizeTable() {
document.getElementById('table-container').style.height =
(window.innerHeight-60)+'px';
};
The only issue is that sometimes the table height becomes smaller than the encompassing div so I get some wasted space at the bottom. So what I would like to have is for the div to resize to the window height unless the height of the table is less than the window height. I've tried this...
function resizeTable() {
var tableContainer = document.getElementById('table-container');
var table = tableContainer.childNodes[0];
if (table.offsetHeight < (window.innerHeight-60))
{ tableContainer.style.height = table.offsetHeight; }
else
{ tableContainer.style.height = (window.innerHeight-60)+'px'; }
};
...but it doesn't work right and cuts off more and more of the table as the window is resized over time. So I come to you for help.
Try using style.maxHeight instead of style.height.
Related
In a web app I have a div with tooltips that are displayed only when hovering over certain objects of the page. These tooltips can overflow out of the div. When this happens, the scrollbars appear on the page as expected.
The issue is that the user cannot scroll with the mouse, because doing so moves the mouse out of the hovering element, so the tooltip disappear, and the window resizes down to the original size (so the scrollbars disappear too).
Here is a mock example of a similar behaviour :
I tried to use scrollIntoView for putting the object into the view, but again this works for a fraction of seconds, as the automatic scrolling of the page to put the element into view moves the mouse out of the hovering element and causes the tooltip to disappear.
Is there a way to always keep the biggest frame size ? This way the user can scroll into the right view before hovering over the elements so that they are displayed entirely.
Got it working by using ResizeObserver.
I defined this function in the source of the web app :
parent.set_size = function(height, width) {
const iframe = document.getElementById('your-iframe');
iframe.style.height = height + "px";
iframe.style.width = width + "px";
}
and then in the page loaded in the iframe I defined something similar to :
$(document).ready(function() {
// set the div which has a dynamic size depending on whether or not the tooltip are displayed
var map_div = document.getElementById("map")
// set the initial size
parent.set_size(map_div.scrollHeight, map_div.scrollWidth);
var max_height = map_div.scrollHeight;
var max_width = map_div.scrollWidth;
// when the size changes, keep the biggest size
var ro = new ResizeObserver(entries => {
for (let entry of entries) {
max_width = Math.max(entry.target.scrollWidth, max_width);
max_height = Math.max(entry.target.scrollHeight, max_height);
parent.set_size(max_height, max_width);
}
});
ro.observe(map_div);
});
This way the iframe always keep the biggest size it get to, which allows scrolling to the correct position before displaying the tooltip.
I have a table sorter html page, the sample is here.
$('table').tablesorter({
theme: 'blue',
widgets: ['zebra', 'scroller'],
widgetOptions: {
scroller_height: 400
}
});
How can I make the bottom button visible even when the windows height is very small (say, can only show one or two rows)? Ideally scroller_height can be some type like $(window).height()/2 and it can automatically update when the window is resized.
The expected is that even when the window is small, the bottom button appears in the screen without scroll action.
If you want to make the scroller window dynamically adjust its height, there are two demos on the main wiki page under Widgets > Scroller.
http://jsfiddle.net/Mottie/txLp4xuk/2/
http://jsfiddle.net/Mottie/abkNM/8037/
Essentially, all you need to do is adjust the outer scroll window height
$('.tablesorter-scroller-table').css({
height: '',
'max-height': height + 'px'
});
Here is the demo you shared updated, and has a minimum height set to 100px.
I'd say that there are a few ways to achieve what you want, and one easy way is to:
create a function that checks the visibility of your table versus the viewport;
Code below:
function checkVisible() {
var bottom_of_table = $("#mytable").offset().top + $("#mytable").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).height();
if(bottom_of_screen > bottom_of_table){
$("#buttons-container").removeClass('bottom-fixed');
}
else {
$("#buttons-container").addClass('bottom-fixed');
}
}
If it exceeds the viewport, add a CSS class to your buttons container that fixes it to the bottom of the screen. Otherwise, remove this class and display the button container normally, at the bottom of the table.
You'd want to run this function-check on load and on window resize, as follows:
$(document).ready(function() {
checkVisible();
$(window).on('resize', checkVisible);
});
I've updated your fiddle: http://jsfiddle.net/12nt19vg/12/show/
Try resizing the window and let me know if this is the behavior you're looking for.
EDIT: Incorporating your additional spec in the comments, I've added an outer div to your buttons container and modified your CSS to visually create the effect that I think you're looking for.
Please take a look at this fiddle: http://jsfiddle.net/12nt19vg/27/show/
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
I am currently implementing a tool for a project, and I am having some difficulties to remove some extra space at the bottom of the main container.
Basically, the container that contains the drawings-list and the map, resizes itself on window resize event. The bottom bar is fixed, so it does not affect anything.
$(window).on('resize', function () {
resize();
});
function resize() {
var height = $(window).height();
var width = $(window).width();
var mapHeight = height-260; // 260 for fixed elements
var mapWidth = width-360; // 360 for left hand side list
$('.map-drawings-container ul').height(mapHeight);
$('#map_parent_container > .map').height(mapHeight);
$('.drawings-list').height(mapHeight);
}
When the page is first loaded, it renders properly. Then when shrinking it, we can see a space that seems to be equal to the difference between the original page height and the current one.
Changing the size of the html and body element does NOT fix the issue.
Using the Google Chrome Dev tool, I am not able to select that grey background.
Changing margin-bottom to a negative value on the main container does not remove that space either.
Any clue on how to get this space removed?
Thanks
Sure you don't have an element inside that extends beyond the body with a min-height set on it. This would push the sticky footer down when the body shrinks below that min-height creating the extra space?
Look for all elements with a min-height and try shrinking them.
When the page is first loaded, it renders properly. Then when
shrinking it, we can see a space that seems to be equal to the
difference between the original page height and the current one.
May problem is: resizing the page so try that:
$(window).resize(function(){
var height = $(window).height();
var width = $(window).width();
var mapHeight = height-260; // 260 for fixed elements
var mapWidth = width-360; // 360 for left hand side list
$('.map-drawings-container ul').height(mapHeight);
$('#map_parent_container > .map').height(mapHeight);
$('.drawings-list').height(mapHeight);
});
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.