So, I've got a button that display toggles a div on a click event. It works properly. However, I can't hide the same div using nearly the same code (however, I want to toggle this div after my screen becomes too big, not after clicking), because I get the problem like in the title- 'cannot read property style of null'
The part that doesn't work (hiding a div after screen becomes too big:
if (screen.width > 900) {
document.getElementById('klik').style.display = 'none';
}
And the part that works (button toggles a div using a click event):
function showDiv() {
if (document.getElementById('klik').style.display == 'block'){
document.getElementById('klik').style.display = 'none';
}
else{
document.getElementById('klik').style.display = 'block';
}
}
I wrote this code because I want to do a scalable menu, displaying a div with list items inside after clicking on it. The menu button is visible only when screen-width <= 900px, if screen-width > 900px I've got a normal navigation bar and the button disappears.
Am I forgetting something? I'm new to Javascript. Also one more thing- it also doesn't work using #media rule, however I can change the background-color with #media. I hope it might help. Also thanks in advance.
Note Two Problems:
Ensure that the element you want to change it's display has the id="klik"
The below code will execute only once.
if (screen.width > 900) { document.getElementById('klik').style.display = 'none'; }
But why?
The answer is because you didn't set an event to run it every time when your resize the screen. Also, screen.width will always return the width of the display. What you are looking for is the window.innerWidth
So a possible solution:
window.addEventListener('resize', function(){
document.getElementById("screen").innerHTML = window.innerWidth.toString() + "px";
if(window.innerWidth < 900)
{
//Perform your desired Executions Here
}
});
<div id="screen"></div>
This will run the code every time a window.onresize is triggered. And that's exactly what #media in CSS does. It works on window.onresize behind the scene in javascript sense.
Note: I have added a simple illustration on how to work with screen.resize which you can use as the basis for modifying element properties based on a certain range. All you need to do, is to ensure that you do your styling within that block and it will work.
Hmmm, actually this is exactly what media queries are made for. Did you try
#media (min-width: 900px) {
#klik {
display: none;
}
}
If that doesn't work: Are there any other css styles that may overwrite that particular style? Something like #klik { display: block !important; } ...?
I have a fixed div that I want to sit on top of a number of background images. The issue is that if this fixed div is taller than the window, it wont scroll, meaning content is lost. I've tried using max-height: 100% and y-overflow:scroll; but no luck.
I have figured a workaround using the following javascript:
<script>
$(window).scroll(function(){
var css = {};
if ($(window).scrollTop() > 120){
css = { top:'0'};
}
else {
css = {top:'120'};
}
$('#writtenContent').animate(css,{duration:200,queue:false});
});
</script>
Which moves it up, but this is not ideal for a number of reasons. Id like to either be able to know how much of the div is hidden, and then move up that amount, or have the fixed div scrollable. Ideally either of these should only happen if necessary i.e. if the div fits in the window, then no action taken.
Any ideas would be great!
===============UPDATE=================
Hi guys - here is a quick jsfiddle showing the type of thing. Its a stripped down version, but shows the problem Im having. If the window is resized to be smaller than the content holding div, we loose it.
Ok well first off, you said that it's a fixed div, which generally means position:fixed but then you say position:relative? What do those refer to? But it really should be scrolling. You said you tried y-overflow but of course that won't work. It's overflow-y with the y after. Try that again and see if it works. If it doesn't work then you will need to post all of the relevant code and styles so we can see what is going on.
Also it's somewhat hackish but try using max-height: with varying percentages less than 100% to see if it works even a little bit correctly.
If I'm understanding you correctly, this will work for you.
var win = window,
$writtenContent = $('#writtenContent'),
$writtenContentPosition;
function windowScrollMagic(){
$writtenContentPosition = $writtenContent.offset().top; // get elements distance from top
// if you've scrolled farther than the elements position:
if (win.scrollY > $writtenContentPosition) {
// do something, like animating $writtenContent to the win.scrollY coordinate
}
}
$(document).ready(function(){
$(win).scroll(){
windowScrollMagic();
});
});
Update in response to example jsfiddle:
var $win = $(window),
$winHeight,
$writtenContent = $('#writtenContent'),
$writtenContentPosition,
$writtenContentHeight,
$writtenContentBottomEdgePosition,
heightDifference;
function calculateHeights() {
$winHeight = $win.height();
$writtenContentPosition = $writtenContent.offset().top;
$writtenContentHeight = $writtenContent.height();
$writtenContentBottomEdgePosition = $writtenContentPosition + $writtenContentHeight;
heightDifference = $winHeight - $writtenContentBottomEdgePosition;
}
function windowResizeMagic() {
calculateHeights();
if (heightDifference < 0) {
$('#alert').html('Written Content is off screen by ' + heightDifference + 'px');
} else {
$('#alert').html('Written Content is not off screen');
}
}
$(document).ready(function(){
calculateHeights();
$win.resize(function(){
windowResizeMagic();
});
});
This is the JS code i'm using:
$("document").ready(function($){
var nav = $('#menu2');
$(window).scroll(function () {
if ($(this).scrollTop() > 90) {
nav.addClass("f-nav");
} else {
nav.removeClass("f-nav");
}
});
But i can't seem to get this into my code.
function checkWidth(init){
/*If browser resized, check width again */
if ($(window).width() < 514) {
$('html').addClass('mobile');
}
else {
if (!init) {
$('html').removeClass('mobile');
}}}$(document).ready(function() {
checkWidth(true);
$(window).resize(function() {
checkWidth(false);
});
And what i want is that when .f-nav is added to #menu2, when the screen is <1050 the classshould be removed.
To change html to #menu2, just replace one with the other. jQuery is pretty simple in this respect
if ($(window).width() < 514) {
$('#menu2').addClass('f-nav');
} else {
$('#menu2').removeClass('f-nav');
}
JSFiddle
There are a few ways to do that:
Javascript only
See it in action: Fiddle
$(window).resize(function() {
if ($(window).width() < 1050) {
$selector.removeClass('my-class');
} else {
$selector.addClass('my-class');
}
}).resize(); // trigger resize event initially
And don't forget: You don't have to place $(window).resize inside $(document).ready.
Mixed Javascript & CSS
See it in action: Fiddle
This technique is explained here: http://www.senaeh.de/media-query-variablen-javascript-auslesen/
Basic principle: set a variable with a CSS pseudo element and get it with javascript.
This workaround is good if you have to use Javascript even if media queries are used, because you don't have to declare the breakpoint twice.
CSS
#media screen and (max-width: 1050px) {
body:after {
content: 'tablet';
display: none;
}
}
Javascript
var mode = window.getComputedStyle(document.body,':after').getPropertyValue('content');
Be aware: IE < 9 doesn't support getComputedStyle. You have to use a polyfill like this one.
this is best achieved with a media query
#media screen and (max-width:1050px){
.mobile{
/* will only apply on devices narrower than 1050px */
}
}
EDIT: also possible to use media queries with javascript in modern browsers
if (matchMedia) { // check if browser supports media queries from JavaScript
var mq = window.matchMedia("(max-width: 1050px)");
WidthChange(mq);
// every time width changes, check the media query
mq.addListener(function WidthChange(mq){
if(mq.matches){
//we are in a mobile size browser
$('#menu2').addClass('mobile');
$('#menu2').removeClass('f-nav');
} else{
// desktop browser
$('#menu2').addClass('f-nav');
$('#menu2').removeClass('mobile');
}
});
}
When you load a website on a screen bigger than your breakpoint, the script wont work, because you need to re-calculate the screen size(refresh the page in this case). You need to get the width of the screen on resize. Use resize() method, and inside it place your test condition, and assign the class to your element. Reference to help you: http://api.jquery.com/resize/
If you want to change the class of a div in JS, you can do something like that:
document.getElementById("#YourId").className = "YourNewClass"
It will just change your class attribute :-)
Like that, you can also check which class is used and do what you want to do with that.
Edit thanks to Olaf Dietsche: this must be a duplicated post, here can be your answer: jquery, add/remove class when window width changes
I want to resize a div on resize of the window to make it fill the entire browser window...
I searched a lot on internet finding a solution, but everything I tried cause the same problem...
at first load of the page it works well, but when I try to resize the window the value of bodyheight keeps increasing...
this is my code
$(document).ready(function() {
body_sizer();
$(window).resize(body_sizer);
});
function body_sizer() {
var bodyheight = $(window).height();
$("#contenitore_full").css('height', bodyheight);
}
EDIT
OK!!! my fault as i thought :)
problem was caused by a wrong way to call jquery in wordpress.
i'm sorry for let you loose time
thanks a lot everyone
ale
You don't need javascript to achieve what you want. All you need is CSS.
Here's a fiddle
CSS
body, html { margin:0; height:100% }
#contenitore_full { border:1px solid #FF0000; width:25%; height:99%; display:block; }
HTML
<div id="contenitore_full"></div>
The thing is in order for height to work, the parent's height also needs to be defined. That's why the height of the body and html tags also have a height of 100%.
It looks like your 'body_sizer' function might not be firing. Add your parens () to the end of it or either create an handler function inside .resize()
$(window).resize(function() {
var bodyheight = $(window).height();
$("#contenitore_full").css('height', bodyheight);
});
I had the exact same problem. I recommend using javascript instead of jQuery.
const width = window.innerWidth;
const height = window.innerHeight;
I have an Html/JavaScript application that contains N columns that need to be large enough contain all of the possible LI elements from all of the columns.
The simple solution seems to count the heights of all of the items in each column, compensate for padding, and then set the height to that total for each of the columns.
This works great when the LI elements contain plain text. Unfortunately, when the LI elements contain images instead, various browsers have problems. For example, when I first load the page in FireFox, it looks like the screenshot below, but upon another refresh, it works fine. It doesn't work as expected in Chrome either.
My application does not pre-populate the LI elements when the page loads - it uses JavaScript, as follows:
function populateUnsetAnswers(unsetCategoryAnswers) {
for (i in unsetCategoryAnswers) {
if (unsetCategoryAnswers.hasOwnProperty(i.toString())) {
$('#categoryQuestionArea #possibleAnswers').append(
categoryAnswerLiTag(unsetCategoryAnswers[i])
);
}
}
}
function categoryAnswerLiTag(unsetCategoryAnswer) {
var html = '<li id="' + unsetCategoryAnswer.id + '">';
if (unsetCategoryAnswer.image) {
html += '<img class="categoryAnswerImage" title="';
html += unsetCategoryAnswer.text;
html += '" src="/trainingdividend/rest/streaming/';
html += unsetCategoryAnswer.image.fileName;
html += '" style="height: ';
html += unsetCategoryAnswer.image.height;
html += ';';
html += '" />';
} else {
html += unsetCategoryAnswer.text
}
html += '</li>';
return html;
}
When the page is done loading, an ajax request fetches all of the objects to be put into LI elements, and then calls the first function above.
After all of the LI elements are created, I call this function right after it:
function resize() {
var currentHeight, totalHeight;
totalHeight = 0;
$("#categoryQuestionArea ul").children().each(function() {
currentHeight = $(this).height();
totalHeight += currentHeight + 13;
});
$("#categoryQuestionArea ul").height(totalHeight);
$("#categoryQuestionArea div#separator").css("padding-top", (totalHeight / 2) + "px");
}
Is there any way to tell jQuery, "Don't call resize() until all of the LI's are fully loaded and the images have rendered" ?
I think what's happening is that on the initial page load, the height of these LI elements is 0 or a small value because it doesn't contain the image, so my resize function is calculating the wrong result (I tested this with some alert statements). As long as the LIs are populated and the images have loaded, the total height is calculated just fine.
Any help? Thanks
To literally answer the question you asked, if you want to only call resize() when all images have finished loading, then you need to install onload handlers for those images and when you've recorded that the last one is now loaded, you can call the resize() function. You could do that like this (code explanation below):
var remainingAnswerImages = 0;
function categoryAnswerImageLoadHandler() {
--remainingAnswerImages;
if (remainingAnswerImages === 0) {
resize();
}
}
function populateUnsetAnswers(unsetCategoryAnswers) {
// add one extra to the image count so we won't have any chance
// at getting to zero before loading all the images
++remainingAnswerImages;
var possibleAnswers$ = $('#categoryQuestionArea #possibleAnswers');
for (i in unsetCategoryAnswers) {
if (unsetCategoryAnswers.hasOwnProperty(i.toString())) {
possibleAnswers$.append(categoryAnswerLiTag(unsetCategoryAnswers[i]));
}
}
// remove the one extra
--remainingAnswerImages;
// if we hit zero on the count, then there either were no images
// or all of them loaded immediately from the cache
// if the count isn't zero here, then the
// categoryAnswerImageLoadHandler() function will detect when it does hit zero
if (remainingAnswerImages === 0) {
resize();
}
}
function categoryAnswerLiTag(unsetCategoryAnswer) {
var obj = document.createElement("li");
obj.id = unsetCategoryAnswer.id;
if (unsetCategoryAnswer.image) {
// count this image
++remainingAnswerImages;
var img = new Image();
img.onload = img.onerror = img.onabort = categoryAnswerImageLoadHandler;
img.title = unsetCategoryAnswer.text;
img.style.height = unsetCategoryAnswer.image.height;
img.src = "/trainingdividend/rest/streaming/" + unsetCategoryAnswer.image.fileName;
obj.appendChild(img);
} else {
obj.innerHTML = unsetCategoryAnswer.text;
}
return obj;
}
By way of explanation, this code makes the following changes:
Add a variable remainingAnswerImages to keep track of how many images still need to be loaded.
Add an onload handler for each <img> tag that is created so we can keep track of when it's loaded.
Each time we generate the HTML for an tag with the onload handler, increment remainingAnswerImages.
When you're done adding all the HTML, check the remainingAnswerImages count to see if it's zero (this would only be the case if there were no images or if all images loaded immediately from the browser cache). If so, call resize() immediately.
In the onload handler which will be called for each image, decrement remainingAnswerImages and if the count has reached zero, call resize().
While adding images, add one extra to remainingAnswerImages as a gate to keep from getting to a zero count until we're done adding images. When done adding images, take that one extra out.
I also rewrote the categoryAnswerLiTag() function to just create the DOM objects directly rather than concat a bunch of strings together into HTML. In this case, the code is a lot cleaner to read and maintain.
I also moved the $('#categoryQuestionArea #possibleAnswers') out of your for loop since it resolves to the same thing every time. Better to do it once before the loop. Also, in most cases, this could be simplified to $('#possibleAnswers') since ids are supposed to be unique in the page.
Here is a jquery plugin that checks the images have loaded: https://github.com/alexanderdickson/waitForImages
Sample usage for your case would be:
$('#categoryQuestionArea').waitForImages(function() {
resize();
});
I would also just check for the total height of the <ul> instead of looping through the list items as you would have to manually change the script if either the padding, margins, or borders on the list items changes later on.
If you do have problems with images on the first page load maybe it is due to the fact that they are not cached and therefore not immediately available. So measuring their height will lead to bad results... did you debug the height that was fetched via jQuery (for example
currentHeight = $(this).height();
console.log(currentHeight);
The only way to do that is I think to observe the load events of all images (and probably the error as well) and count whether all request have been finished
try using
$('img').load(function(){
//put code here
});
I guess your HTML is screwed up. Particularly, your <img> tags.
Add the width and height attributes to your <img> tags. Everything will be magically solved.
See this jsfiddle to understand what I mean: http://jsfiddle.net/Ralt/Vwg7P/
Even though there is no image in there, the width and height attributes will occupy the space required for the image. As soon as the DOM is loaded.
This is rather a CSS problem, most probably due a fixed height, with items either floated or absolutely positioned.
There are number of ways to fix this.
Give a min-height instead of fixing a height.
#container { min-height: 100px; }
Clear the float and do not set any heights
#container { overflow: hidden; }
Use Scripts to add up to the height, once every element is added. Like the jQuery snippet below
$("#container").append($("#theimg"));
$("#container").height($("#container").height()+$("#theimg").height());
I think I might have a solution for you.
The main idea of my solution lies in CSS. You want to have 3 columns of the same height, right? You can have something like this: http://jsfiddle.net/agilius/NvzZp/46/
There is quite a lot of CSS there, but the main idea is this:
I simulate a 3 column layout under the actual content, with the .inner and .column classes.
The content is placed over (via z-index 2 > .inner zindex 1), with the same width as the columns that are under.
When content is added to the content zones, the height of the main #container updates.
Since .inner is top,left,right,bottom = 0, it updates, and since the .columns have 100% height, they update their height to match the #containers height.
Observations.
You can have padding, borders, margins in the .column class as you see fit.
No javascript is required.
Another simple Equal Height CSS solution:
LOGIC is very simple -
all of the columns/LI are floated
with .eH{ padding-bottom: X; margin-bottom: -X } and
wrapper/UL is .eW{overflow: hidden}
X= large arbitrary amount of px for factor of safety
EXAMPLE:
http://jsfiddle.net/rahen/TXVYD/4/
This sounds exactly like one of the problems i had when coding SudoSlider.
Below i've copied the code i solved it with. Just call autoheightwidth(i, 0, true) inside your resize() function.
The basic idea is that you do not know when the browser has completed loading the images, so instead of relying on a single height adjustment, you adjust the height every time something happens (mostly just that an image has been loaded).
It should work if you change the references of "obj" and "li" in the first 2 methods.
It's not very readable, but there was a big focus on size when i coded it.
// Automaticly adjust the height and width, i love this function.
// Before i had one function for adjusting height, and one for width.
function autoheightwidth(i, speed, axis) // Axis: true == height, false == width.
{
obj.ready(function() {// Not using .load(), because that only triggers when something is loaded.
adjustHeightWidth (i, speed, axis);
// Then i run it again after the images has been loaded. (If any)
// I know everything should be loaded, but just in case.
runOnImagesLoaded (li.eq(i), falsev, function(){
adjustHeightWidth (i, speed, axis);
});
});
};
function adjustHeightWidth (i, speed, axis)
{
var i = getRealPos(i); // I assume that the continuous clones, and the original element is the same height. So i allways adjust acording to the original element.
var target = li.eq(i);
// First i run it. In case there are no images to be loaded.
var b = target[axis ? "height" : "width"]();
obj.animate(
axis ? {height : b} : {width : b},
{
queue:falsev,
duration:speed,
easing:option[8]/*ease*/
}
);
}
function runOnImagesLoaded (target, allSlides, callback) // This function have to be rock stable, cause i use it ALL the time!
{
var elems = target.add(target.find('img')).filter('img');
var len = elems.length;
if (!len)
{
callback();
// No need to do anything else.
return this;
}
function loadFunction(that)
{
$(that).unbind('load').unbind('error');
// Webkit/Chrome (not sure) fix.
if (that.naturalHeight && !that.clientHeight)
{
$(that).height(that.naturalHeight).width(that.naturalWidth);
}
if (allSlides)
{
len--;
if (len == 0)
{
callback();
}
}
else
{
callback();
}
}
elems.each(function(){
var that = this;
$(that).load(function () {
loadFunction(that);
}).error(function () {
loadFunction(that);
});
/*
* Start ugly working IE fix.
*/
if (that.readyState == "complete")
{
$(that).trigger("load");
}
else if (that.readyState)
{
// Sometimes IE doesn't fire the readystatechange, even though the readystate has been changed to complete. AARRGHH!! I HATE IE, I HATE IT, I HATE IE!
that.src = that.src; // Do not ask me why this works, ask the IE team!
}
/*
* End ugly working IE fix.
*/
else if (that.complete)
{
$(that).trigger("load");
}
else if (that.complete === undefined)
{
var src = that.src;
// webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f
// data uri bypasses webkit log warning (thx doug jones)
that.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; // This is about the smallest image you can make.
that.src = src;
}
});
}
I think the Browser does not know the images' dimensions, because they are not loaded.
Either try to wrap the invocation of resize in a
jQuery(document).load( function funcName() {
...
} )
or give the image width and height attributes in the HTML img tags.
Maybe both