Why Doesn't This Javascript Work? Style Change - javascript

I cant for the life of me figure out why this doesn't work:
javascript:
//==================================//
// resize_middle //
//----------------------------------//
// Resizes the content and left //
// navigation div to make up the //
// remains of available space. //
//==================================//
function resize_middle()
{
min_height = (window.innerHeight - 276) + "px";
middle_left = document.getElementById("middle_left");
middle_right = document.getElementById("middle_right");
alert("its not going to work!");
alert("here goes...");
alert(min_height);
middle_left.style.minHeight = min_height;
alert("it works!");
middle_right.style.minHeight = min_height;
}
//==================================//
// event handlers //
//==================================//
window.onload = resize_middle();
window.onresize = resize_middle();
html(body & javascript bit in head shown only):
<script src="javascript.js" type="text/javascript" charset="utf-8"></script>
<body>
<div id="container">
<div id="central_column">
<div id="top_left">
<img src="./images/icon.png" alt="icon" style="width:100%;height:auto;" />
</div>
<div id="top_right">
top right
</div>
<div id="middle_left">
middle left
</div>
<div id="middle_right">
middle right
</div>
<div id="bottom">
bottom
</div>
</div>
</div>
</body>
I'v used this before and have a working copy of some only slightly different code, but it works perfectly. I get the debugging alerts up until "it works!", which I don't get. Thanks in advance, ell.

You need this instead:
window.onload = resize_middle;
window.onresize = resize_middle;
Because as having it resize_middle() the function is processed immediately and the result is added to the event. You want the function itself to be added to the event so you leave off the () unless your function returns a function for the event to use.

You need this instead:
window.onload = resize_middle;
window.onresize = resize_middle;
Currently you're calling those functions and assigning their return value to the event. What you want is to assign the functions themselves to the events, and let the events call them.
Side note:
Unless the variables in resize_middle are defined elsewhere and you intend for them to be accessible to the outer scope, it is good practice to use the var keyword when defining new variables.
function resize_middle()
{
// Changed to use "var"
var min_height = (window.innerHeight - 276) + "px";
var middle_left = document.getElementById("middle_left");
var middle_right = document.getElementById("middle_right");
alert("its not going to work!");
alert("here goes...");
alert(min_height);
middle_left.style.minHeight = min_height;
alert("it works!");
middle_right.style.minHeight = min_height;
}

window.onload = resize_middle;
Read this resource on assigning event handlers.

Related

how can I set a setInterval as a global variable?

I just wanna make a button to start adding some text in my body, and a button to stop adding this text.
I figured out that I can use a setTimeout in a function or a setInterval...but I couldn't Clear both of them because of the local scope...I can't declare both of them as a global scope, I want my button.onclick activate them not by default.
/* global document*/
var myStart = document.querySelector('#start'),
myEnd = document.querySelector('#end'),
myRepeat;
function start() {
"use strict";
document.body.innerHTML += '<br>Welcome StackOverFlowMembers!';
myRepeat = setTimeout(start, 1000)
}
function stop() {
"use strict";
clearTimeout(myRepeat);
}
myStart.onclick = start;
myEnd.onclick = stop;
<body>
<button id="start">Start!</button>
<button id="end">End!</button>
<script src="script.js"></script>
</body>
The problem here is not the scope of the variables. Everything is actually fine with your code on that.
The problem is here:
document.body.innerHTML += '<br>Welcome StackOverFlowMembers!';
If you replace it with:
console.log('Hello!');
Both buttons will work normally. Check this fiddle.
Basically, when you use innerHTML you destroy the event listeners. You can find more on that in this answer
As #anpel's answer explains, your innerHTML call is trashing your event listeners. In the code below, I work around that by putting the onclick attribute directly into the HTML button elements. The boolean doRepeat variable governs whether a subsequent timeout gets initiated.
/* global document*/
var myStart = document.querySelector('#start'),
myEnd = document.querySelector('#end'),
doRepeat;
function start() {
"use strict";
document.body.innerHTML += '<br>Welcome StackOverFlowMembers!';
if (doRepeat) {
setTimeout(start, 1000);
}
}
<body>
<button id="start" onclick="doRepeat=true;start();">Start!</button>
<button id="end" onclick="doRepeat=false;">End!</button>
<script src="script.js"></script>
</body>
Alternatively, you can make a separate <div> into which your function writes its text-- instead how you're doing innerHTML to the entire HTML body, which destroys all child listeners-- and you won't have to worry about your event listeners getting destroyed since those listeners aren't on children of the target div.
Here's a JS Fiddle to demonstrate that: https://jsfiddle.net/j9voxg7s/

How do I clear inner HTML

