Set large value to div's height - javascript

I have a problem with height limitation of <div></div> in some web browsers, like Firefox. I have javascript code like this:
$('#MyDiv').css("height","20000000px"); // 20,000,000 pixel height
But I see height: 2e+7px; rule in the firebug. This problem exist in IE too, But in google chrome everything is ok and I see height: 20000000px;. How can I set very large value to div's height in a way that works for most browsers?
EDIT: firefox has no scrollbar in this div, but google chrome has scrollbar.

I want just confirm the problem which describes hamed. One can try the demo http://jsfiddle.net/OlegKi/y4tLxx53/4/ which contains setting height property using jQuery.css on the test div:
var testValues = [10000, 1533916, 1533917, 1533918, 10737418, 10737419,
17895696, 17895697, 17895698, 20000000], h, i;
for (i = 0; i < testValues.length; i++) {
h = testValues[i] + "px";
$("#test").css("height", h);
$("#log").append("<span>After setting height " + h +
", one have height: " + $("#test").css("height") +
"</span><br/>");
}
with very simple HTML markup
<div id="log"></div>
<div id="test"></div>
One can see in Google Chrome the expected results
but Firefox shows
and IE10 and IE11 displays
instead.
By the way, the setting of large height on divs will be used to implement "virtual scrolling" (for example in jqGrid). So that the user sees div with large scroll and a table inside. If the user uses scroll bar then the page of data will be downloaded from the server via Ajax. In the way the height of the div should corresponds to the size of data on the server. If one row of table data have height 23px, then IE10/IE11 can simulate in the simple way only 66692 rows of virtual data in IE (1533916/23=66692) and 778073 rows (less as a million rows) in Firefox. The demos shows that one need use more sophisticated implementation of "virtual scrolling" to have no, described above, problems with setting of height of div.
One can use the same inline demo alternatively:
var testValues = [10000, 1533916, 1533917, 1533918, 10737418, 10737419,
17895696, 17895697, 17895698, 20000000], h, i;
for (i = 0; i < testValues.length; i++) {
h = testValues[i] + "px";
$("#test").css("height", h);
$("#log").append("<span>After setting height " + h +
", one have height: " + $("#test").css("height") +
"</span><br/>");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<div id="log"></div>
<div id="test"></div>

I have run into the same issue implementing virtual scrolling. My solution is to detect numbers that are too large and use a multiplier.
This means that the height of the overflowed content will be realHeight / multiplier. And when I'm trying to figure out what data to show, I just take the scrollTop * multiplier. This works fine to the user because the scrollbar has a minimum height.
This will work if you have control over the effect. I'm not familiar with jqGrid, but the source code may have to be updated.

That's not a problem. The value 2e+7 is the same as 20000000, it's just a different way of showing the number.
In some tools, large numbers are shown in scientific notation. The number 2e+7 means 2 * 107.

If your document is size is not fixed, you can use this:
var height = $(document).height();
and set your div container height accordingly
$('#MyDiv').css("height",height);
This should work on all the browsers

Related

Javascript code broken in firefox browser only

I created a div C.
Its absolute position is setted to stay between the bottom margin of div A and top margin of div B.
Every div is a rectangle with same width.
C is a less hig than A and B. I use this solution in order do "hide" the seam between the two background image of A and B by covering the area where their margins meet one another. C has a backgorund image itself.
I manage these settings usign Javascript code insert in the right place of a WP theme Dashboard (Uncode theme, I didn't use Javascript pligin).
It's all right with all browser (I tried a LOT of browsers, mobile version too) but Firefox. I really can't understand why.
The code is:
var divTop = document.getElementsByClassName("A")[0].clientHeight;
var divWidth = document.getElementsByClassName("A")[0].clientWidth;
var Gap = document.getElementsByClassName("C")[0].clientHeight/2;
document.getElementsByClassName('C')[0].style.top=divTop-Gap + ".px";
document.getElementsByClassName('C')[0].style.width=divWidth + ".px";
U can verify by yourself: https://www.dolomitiinebike.it/
The website works well in every browser but opening it with firefox, everything is broken.
I solved installing a plug-in for adding Javascript and Jquery scripts (JS Inserter) and then I translate the code from Javascript to Jquery. I add the script infooter section.
This solution is compatible with Firefox too.
var topHeight = jQuery('A').outerHeight();
var width = jQuery('A').outerWidth();
var gap = jQuery('C').outerHeight()/2;
jQuery('C').css({ top : topHeight - gap + "px" });
jQuery('C').css({ width : width + "px" });

Is there any way to get the height of a single page if you would print the page as a pdf?

I'm trying to render a pdf from dynamic content with puppeteer and react. The layouting is done in material ui for react, so page-break-before:always is not an option because i need the grid layout which is flex and wont work with page-break-before. I need to get the height of one page, so the header of the next page doesn't overflow. If i calculate where the header should be with pagewidth * Math.sqrt(2), it gives me the position value of where it actually is. But unfortunally when i go to print it it's overflowing by a few pixels and the error is getting bigger with each page. I have wondered how to fix this problem for the last 2 days. I've even tried resetting the position with a margin.
Here are some code snippets from my program which might maybe help.
let width = 800//document.documentElement.getBoundingClientRect().width
for (let pagewidth = width; pagewidth * Math.sqrt(2) < document.documentElement.getBoundingClientRect().height; pagewidth += width) {
let pageBreakXPosition = Math.ceil(Math.sqrt(2) * pagewidth)
header.style.marginTop = pageBreakXPosition - header.getBoundingClientRect().top + "px"
}
this is just the "important" part of the code because all of the other code targets the elements' width or some other styles. My problem would really be fixed if i just knew the exact point where the page would break, but appareantly my calculation for pageBreakXPosition is wrong in some way.
attached is a picture of the overflow(if you look carefully you can see that the error is getting bigger):
Page 2
Page 4
I think you can set the height as per your requirement and that should work
Use these:
`- document.height()
document.body.scrollheight
screen.height
$(document).height()`

A very, very, very big div

For a project of mine (see BigPictu.re or bigpicture.js GitHub project), I have to deal with potentially a very, very, very big <div> container.
I knew there was a risk of poor performance with the simple approach I use, but I did not expect it to be mostly present with ... Chrome only!
If you test this small page (see code below), panning (click + drag) will be:
Normal / smooth on Firefox
Normal / smooth even on Internet Explorer
Very slow (nearly crashing) on Chrome!
Of course, I could add some code (in my project) to do that when you're zoomed in a lot, text with potentially very very big font-size would be hidden. But still, why does Firefox and Internet Explorer handle it correctly and not Chrome?
Is there a way in JavaScript, HTML, or CSS to tell the browser not to try to render the whole page (which is 10000 pixels wide here) for every action? (only render the current viewport!)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<style>
html, body {
overflow: hidden;
min-height: 100%; }
#container {
position: absolute;
min-height: 100%;
min-width: 100%; }
.text {
font-family: "Arial";
position: absolute;
}
</style>
</head>
<body>
<div id="container">
<div class="text" style="font-size: 600px; left:100px; top:100px">Small text</div>
<div class="text" style="font-size: 600000px; left:10000px; top:10000px">Very big text</div>
</div>
<script>
var container = document.getElementById('container'), dragging = false, previousmouse;
container.x = 0; container.y = 0;
window.onmousedown = function(e) { dragging = true; previousmouse = {x: e.pageX, y: e.pageY}; }
window.onmouseup = function() { dragging = false; }
window.ondragstart = function(e) { e.preventDefault(); }
window.onmousemove = function(e) {
if (dragging) {
container.x += e.pageX - previousmouse.x; container.y += e.pageY - previousmouse.y;
container.style.left = container.x + 'px'; container.style.top = container.y + 'px';
previousmouse = {x: e.pageX, y: e.pageY};
}
}
</script>
</body>
</html>
Changing to position: fixed seems to speed things up.
Use transform instead of top/left:
container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';
A live demo at jsFiddle.
Answer to first quest "why". One of problems are font size. you have font size 600000px, most browser will see it as too high and render smaller, while chrome tries to render original size. Looks like chrome can not repaint such big letters with your requested styles very fast.
But combining Teemu and geert3 answers - using transform and position:fixed, makes chrome works much more faster even with big fonts.
Answer to 2nd question: "Is there a way ... not to try to render the whole page" - you can try to apply mouse action for elements in container, not for whole container.
Maximum font sizes: http://jsfiddle.net/74w7yL0a/
firefox 34 - 2 000 px
chrome 39 - 1 000 000 px
safari 8 - 1 000 000 px
ie 8-11 - 1 431 700 px
In addition to Teemu's answer of using translate:
container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';
Which you should also use other vendor prefixes, You can simply fix this by using this on the body:
height: 100%;
width: 100%;
position: relative;
overflow: hidden;
and this on html:
height: 100%;
this will, however, disable scrolling. So what I'd do is, add a mousedown event to the body and apply those styles using a css class whenever mousedown is triggered, and removing that class on mouseup.
#Teemus' answer almost does it all.
Use transform with translate3d instead of top/left.
translate3d enables hardware acceleration.
container.style.transform = 'translate3d(' + container.x + 'px, ' + container.y + 'px, 0)';
A live demo at jsFiddle.
I analyzed this and I found that the original problem related to the Chrome display architecture, and its use of background threads to render the page.
If you want to have fast rendering, go into chrome:flags, scroll to the setting Impl-side painting, and set "Disabled", then restart the browser - the mousemove will be smooth.
What I found is that if you enable the FPS counter, the reported FPS in this scenario is still very high, even though the actual onscreen performance is very low. My tentative explanation (not being a Chrome display architecture expert) is that if the UI thread and display are on separate threads, then there can be contention in the rendering of the div - in the case where the UI thread and rendering thread is on the same thread, the UI thread cannot send messages faster than the UI thread can render.
I would suggest that this should be filed as a Chrome bug.
Use display: table and table-layout:fixed on the div, or a table wrapping the div. In HTML:
The HTML table model has been designed so that, with author assistance, user agents may render tables incrementally (i.e., as table rows arrive) rather than having to wait for all the data before beginning to render.
In order for a user agent to format a table in one pass, authors must tell the user agent:
The number of columns in the table. Please consult the section on calculating the number of columns in a table for details on how to supply this information.
The widths of these columns. Please consult the section on calculating the width of columns for details on how to supply this information.
More precisely, a user agent may render a table in a single pass when the column widths are specified using a combination of COLGROUP and COL elements. If any of the columns are specified in relative or percentage terms (see the section on calculating the width of columns), authors must also specify the width of the table itself.
For incremental display, the browser needs the number of columns and their widths. The default width of the table is the current window size (width="100%"). This can be altered by setting the width attribute of the TABLE element. By default, all columns have the same width, but you can specify column widths with one or more COL elements before the table data starts.
The remaining issue is the number of columns. Some people have suggested waiting until the first row of the table has been received, but this could take a long time if the cells have a lot of content. On the whole it makes more sense, when incremental display is desired, to get authors to explicitly specify the number of columns in the TABLE element.
Authors still need a way of telling user agents whether to use incremental display or to size the table automatically to fit the cell contents. In the two pass auto-sizing mode, the number of columns is determined by the first pass. In the incremental mode, the number of columns must be stated up front (with COL or COLGROUP elements).
and CSS:
17.5.2.1 Fixed table layout
With this (fast) algorithm, the horizontal layout of the table does not depend on the contents of the cells; it only depends on the table's width, the width of the columns, and borders or cell spacing.
The table's width may be specified explicitly with the 'width' property. A value of 'auto' (for both 'display: table' and 'display: inline-table') means use the automatic table layout algorithm. However, if the table is a block-level table ('display: table') in normal flow, a UA may (but does not have to) use the algorithm of 10.3.3 to compute a width and apply fixed table layout even if the specified width is 'auto'.
References
HTML 4: 11.2, Elements for constructing tables
HTML 4: Appendix B, Section 5.1.2: Incremental Display
HTML 5: Algorithm for Processing Rows
CSS2: 17.5.2 Table width algorithms, the 'table-layout' property
Draft U.S. Web Design Standards Documentation | Tables

offsetWidth returns wrong width in css animated block under Chrome

I'm trying to make a kind of "news bar" on a web page.
The bar use a CSS animation, and the text content is refreshed on each iteration using ajax to retrieve data from an RSS feed.
My problem is that the content length may vary, so I want to set the size of the font used to display the text small enough to display all the content.
I then use this function to resize the text content:
function resize(content /*content div*/, maxHeight/*bar height*/, maxWidth /*bar width*/) {
content.parentNode.style.fontSize = maxHeight + 'px';
var totalwidth = content.offsetWidth;
if (totalwidth > maxWidth) {
content.parentNode.style.fontSize = (maxHeight * maxWidth / totalwidth) + 'px';
}
}
It sometimes works on first iteration, but after it returns totally wrong values (like 36) for totalWidth.
If I put a breakpoint on the 'if' line the debugger display a coherent value (like 4320) for content.offsetWidth.
How can I fix this ?
I've found the solution.
I have to set the content as "inline-block".
If content display is set as "block" its offsetWidth vary with the css animation.

Javascript DOM offsetHeight issue on small screens

I have a simple code to set the height of one column, id="colLeft" to the height of another column, id="colRight", with no padding or borders:
<script type="text/javascript">
var colLeft = document.getElementById("colLeft");
var colRight = document.getElementById("colRight");
colLeft.style.height = colRight.offsetHeight + "px";
</script>
This code works fine on desktop and iPad, but on my android phone the results are rather unpredictable. Sometimes colLeft is much longer, sometimes colRight, and sometimes it works the way it should. I have tried it on two browsers with the same results.
I have also tried it inside window.onload=function(){...} which gave slightly less variance in the results, but is still not perfect.
Thanks for any help.
You can read a bit about offsetHeight here. The important thing to note is that if the content is larger than the viewable area the browser might do funny things with non-scrolling elements. Because this is a phone browser, I am guessing that the issue is that it is miscalculating the column height because it doesn't deal with scrolling elements correctly.
How do you set the height of the first column? If it has a valid height set in the style sheet you could easily do something like this:
colLeft.style.height = colRight.style.height;
If that doesn't work, you may need to set the column height based on the browser window size with something like:
colLeft.style.height = colRight.style.height = (window.innerHeight - 10) + "px";
Or something similar.

Categories

Resources