Javascript cannot set innerHTML of button with id because it's "null" - javascript

My goal is to have a button that onclick will call a function to change the styling of the html tag and the text (or innerHTML) of the button itself. Shouldn't be that hard, right? Well...
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>New look for my site!</title>
<link rel="stylesheet" type="text/css" href="main.css">
<script src="change-template.js"></script>
</head>
<body>
<aside>
<button type="button" id="template-button" onclick="changeTemplate()">Nightmode: On</button>
</aside>
<main>
<h1>New page look for my site</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</main>
</body>
</html>
CSS (main.css):
html{
background: "#111";
color: "#0F0";
}
JS (change-template.js):
var html = document.getElementsByTagName('html')[0];
var button = document.getElementById('template-button');
var nightmode = true;
function changeTemplate(){
//change to lighter color if black and vice versa
if(nightmode){
html.style.background = "#EEE";
html.style.color = "#000";
button.innerHTML = "Nightmode: OFF";
}else{
html.style.background = "#111";
html.style.color = "#0F0";
button.innerHTML = "Nightmode: ON";
}
nightmode = !nightmode;
}
And I'm getting this error
Uncaught TypeError: Cannot set property 'innerHTML' of null
at changeTemplate (change-template.js:10)
at HTMLButtonElement.onclick (new-look.html:11)
So please help me it's 90 degrees and I'm sitting here on the verge of hunger stressed about this simple issue and can barely think.

That is because, your script is parsed, event before the elements are available in the DOM.
When the parser encounters var button = document.getElementById('template-button'); the element is not yet available in the DOM.
Because of which your code is technically doing this.
undefined.innerHTML
Move the script tag to just above the closing body tag. This will fix the issue since the elements are available in the DOM, when they get stored in the variables.
</main>
<script src="change-template.js"></script>
</body>
if you still want to include your script in the head, the other way around is wrap the code in document.onload which triggers, when the DOM is ready.
document.onload = function(e) {
// your code goes here
};

Related

How to get this jQuery scrollTop() to work...?

Trying to get this script to work (basically want the user to scroll the html page I made, and when it reaches a certain point, to have the text change colour).
Here's what I've done so far:
jQuery(document).ready(function(){
if(jQuery(window).scrollTop() > 20){
jQuery(".changeme").addClass("changeme2");
}
});
The css:
.changeme{
height: 300px;
}
.changeme2{
color: blue;
}
and the HTML:
<html>
<head>
<title>Scroll effect</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://code.jquery.com/jquery-1.12.4.js" integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU=" crossorigin="anonymous"></script>
<script type="text/javascript" src="scroll.js"></script>
</head>
<body>
<div class="changeme">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div class="changeme">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
<div class="changeme">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div>
</body>
</html>
Its something very simple, but I cant get it to work. Any ideas?
The code is working perfectly but you are not detecting the document on the scroll, use below code snippet for reference.
<script>
jQuery(document).ready(function(){
jQuery(document).scroll(function(){
if(jQuery(window).scrollTop() > 20){
jQuery(".changeme").addClass("changeme2");
}
});
});
</script>
First, get an updated version of jQuery if you can. And the shorter $ instead of jQuery can also make it much easier to use jQuery.
To do something when you interact with the page you should listen for events. In this case listen for the scroll event. You can listen for events with the on method.
$(document).ready(function() {
let $window = $(window);
let $changeMe = $('.changeme');
$window.on('scroll', function() {
if ($window.scrollTop() > 20) {
$changeMe.addClass('changeme2');
} else {
$changeMe.removeClass('changeme2');
}
});
});

Hover over one element to make a different element visible

I have been told that this isn't possible via CSS alone and so have turned to javascript.
Using onmouseover but I cannot get the hidden element to appear. I want it so that when hovering over element with ID #a, element with class .excerpt-box appears and then disappears when the mouse is moved away.
Does anyone know where I am going wrong? Thanks
Here's the code I've written so far:
The CSS includes visibility hidden for .excerpt-box.
<div class="ind-circle" id="a" onmouseover="showExcerpt()">
<p class="circle-title"> Read more</p>
</div>
<div class="excerpt-box" id="b">
<h1 class="excerpts-title">This is an example excerpt title...</h1>
<img class="excerpts-fi" src="<?php echo BASE_URL . '/assets/images/water.jpg'; ?>" alt="">
<p class="excerpts-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
function showExcerpt() {
document.getElementByClass('excerpt-box').style.visibility = 'visible';
}
First, the function you are looking for is document.getElementsByClassName.
After this you have to select a particular element by index. See this link.
Better would be this solution:
Grab the id of the div (id='b') and set display to block.
As you can see, the div is display:none; at startup.
function showExcerpt() {
document.getElementById('b').style.display = 'block';
}
.excerpt-box {
display: none;
}
<div class="ind-circle" id="a" onmouseover="showExcerpt()">
<p class="circle-title"> Read more</p>
</div>
<div class="excerpt-box" id="b">
<h1 class="excerpts-title">This is an example excerpt title...</h1>
<img class="excerpts-fi" src="<?php echo BASE_URL . '/assets/images/water.jpg'; ?>" alt="">
<p class="excerpts-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
Your HTML structure allows to do the same via CSS as well.
.excerpt-box goes right after the .ind-circle and can be targeted via adjacent sibling combinator.
.excerpt-box {
display: none;
}
.ind-circle:hover + .excerpt-box {
display: block;
}

insert element on the half div

