I am a newb to JavaScript, but am trying to learn. For that reason I would like to try and accomplish this without resorting to jQuery.
I am trying to load a page where the content is dynamically re-sized based on the height and width of the browser. I presently have two iterations of the code, one with an image in the content div and another, much simpler, without.
Firstly, addressing the one without the image. Calling winSizefrom an onload event in the body tag or inside the script tag at the bottom of the HTML seems to be able to determine the scrollHeight/Width prior to setting the style, but fills the entire window with the black of the content div rather than setting its width to 704px as the script has determined it should be. Using the document.body.onload in the script header to call winSize resulted in a null scrollWidth/Height and only displays the grey background.
The code for that is as as follows:
<style>
body {
padding:0px;
background-color: #808080;
}
div {
position:absolute;
}
</style>
<script type="text/javascript">
bArat=3/2;
bH1=0;
bW1=0;
bX1=0;
bY1=0;
function winSize(){
winW=document.body.scrollWidth;
winH=document.body.scrollHeight;
_style();
}
function _style(){
bH1=winH;
bW1=bH1/bArat;
bX1=(winW/2)-(bW1/2);
document.getElementById("gutters").style.left=bX1;
document.getElementById("gutters").style.top=bY1;
document.getElementById("gutters").style.height=bH1;
document.getElementById("gutters").style.width=bW1;
document.getElementById("gutters").style.backgroundColor="black";
document.body.style.backgroundColor="black";
}
//document.body.onload=winSize();
</script>
</head>
<body>
<div id="gutters">
</div>
<script>
//winSize();
</script>
</body>
</html>
Secondly, in the more complicated version of this script that includes a div within "gutters" that houses an img (soon to be multiple, as soon as this problem is solved), almost everything works fine except for when it loads, it does not load the styles (in Chrome). It does, however, load the styles on a refresh or if I set a 50ms delay on the onload trigger. I presume this is because Chrome (and Safari?) triggers the onload event after the html has loaded but before the image itself has been rendered, therefore the function cannot determine the height and width of the body that has not truly finished loading.
In this second script the function above:
function winSize(){
winW=document.body.scrollWidth;
winH=document.body.scrollHeight;
_style();
}
does not work at all. winH or winW are not defined.
but the function snagged from http://www.javascripter.net/faq/browserw.htm
function winSize(){
if (document.body && document.body.offsetWidth) {
winW = document.body.offsetWidth;
winH = document.body.offsetHeight;
}
if (document.compatMode=='CSS1Compat' &&
document.documentElement &&
document.documentElement.offsetWidth ) {
winW = document.documentElement.offsetWidth;
winH = document.documentElement.offsetHeight;
}
if (window.innerWidth && window.innerHeight) {
winW = window.innerWidth;
winH = window.innerHeight;
}
}
works as described above: "...when it loads it does not load the styles (in Chrome). It does, however, load the styles on a refresh." If I run this second winSize function in the first script it returns the error "Cannot read property 'style' of null".
I prefer the first function for its brevity and (according to W3schools.com) better cross browser compatibility with object.scrollWidth over window.innerWidth, but clearly, one or both are broken in some context.
My questions are, in order of importance:
In the second script, how can I get the 'winSize' function to run after the images have fully loaded? (if that is the issue)
Why are the two scripts having such drastically different reactions to the two functions when implemented in the same way.
What would fix the first script that I presented--where the first content div, "gutters", is filling the entire screen rather than making a rectangle.
Why putting an onload event in the body tag works, but putting document.body.onload in the script of the head doesn't.
Sorry for such a long question--and so many questions in one, but I couldn't figure a way to untangle them. I would appreciate any help and forever praise those who can help me wrap my head around this.
why not just specify dimensions in % and let the browser do it.
May be you have some very specific requirement?
Please write the scenario, (in short)
Related
Note that I'm not asking how to make a div the size of the "window" or "viewport" for which there are plenty of existing questions.
I have a web page of some height and width, and I'd like to add an empty, top-level div (i.e., not one containing the rest of the page) with a size exactly equal to the page's height and width. In practice, I also want it to be at least the size of the viewport.
I know I can do a one-time calculation of the height and width in JavaScript:
var height = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);
var width = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);
But this value can change based on images loading, or AJAX, or whatever other dynamic stuff is going on in the page. I'd like some way of locking the size of the div at the full page size so it resizes dynamically and on-demand.
I have tried something like the following:
function resetFakeBg() {
// Need to reset the fake background to notice if the page shrank.
fakeBg.style.height = 0;
fakeBg.style.width = 0;
// Get the full page size.
var pageHeight = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);
var pageWidth = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);
// Reset the fake background to the full page size.
fakeBg.style.height = pageHeight + 'px';
fakeBg.style.width = pageWidth + 'px';
}
// Create the fake background element.
fakeBg = setFakeBgStyle(document.createElement('div'));
document.body.appendChild(fakeBg);
// Keep resizing the fake background every second.
size_checker_interval = setInterval(resetFakeBg, 1000);
Limitations
This is for a Chrome extension, and I'd like to limit my modification of the page to adding this single div. This means that adding CSS to modify the height and width of the html and/or body tags is undesirable because it might have side-effects on the way the rest of the page is rendered.
In addition, I do not want to wrap the existing page in the div because that has the potential to break some websites. Imagine, for example, a site styled with the CSS selector body > div. I'd like my extension to break as few websites as possible.
WHY OH WHY WOULD I NEED TO DO THIS?
Because some people like to hold their answers hostage until they're satisfied that I have a Really Good Reason™ for wanting to do this:
This is for an accessibility-focused Chrome extension that applies a CSS filter across an entire page. Recent versions of Chrome (>= 45) do not apply CSS filters to backgrounds specified on the <html> or <body> tag. As a result, I have chosen to work around this limitation by copying the page's background onto a div with a very negative z-index value, so that it can be affected by the page-wide CSS filter. For this strategy to work, the div needs to exactly imitate the way the page background would appear to a user—by being the exact size of the document (and no larger) and at least filling the viewport.
setInterval() is your best friend in cases like this where you want the .height() and .width() of an element to be asynchronously specified all the time to something that can be dynamicly altered by user input and DOM tree changes. It is what I dub as a "page sniffer", and arguably, works better than $(document).ready if you are working in multiple languages (PHP, XML, JavaScript).
Working Example
You should get away with setting the width and height in the window resize function, you might wanna add it in a load function as well, when all data/images are loaded.
just add width=100%
e.g;-
Hello World
I think you must do it like this:
...
<body>
<script>
function height()
{var height = Math.max(document.body.scrollHeight,
document.documentElement.clientHeight);}
function width()
{var width = Math.max(document.body.scrollWidth,
document.documentElement.clientWidth);}
</script>
<div height="height()" width="width()">
</div>
</body>
...
My dev site uses lots of Skrollr animation at 1024px resolutions and up. Under 1024px, I don't want the animation to show, so I hid all of the images and whatnot.
However, the javascript that gets called to make the animation work is still getting called on smaller resolutions and causing some issues.
Is there a way to basically say "If the resolution is less than 1024px, ignore these JS files"?
I tried putting them in a DIV and using my existing CSS media queries to "display: none" the DIV on smaller resolutions, but that doesn't work.
FYI, these are the files being called:
<script type="text/javascript" src="/js/skrollr.min.js"></script>
<script type="text/javascript" src="/js/homepageanimation.js"></script>
On top of the jQuery(function($) { in http://workwave.joomlatest01.mms-dev.com//js/homepageanimation.js put something like
jQuery(function($) {
if(screen.width < 1024) {
return;
}
// skrollr stuff....
}
so all the skrollr functions won't be called on screen sizes with a width below 1024px.
The easiest way is too use jQuery..
$(window).width();
plain Javascript:
var w = window.innerWidth;
var ow = window.outerWidth; //toolbars and status, etc...
if(w > 1024) {
//Skrollr
}
from there an small if to trigger the Skrollr event
I would suggest conditionally loading the script. Basically the script only gets loaded if the screen size is greater than 1024.
if(window.innerWidth >= 1024){
var file = document.createElement('script')
file.setAttribute("type","text/javascript")
file.setAttribute("src", "/js/skrollr.min.js")
}
A nice approach here would be to only call the function that initiates the Skrollr functionality at given screen sizes. A real quick Google suggests that Skrollr has a .init() function that gets things rolling.
Without seeing how the JS is set up it's hard to give any solid advice, but here's an idea:
You have a JS file for the page/site that contains a conditional that checks the width of the window before initializing the plugin after the document is ready.
$(document).ready(function() {
if ($(window).width() > 1023) {
skrollr.init();
}
});
jQuery makes this a lot easier too, so it's worth taking advantage of that.
Another option to consider instead of going via window width (which can sometimes be inconsistent with the CSS widths among different browsers) is to test against a CSS rule and whether it is true, so use one you know would be true at a size above 1024px, and this would eliminate any inconsistency.
Within this condition link the JQuery files as demonstrated in other answers.
I have a control contained in an iframe on a page of my ASP.NET web application.
Control changes its vertical size correspondingly to what user selects on it (some elements get in, others get out). So, I have to set the iframe size precisely to get the whole control shown and not to make gap between the iframe and the elements below it.
Somewhere on the web I have found a way to get the document height in a cross-browser way:
function getDocHeight(document) {
return Math.max(
Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
Math.max(document.body.clientHeight, document.documentElement.clientHeight)
);
}
On self.document.body.onload on the control page, hence, I call this function:
function adjustIframeHeight() {
var iframe = window.parent.document.getElementById(window.frameElement.id);
var iframeHeight = getDocHeight(iframe.contentWindow.document);
iframe.style.height = iframeHeight + "px";
}
The problem is it works fine e.g. in Firefox, but in some cases bottom sections of the control are cutoff in Chrome and IE for example.
Is there some truly cross-browser way to get this height, or I am doing something else wrong?
Thank you for the time
I'd use something like jQuery to help out with this (since using height methods seem to vary from browser to browser) and here is some jQuery code that could help out:
$(document).height(); // height of HTML doc
I'm using epiceditor within my site, and I am populating it with markdown embedded on the page by the server. Currently when epiceditor displays, it has a very small default height, with scroll bars to handle viewing the entire content. I can manually set the height of the div, and for now that's the best I've been able to do (I've set it to something reasonably large: 800px). However I would like its height to always be enough to fit the entire content without scroll-bars. Essentially something like overflow:visible.
Here's the relevant portions so far
<html>
<head>
<script src="/assets/javascripts/epiceditor/js/epiceditor.min.js" type="text/javascript"></script>
<script id="postMarkdown" type="text/markdown" data-postId="1">
#Markdowns in here
...
</script>
<style>
#epiceditor{
height: 800px;
}
</style>
<script src="/assets/javascripts/thrown/posts/edit.js" type="text/javascript"></script>
</head>
<body>
<div id="epiceditor">
</div>
</body>
</html>
And heres the edit.js source (its compiled from coffescript)
$ ->
postMarkdown = $("#postMarkdown").first()
options =
basePath : '../../assets/javascripts/epiceditor'
editor = new EpicEditor(options).load()
postId = postMarkdown.data('postId')
markdown = postMarkdown.html()
editor.importFile('posts/'+postId,markdown);
editor.reflow();
I was hoping reflow might expand the height after the content was inserted, however no such luck. However If I resize the div and call reflow, It does resize properly.
I've inspected the markup it creates in hopes I could determine the height and resize its container and tell it to reflow. However it seems it contains multiple iframes, and at a glance I didn't expect that to be a quick change, or if it would even be possible. However I'd welcome any solution.
I also understand that if I size its container to the right height, epiceditor will fill the proper space. However I want its height to be the amount needed to render, such that the editor takes up the right space in the rest of the sites design. Therefore if there something I can set in EpicEditor to have it not overflow in the manner it is, or a way to determine the height after it loads, I'm set.
Thanks for any help.
I'm the guy who made EpicEditor, here's a solution for you:
var editor = new EpicEditor({
basePath: 'https://raw.github.com/OscarGodson/EpicEditor/develop/epiceditor'
});
var updateEditorHeight = function () {
editorHeight = $(editor.getElement('editor').body).height();
// +20 for padding
$('#epiceditor').height(editorHeight + 20);
editor.reflow();
}
editor.load(function (){
updateEditorHeight();
});
editor.on('update', function () {
// You should probably put a check here so it doesn't
// run for every update, but just on update, AND if the
// element's height is different then before.
updateEditorHeight();
});
Also, in the CSS I added a overflow: hidden to epiceditor's wrapper so the scrollbars don't appear as it grows.
DEMO: http://jsbin.com/eyidey/1/
DEMO CODE: http://jsbin.com/eyidey/1/edit
UPDATE
As of EpicEditor 0.2.2 autogrow is built in. Just turn on the autogrow option.
I'm making a canvas webpage for animation. Strange thing is that every time I launch the webpage from double clicking the html file the canvas will almost always size incorrectly. I have post a similar question before: Canvas sizing incorrectly on loading but have no desired answer.
After extensive debugging I find out that it's the window.innerWidth that's giving me such trouble. The window.innerWidth returns 0 every time the page is launched from double clicking the html file and results in a incorrect canvas size (interestingly the canvas size is not exactly 0, but a very small one that has object to be rendered stack on top of one another), but after reloading the page (Ctrl+R) the problem no longer happens. I'm using jQuery to load the page, here is my code:
html:
<body>
<canvas id="main_canvas"></canvas>
</body>
js:
$(document).ready(function() {
var SCREEN_WIDTH = window.innerWidth-10,
SCREEN_HEIGHT = window.innerHeight-10;
if (window.innerWidth === 0) { alert("wtf? width = 0?");}
var canvas = $('canvas')[0],
context;
init(); // use $(window).load(init) does not fix the problem
function init() {
if (canvas.getContext) {
context = canvas.getContext('2d');
animate(); // draw stuff
}
else {
alert('Your browser does not support html5 canvas');
}
}
});
As you can see here, I'm already using $(docuemnt).ready(function()) to make sure things gets loaded, however from a link http://4loc.wordpress.com/2009/04/28/documentready-vs-windowload/ the author suggest that the document ready event executes already when the HTML-Document is loaded and the DOM is ready, even if all the graphics haven’t loaded yet.
On the other hand the $(window).load(function()) executes a bit later when the complete page is fully loaded, including all frames, objects and images. Therefore functions which concern images or other page contents should be placed in the load event for the window or the content tag itself. But even I use this the problem is not solved.
Maybe the js file is asking for window's width before it's loaded, but I can't find a viable solution. Can anyone help with this?
Use an event listener that triggers on a window resize. That way you don't have to do any nonsense with trying to find when the window fully initializes. It will also make you less dependent on state which is a nice bonus.
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
windowX = window.innerWidth;
windowY = window.innerHeight;
}
I had a similar problem with window.outerWidth which is returning 0 on some browsers when called from the ready() method, and I solved it by using screen.width instead.
I didn't test it but I think that screen.availWidth would solve your issue.