I've been fiddling with this for a while but it won't work and I can't figure out why. Please help. Here is what I have:
<html>
<head>
<title>lala</title>
</head>
<body>
<h1 onmouseover="go('The dog is in its shed')" onmouseout="clear()">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
function go(what) {
document.getElementById("goy").innerHTML = what;
}
function clear() {
document.getElementById("goy").innerHTML = "";
}
</script>
</body>
</html>
The mouseover works and displays the text in the div, but when I move the mouse out of the h1 tag, the text stays there and I don't know why, help would be appreciated.
The problem appears to be that the global symbol clear is already in use and your function doesn't succeed in overriding it. If you change that name to something else (I used blah), it works just fine:
Live: Version using clear which fails | Version using blah which works
<html>
<head>
<title>lala</title>
</head>
<body>
<h1 onmouseover="go('The dog is in its shed')" onmouseout="blah()">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
function go(what) {
document.getElementById("goy").innerHTML = what;
}
function blah() {
document.getElementById("goy").innerHTML = "";
}
</script>
</body>
</html>
This is a great illustration of the fundamental principal: Avoid global variables wherever possible. The global namespace in browsers is incredibly crowded, and when conflicts occur, you get weird bugs like this.
A corollary to that is to not use old-style onxyz=... attributes to hook up event handlers, because they require globals. Instead, at least use code to hook things up: Live Copy
<html>
<head>
<title>lala</title>
</head>
<body>
<h1 id="the-header">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
// Scoping function makes the declarations within
// it *not* globals
(function(){
var header = document.getElementById("the-header");
header.onmouseover = function() {
go('The dog is in its shed');
};
header.onmouseout = clear;
function go(what) {
document.getElementById("goy").innerHTML = what;
}
function clear() {
document.getElementById("goy").innerHTML = "";
}
})();
</script>
</body>
</html>
...and even better, use DOM2's addEventListener (or attachEvent on IE8 and earlier) so you can have multiple handlers for an event on an element.
const destroy = container => {
document.getElementById(container).innerHTML = '';
};
Faster previous
const destroyFast = container => {
const el = document.getElementById(container);
while (el.firstChild) el.removeChild(el.firstChild);
};
The h1 tags unfortunately do not receive the onmouseout events.
The simple Javascript snippet below will work for all elements and uses only 1 mouse event.
Note: "The borders in the snippet are applied to provide a visual demarcation of the elements."
document.body.onmousemove = function(){ move("The dog is in its shed"); };
document.body.style.border = "2px solid red";
document.getElementById("h1Tag").style.border = "2px solid blue";
function move(what) {
if(event.target.id == "h1Tag"){ document.getElementById("goy").innerHTML = "what"; } else { document.getElementById("goy").innerHTML = ""; }
}
<h1 id="h1Tag">lalala</h1>
<div id="goy"></div>
This can also be done in pure CSS by adding the hover selector css property to the h1 tag.
Take a look at this. a clean and simple solution using jQuery.
http://jsfiddle.net/ma2Yd/
<h1 onmouseover="go('The dog is in its shed')" onmouseout="clear()">lalala</h1>
<div id="goy"></div>
<script type="text/javascript">
$(function() {
$("h1").on('mouseover', function() {
$("#goy").text('The dog is in its shed');
}).on('mouseout', function() {
$("#goy").text("");
});
});

Call two different functions on same onclick event in javascript one after another

I have one div content whose height should be 300px when i click on another div name button.
But how can i reset the height, when again clicked on button div?
Here is the javascript code for reference:
function chk()
{
var x = document.getElementById('content').style.height = '300px';
}
This is the HTML code
<div id="content">
This is dummy text.
</div>
<div id="button" onclick="chk()">
click to read
</div>
When button div is click content height increases, but how can i reduce the height by clicking on same div with same onclick event?
Use CSS:
#content {
height: auto;
}
#content.expand {
height: 300px;
}
In your script:
function chk()
{
var node = document.getElementById('content');
node.classList.toggle('expand');
}
This keeps the state local to the element you're working on, which makes for more flexible code.
See also: classList API
You could use a flag:
var isSet = false:
function chk(){
if(!isSet) {
var x = document.getElementById('content').style.height = '300px';
isSet = true;
}
else {
// some other computation
isSet = false;
}
}
Either a flag
var flag;
function chk() {
var height = flag ? '0px' : '300px';
document.getElementById('content').style.height = height;
flag = !flag;
}
or by checking the current height
function chk() {
var currHeight = document.getElementById('content').style.height;
var setHeight = height == '300px' ? '0px' : '300px';
document.getElementById('content').style.height = setHeight;
}
If you are just learning HTML, CSS, and JavaScript you should start by making your code more clear.
// HTML should look more like
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<style type='text/css'>
#import 'common.css'; #import 'page.css';
</style>
</head>
<body>
<div id='content'>
This is dummy text.
</div>
<input type='button' value='click to read' id='button' />
<script type='text/javascript' src='common.js'></script>
<script type='text/javascript' src='page.js'></script>
</body>
</html>
Notice, your button should be a button, not a div. XHTML is more expandable for scraping and XSLT, and will work on HTML pages, but not the other way around.
// learn to keep your JavaScript separate pages for caching - common.js
//<![CDATA[
// reduce objects to smaller variables and never use `document.getElementById()`
var doc = document, bod = doc.body;
function E(e){
return doc.getElementById(e);
}
//]]>
// page.js
//<![CDATA[
var button = E('button');
/* The self-executing Anonymous Function below creates scope for `var test` and
returns an unexecuted function you can call later. Note that a function is
basically a variable that if you add `()` to will execute. */
var changeHeight = (function(){
var test = false;
return function(id, before, after){
E(id).style.height = test ? before : after;
test = !test;
}
})();
/* This is a backward compatible way of creating an `onclick` function, unlike
`.addEventListener()` and `attachEvent()`, this is assignment, so it will
write over your last `onclick` assiged to this specific Element */
button.onclick = function(){
changeHeight('content', '20px', '300px');
}
// To combat the comment above you could do something like this:
/*
button.onclick = function(){
changeHeight('content', '20px', '300px');
}
function anotherFunction(){
console.log('wow');
}
var before = button.onclick;
button.onclick = function(){
if(before)before();
anotherFunction();
}
*/
/* An executed function, would execute before the event is handled. The only
thing that is automatically passed to your variable function or Anonymous
Function is the Event Object. In this case it is not necessary, because we
are not accessing the Event Object. */
//]]>