I try to insert an element ( a div for example ) on the half of the div and just after a double <br /> element
here my code it just an example the div could be longer or smaller
<html>
<head>
<title></title>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script type="text/javascript">
$( document ).ready(function() {
console.log( "ready!" );
var h_div = $('#my_post').height();
});
</script>
</head>
<body>
<div id='container'>
<div id='my_post'>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<br /><br />
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<br /><br />
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<br /><br />
</div>
</div>
</body>
</html>
Should I use position() function in Jquery to do that ?
How about:
$('br:eq(1)', '#my_post').after('<div>whatever ...</div>');
This would insert a div within #my_post after the second <br>
Ok, let's break that down a bit more:
$('br') is a jquery selector that returns a collection of all <br> elements in the document. Since you need only the <br> in a specific container we limit the search to this container: $('br', '#my_post'). Now you have a collection of all <br> elements within the div #my_post. Now we add the filter :eq() which selects only a specific one of the <br> elements. Since :eq() is zero index based we use the number 1 to get the second <br> element.
Now we use the jquery method .after() to insert content after the element we specified with the selector $('br:eq(1)', '#my_post')
You might want to take a look at the jquery docs: http://api.jquery.com/after/

Show hidden div, why code works in FF/Chrome but NOT in IE9?

Consider the following example:
<html>
<head>
</head>
<body>
<style type="text/css">
.hide
{
display: none;
}
</style>
<button style="width:200;height:20;background-color:#B4CFEC;font: bold 10px Verdana" onclick="document.getElementById('CUST_CLASS').classList.remove('hide');" >CUSTOMER DIMENSION</button>
<div class="hide" id="CUST_CLASS">"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</div>
</body>
</html>
I am using the document.getElementById('id').classList.remove('class'); function here.
Should I use a different function? Something Microsoft only?
This is hideous, but removes the specified class, retaining all others:
onclick="document.getElementById('CUST_CLASS').setAttribute('class', document.getElementById('CUST_CLASS').getAttribute('class').replace('hide', ''));"
As commented, IE9 doesn't support classList, so you can either shim it, or fall back to jQuery, which would handle browser compatibility. This is the jQuery equivalent to your code:
$("#CUST_CLASS").removeClass("hide");
However, if your hide class is used for nothing more than toggling visibility, you could simplify even more:
$("#CUST_CLASS").hide();
$("#CUST_CLASS").show();

Trigger opening of a Zurb Foundation Accordion via URL hash link

I'd really like to be able to "activate" / "open" a Zurb Foundation Accordion via the URL with the accordion pane in questions hash.
So like example.com/page#accordion1
Is this possible already with Foundation or is it easy to implement? I honestly haven't got a clue :-/
Thanks in advance for any help given!
You can do this by adding an unique attribute to each accordion title <div class="title" data-ref="panel-1"> In this case I added a data-ref attribute. Then you will need to add some jQuery to look at the hash and if it is a accordion panel, then click that panel.
HTML
<ul class="accordion">
<li class="active">
<div class="title" data-ref="panel-1">
<h5>Accordion Panel 1</h5>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</li>
<li>
<div class="title" data-ref="panel-2">
<h5>Accordion Panel 2</h5>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</li>
<li>
<div class="title" data-ref="panel-3">
<h5>Accordion Panel 3</h5>
</div>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</li>
</ul>​
jQuery
jQuery(function() { // Document ready shorthand
// Get the hash and remove the #
var hash = window.location.hash.replace('#', '');
if (hash != '') {
// Cache targeted panel
$target = $('.title[data-ref="' + hash + '"]');
// Make sure panel is not already active
if (!$target.parents('li').hasClass('active')) {
// Trigger a click on item to change panel
$target.trigger('click');
}
}
});​
View in action
Edit code
One note: When in jsfiddle edit the hash will not work. Need to view in the full mode.
UPDATE
If you want to have a link that opens up a panel and updates hash. You will need to add a specific class to the link. In my example I add panel-btn
HTML
Goto Panel 2
jQuery
$('.panel-btn').click(function(e){
// Get the links href and remove the #
target_hash = $(this).attr('href').replace('#','');
// Click targeted panel
$('.title[data-ref="' + target_hash + '"]').trigger('click');
// Update hash, so that if page is refreshed, target panel will open
window.location.hash = target_hash;
// Stop all default link functionality
return false;
});
Updated jsfiddle view
Updated jsfiddle code
If you are looking for more of a history thing when each panel is clicked. You will need to add a click event to each .title and get its data-ref and change the hash to that, like this:
$('.title').click(function(){
// Get the data-ref
hash = $(this).attr('data-ref');
// Set hash to panels hash
window.location.hash = hash;
});
If you are using Foundation 5:
Foundations Accordion has a custom event click.fndtn.accordion you can use. It will take care of the proper open/closed states:
jQuery(document).ready(function($) {
var hash = window.location.hash;
if (hash != '') {
$('[data-accordion] [href="' + hash + '"]').trigger('click.fndtn.accordion');
}
});
See the example here, it will programatically open the second tab upon page load by detecting a window hash (simulated by a dummy hash in the code):
http://jsfiddle.net/ynyrrm99/
Link to the page without setting the a link to data-tab or any other settings. As of foundation 5.5.1 it will parse the uri with a hash on page load... meaning it doesn't matter how you set the originating link.
Set a variable to the hash in the URL, give the content panel div the same id as in your hash. Then add a class of .active to the panel with the same id as your link.
if(window.location.hash) {
var hash = window.location.hash;
$( hash ).addClass( "active" );
}

Categories

Resources