JavaScript windows.onload or referencing new elements?

I'm trying to create a lightbox and I'm having trouble.
I think the problem is either because I have 2 window.onloads or because I'm trying to reference a newly created DOM element. I added some comments in the code below that explain what I'm trying to do.
//open lightbox
window.onload = showLargeImage;
function showLargeImage() {
var enlargeButton = document.getElementById("thumb1"); // thumb1 is a thumbnail you click to get the lightbox
enlargeButton.onclick = handleClick;
}
function handleClick() {
var lightboxContainerId = document.getElementById("lightboxContainer");
lightboxContainerId.innerHTML = '<div class="lightbox"><a class="reduceButton" href="#" ><img id="imageButton" class="largeImage" src="2012/images/web/web1.jpg" width="500" height="500" alt="Web Thumb 1"></a></div>';
} // the inner HTML creates the lightbox.
//close lightbox
window.onload = reduceImage; // i'm pretty sure that this windo.onload is the problem... or, that I'm referencing "imageButton" which is new to the DOM
function reduceImage() {
var reduceButton = document.getElementById("imageButton"); // you're supposed to click the big image in the lightbox to get close it.
reduceButton.onclick = handleReduceClick;
}
function handleReduceClick() {
var shadeId = document.getElementById("lightboxContainer");
shadeId.innerHTML = "say what"; // closing the lightbox simply strips everything out of the lightboxContainer
alert("oh yeah");
}
Here are a few reasons why your code is not working:
showLargeImage and reduceImage are missing invocation parentheses in the places where they are being assigned to window.onload. Without parentheses, window.onload is being assigned a function, but that function is not getting called. You should, for instance, have window.onload = showLargeImage();
As you suspected, the second window.onload is overwriting the first.
reduceButton is (as you also suspected) being assigned before it exists, causing an error.
Here is one solution that may work for you.
HTML:
<!DOCTYPE html>
<html><head><title></title>
</head><body>
View
<div id="lightboxcontainer"></div>
</body></html>
JavaScript:
window.onload = function() {
// click link to show
var enlargeButton = document.getElementById('thumb');
enlargeButton.onclick = function() {
var lightboxContainerId = document.getElementById('lightboxcontainer');
lightboxContainerId.innerHTML = '<img src="http://placehold.it/350x150"' +
'width="350" height="150 alt="Thumb 1">' +
'<p>Click image to hide.</p>';
};
// click image to hide
var reduceButton = document.getElementById('lightboxcontainer');
reduceButton.onclick = function() {
reduceButton.innerHTML = ''; // removes lightbox contents
};
};
Live demo: http://jsfiddle.net/ericmathison/BxwYY/7/
If the code is placed at the end of the <body> (or anywhere after your lightbox elements), just use this:
document.getElementById("thumb1").onclick = function () {
document.getElementById("lightboxContainer").innerHTML = '<div class="lightbox"><a class="reduceButton" href="#" ><img id="imageButton" class="largeImage" src="2012/images/web/web1.jpg" width="500" height="500" alt="Web Thumb 1"></a></div>';
document.getElementById("imageButton").onclick = function () {
document.getElementById("lightboxContainer").innerHTML = "say what";
alert("oh yeah");
};
}
This will do everything you want.

javascript document.getElementById not working

Following is my javascript program. I am trying to get all child tags of parent div tag but when I am running the program document.getElementById('abc') returning null.
function init(){
// currentDiv = document.getElementById("intro");
alert("working");
count = 0;
divs = document.getElementById('abc').getElementsByTagName("div");
alert("HI " + divs)
currentDiv = divs[count];
nextDiv = divs[count + 1]
count = count + 1;
}
window.onload = init();
Following is my div tag definitions:
<div id='abc'>
<div></div>
</div>
thanks.
The problem is in this line:
window.onload = init();
You are running init and setting the return value as the value of window.onload. My guess is that the code is being executed before the DOM is ready, i.e. before the divs exist.
Try this instead:
window.onload = init;
I suggest you start using jQuery instead, then you have much more powerful tools for this kind of DOM search/traversing
<body onload="init()">
<div id='abc'>
<div></div>
</div>
</body>
this probably solves your problem

Categories

Resources