Problems with javascript event handler - javascript

I'm hoping this doesn't get marked as "duplicate", because I have reviewed several threads and followed the advice I found. I know I'm missing something simple, and need other eyes on this. I'm a newbie, so please bear with me. I am testing a simple button element that I have a click event handler on, but it is not working. It works inline with "onclick", but I am trying to avoid that. The simple html:
<div>
<button id='handler'>Event</button>
</div>
<div id='stringText'>
<h4>Some Description</h4>
<p>
Some more information
</p>
</div>
And the javascript:
<script>
document.getElementById("handler").addEventListener("click", display, true);
function display() {
if (document.getElementById("stringText").style.display === "block") {
document.getElementById("stringText").style.display = "none";
} else {
document.getElementById("stringText").style.display = "block";
}
};
</script>
I have the css that initially sets the "stringText" display as "none". I appreciate any assistance.

Probably your problem is related to the execution of that script while the document is being loaded.
Add this condition stringText.style.display === "" to show/hide the elements correctly.
An alternative is using the event DOMContentLoaded
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOM fully loaded and parsed");
document.getElementById("handler").addEventListener("click", display, true);
function display() {
var stringText = document.getElementById("stringText");
if (stringText.style.display === "block" || stringText.style.display === "") {
stringText.style.display = "none";
} else {
stringText.style.display = "block";
}
};
});
<div>
<button id='handler'>Event</button>
</div>
<div id='stringText'>
<h4>Some Description</h4>
<p>
Some more information
</p>
</div>

Please allow some delay to load the pages using window.onload events
<div>
<button id='handler'>Event</button>
</div>
<div id='stringText'>
<h4>Some Description</h4>
<p>
Some more information
</p>
</div>
<script>
window.onload = function(){
document.getElementById("handler").addEventListener("click", display, true);
};
function display() {
if (document.getElementById("stringText").style.display === "block") {
document.getElementById("stringText").style.display = "none";
} else {
document.getElementById("stringText").style.display = "block";
}
};
</script>

If you make sure and set the initial display property to block it works fine. As an alternative, you could also try using jQuery, as I have in the snippet.
//with jquery
$(document).ready(function() {
$('#handler').on('click', function() {
$('#stringText').toggleClass('hide');
})
})
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button id='handler'>Event</button>
</div>
<div id='stringText'>
<h4>Some Description</h4>
<p>
Some more information
</p>
</div>

Related

Toggle visibility of the current element

I'm trying to write a function toggle_active to show the hidden content on a click, and collapse the content again on one more click. Sadly, it does not work. Could you help me modify it?
function toggle_active(this){
var x = this.nextSibling;
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
};
}
.daccord_b{
display:none;
}
<header class="ca_h" onclick="toggle_active(this);">
<i class="i i-plus ca_hi"></i>
Title
</header>
<div class="had daccord_b">Hidden content</div>
Use method nextElementSibling to return the next element. And it is not necessary to use the if {} operator.
Don't use this for arguments in functions.
The more correct way for your task is method toggle(), which your class uses in css .daccord_b.
function toggle_active(el) {
var x = el.nextElementSibling;
x.classList.toggle("daccord_b");
}
.daccord_b {
display: none;
}
<header class="ca_h" onclick="toggle_active(this);">
<i class="i i-plus ca_hi"></i>
Title
</header>
<div class="had daccord_b">Hidden content</div>
Second solution using style.display.
function toggle_active(el) {
var x = el.nextElementSibling;
x.style.display = x.style.display === 'block' ? 'none' : 'block';
}
.daccord_b {
display: none;
}
<header class="ca_h" onclick="toggle_active(this);">
<i class="i i-plus ca_hi"></i>
Title
</header>
<div class="had daccord_b">Hidden content</div>
js:
function toggle_active(id){
var x = document.getElementById(id);
if (x.style.display === "none" || x.style.display === "") {
x.style.display = "block";
} else {
x.style.display = "none";
};
}
html:
<header class="ca_h" onclick="toggle_active('HiddenContent');">
toggle
</header>
<div class="had daccord_b" id='HiddenContent'>Hidden content</div>
You're having some syntax errors in this code. First, I suggest you name the function arguments something other than this because this is a reserved keyword in JavaScript.
Secondly, I recommend consulting with W3School with such simple problems before reaching out, as most of the time, there is a simple solution :)
Here's a link that solves exactly the problem you're describing.
https://www.w3schools.com/howto/howto_js_collapsible.asp
And, here's an example and how you can achieve this:
let content = document.getElementById("content");
function handleClick() {
if (content.classList.contains("hide")) {
content.classList.remove("hide");
} else {
content.classList.add("hide");
}
}
.my-content {
display: block;
}
.my-content.hide {
display: none;
}
<button onclick="handleClick()">Toggle</button>
<div class="my-content" id="content">Hello, some content</div>
EDIT If you decide to introduce jQuery to your project, you can achieve it even with fever lines of code:
$("[data-collapse]").on('click', function () {
let target = $(this).data('collapse');
$(target).toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-collapse="#content">Clicker</button>
<div id="content">
My Content
</div>
This makes it abstract and reusable, even allowing you to do things like separate containers:
$("[data-collapse]").on('click', function () {
let target = $(this).data('collapse');
$(target).toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-collapse="#target1">Collapse #1</button>
<button data-collapse="#target2">Collapse #2</button>
<div id="target1">
<h1>I'm Target #1</h1>
</div>
<div id="target2">
<h1>I'm target #2</h1>
</div>
It is a good practice to use an Event object in you handler function when you can. Please read this post then try fixing your code accordingly: What exactly is the parameter e (event) and why pass it to JavaScript functions?
More about Event.currentTarget here: https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget
function toggle_active(evt){
var x = evt.currentTarget.nextElementSibling;
x.classList.toggle('daccord_b');
}
.daccord_b {
display: none;
}
<header class="ca_h" onclick="toggle_active(event);">
<i class="i i-plus ca_hi"></i>
Title
</header>
<div class="had daccord_b">Hidden content</div>

Uncaught TypeError: Cannot Read Property 'checked' of null - html checkbox toggle

I am getting an error when attempting to run a function once a checkbox is being checked. The above error appears consistently each time I am attempting to run it. Heres the code:
HTML:
<body>
<header>
<div class="header_container">
<h1>Trivia Quiz</h1>
<p>Welcome to the Trivia Quiz 2020!</p>
<p>The aim of the game is to get as many questions correct as possible!<br> The topics range from film to geography, so good luck!</p>
<div class="header_settings" id="header_settings">
<input type="checkbox" id="checkbox" onclick="TimeToggle()">
<label for="TimeToggle">Time Limit</label><br>
<input type="text" id="Timer" name="Timer" placeholder="Seconds" id="header_input">
</div>
<button>Start</button>
</div>
</header>
</body>
And Javascript (stored externally, linked in the head of the HTML document.):
var header_input = document.getElementById("header_input");
var header_settings = document.getElementById("header_settings");
var checkbox = document.getElementById("checkbox");
function TimeToggle() {
if (checkbox.checked) {
header_settings.style.height = "3%";
setTimeout(function () {
header_input.style.display = "none";
}, 500);
} else {
header_settings.style.height = "10%";
setTimeout(function () {
header_input.style.display = "block";
}, 500);
}
}
The code is intended to toggle the height of the div named "header_settings", and the display setting of the input named "header_input" depending on whether the checkbox is checked.
I would appreciate any pointers regarding how this is not working, I have tried a lot. Thanks :)
Is this what you are trying to do ? You can use an onchange function and pass this as an argument and check if in your toggle function if input is checked or unchecked.
Also, you have had two id selectors on your input which is not possible.
In addition, please ensure that your scripts.js is loading just added before the </body> end tag
Add this code as your HTML input
<input type="checkbox" id="checkbox" onchange="TimeToggle(this)">
Live Working Demo:
function TimeToggle(el) {
var header_input = document.getElementById("header_input");
var header_settings = document.getElementById("header_settings");
var checkbox = document.getElementById("checkbox");
if (el.checked) {
header_settings.style.height = '50px';
setTimeout(function() {
header_input.style.display = "none";
}, 500);
} else {
header_settings.style.height = '100px';
setTimeout(function() {
header_input.style.display = "block";
}, 500);
}
}
<body>
<header>
<div class="header_container">
<h1>Trivia Quiz</h1>
<p>Welcome to the Trivia Quiz 2020!</p>
<p>The aim of the game is to get as many questions correct as possible!<br> The topics range from film to geography, so good luck!</p>
<div class="header_settings" id="header_settings">
<input type="checkbox" id="checkbox" onchange="TimeToggle(this)">
<label for="TimeToggle">Time Limit</label><br>
<input type="text" name="Timer" placeholder="Seconds" id="header_input">
</div>
<button>Start</button>
</div>
</header>
</body>
Your problem is a very common one. You are trying to get the html elements using document.get... before the DOM has loaded. You need to wrap those document fetches in the onload listener for the window:
let checkbox;
window.onload = function() {
checkbox = document.getElementById();
};
function TimeToggle() {//...}
Place the external JS to at the end. Just before</body>. And your problem will be solved.
Somewhat like
<body>
<!--Your HTML content here-->
<script src = "External Js.js"></script>
</body>

Toggle display of an an element when you click on another element

I have a p element and a hidden pre element. I want to make it so that when you click on a p element with (for example) id/class = "p1", it changes the display of the pre element with (for example) id/class = "pre1".
This is my javascript code :
var p = 1;
setInterval(function() {
if(p <= document.querySelectorAll(".show").length) {
document.getElementById("display-pre"+p).onclick = function() {
console.log(p);
if(document.getElementById("display-pre-a"+p).style.display == '') {
document.getElementById("display-pre-a"+p).style.display = 'block';
} else if(document.getElementById("display-pre-a"+p).style.display == 'block') {
document.getElementById("display-pre-a"+p).style.display = 'none';
}
};
p++;
if(p > document.querySelectorAll(".show").length) {p = 1;}
}
}, 100);
This code kind of works but not really. It sometimes changes other elements and sometimes does nothing.
This is my full javascript code : https://pastebin.com/wEwdKKLy
This is my html :
<div id="test-div">
<input type="text" id="search"/>
<button type="submit" onclick="query()">Submit</button>
<button type="submit" onclick="newInput()">New</button>
<button type="submit" onclick="remove()">Delete</button>
<button type="submit" onclick="deleteAll()">Delete All</button>
<div class="query-div"><p class="query-p">Test-a</p></div>
<div class="query-div"><p class="query-p">Test-b</p></div>
<div class="query-div"><p class="query-p">Test-ba</p></div>
<p id="query-show0">TEST-SHOW</p>
<p id="child"></p>
</div>
Note : elements with class "show" have display none
I tried doing this with jquery but I'm just began learning jquery yesterday and it didn't work (I had the same problem as this).
Jquery code I tried : https://pastebin.com/cBisCmEZ
Thank you for your help.
Here is the solution for you
$("p[data-id]").on("click", function() {
var idFound = $(this).data("id");
$("[data-pre='"+ idFound +"']").toggleClass("show");
});
pre {
display:none;
}
.show {
display:block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p data-id="p1">This is the paragraph</p>
<pre data-pre="p1">This is the pre<pre>
I recommend using a button element for anything you click so that it stays accessible.

How do you properly write onclick events in JavaScript?

I'm trying to use an onclick event with an anchor tag that will change the innerHTML of another element on the page. I'm not sure what I'm doing wrong, so all the code I'm using is below. I hope you guys can point out my mistake and tell me what it was I misunderstood. The JavaScript file is included after the body, but you can see that on the JSfiddle here. So, when I click Settings, I want the BookmarkList div to show it's own HTML code, and the same for Home. The BookmarkList div will be the center of attention for this site. I'm just not sure what I'm doing wrong for this.
HTML:
<body id="bodyBG">
<div class="wrapper">
<div class="box header">
Header
</div>
<div class="box content">
<div class="box subcontent1">
<div class="sdfgsdfgsdfg"><input id="categoryName" placeholder="Category Name"></input></div>
<div class="sdfgsdfg"><input id="urlLink" placeholder="Site Address"></input></div>
<div class="sdfgsddfg"><input id="bookmarkName" placeholder="Bookmark Name"></input></div>
<div><button>Save</button></div>
<hr>
<input placeholder="Search Bookmarks"></input>
<button>Search</button>
</div>
<div class="box subcontent2">
Settings
<hr>
Home
Back
Forwards
</div>
<div id="bookmarkList" class="box subcontent3 bookmark-list">
</div>
</div>
<div class="box footer">Footer</div>
</div>
<script src="assets/js/bookmark-action-script.js"></script>
</body>
JavaScript:
var settingsNav = document.getElementById('settingsNav');
var homeNav = document.getElementById('homeNav');
var changeThis = document.getElementById("bookmarkList");
function myFunction(this) {
if (this === settingsNav) {
changeThis.innerHTML = "<h3>Bookmarks</h3><hr>";
}
else if (this === homeNav) {
changeThis.innerHTML = "<h3>Bookmarks</h3><hr><p>Store all your bookmarks here!</p><ul><li>An secure storage means for your privacy needs!</li><li>24/7 Availability</li></ul>";
}
else (this != settingsNav | homeNav) {
changeThis.innerHTML = "Nothing to see here!";
}
};
document.getElementById("settingsNav").addEventListener("click");
document.getElementById("homeNav").addEventListener("click");
The Solution:
I always add the solution that was appropriate for my problems, so future observers can see what issue I had and what the solution was. My issue was not adding the function to my eventlistener. You do not need to specify onclick events inside the HTML code if you specify event listeners with accompanying functions in your JavaScript code. But without the functions tied to the eventlisteners, nothing will happen. I understand that now.
var settingsNav = document.getElementById('settingsNav');
var homeNav = document.getElementById('homeNav');
var changeThis = document.getElementById("bookmarkList");
function myFunction(event) {
var el = this;
if (el === settingsNav) {
changeThis.innerHTML = "<h3>Bookmarks</h3><hr>";
} else if (el === homeNav) {
changeThis.innerHTML = "<h3>Bookmarks</h3><hr><p>Store all your bookmarks here!</p><ul><li>A secure storage means for your privacy needs!</li><li>24/7 Availability</li></ul>";
} else if (el != settingsNav || homeNav) {
changeThis.innerHTML = "Nothing to see here!";
}
};
document.getElementById("settingsNav").addEventListener("click", myFunction);
document.getElementById("homeNav").addEventListener("click", myFunction);
Remove attribute event handlers from HTML. Change function (this) to function (event). You did not add an event handler at.addEventListener()call, where you can passmyFunction` as a reference to to function to call when event is dispatched.
OR in JavaScript should be || instead of | at second else..if
Note, <input> element is self-closing, </input> is invalid HTML.
<body id="bodyBG">
<div class="wrapper">
<div class="box header">
Header
</div>
<div class="box content">
<div class="box subcontent1">
<div class="sdfgsdfgsdfg"><input id="categoryName" placeholder="Category Name"></div>
<div class="sdfgsdfg"><input id="urlLink" placeholder="Site Address"></div>
<div class="sdfgsddfg"><input id="bookmarkName" placeholder="Bookmark Name"></div>
<div><button>Save</button></div>
<hr>
<input placeholder="Search Bookmarks">
<button>Search</button>
</div>
<div class="box subcontent2">
Settings
<hr>
Home
Back
Forwards
</div>
<div id="bookmarkList" class="box subcontent3 bookmark-list">
</div>
</div>
<div class="box footer">Footer</div>
</div>
<script>
var settingsNav = document.getElementById('settingsNav');
var homeNav = document.getElementById('homeNav');
var changeThis = document.getElementById("bookmarkList");
function myFunction(event) {
var el = this;
if (el === settingsNav) {
changeThis.innerHTML = "<h3>Bookmarks</h3><hr>";
} else if (el === homeNav) {
changeThis.innerHTML = "<h3>Bookmarks</h3><hr><p>Store all your bookmarks here!</p><ul><li>An secure storage means for your privacy needs!</li><li>24/7 Availability</li></ul>";
} else if (el != settingsNav || homeNav) {
changeThis.innerHTML = "Nothing to see here!";
}
};
document.getElementById("settingsNav").addEventListener("click", myFunction);
document.getElementById("homeNav").addEventListener("click", myFunction);
</script>
</body>
Your code works fine in Chrome by fixing couple of syntax errors.
update else to else if
else if (clk != settingsNav | homeNav)
update this parameter to something else in myFunction
function myFunction(clk)
no need to add event since you called myFunction in onclick, so remove:
document.getElementById("settingsNav").addEventListener("click");
document.getElementById("homeNav").addEventListener("click");
Somehow it didn't work in jsfiddler.

formatting lose when showing a previously hidden div

So my webpage shows a new div when you click on an existing div. This hidden div has exactly the same formatting as the existing visible div, but when it is made to appear, all of that formatting is lost and I can't quite work out why. Here's the code:
<div id="visible" class="visibleDiv" onclick="expandItem()">
Stuff here
</div>
<div id="invisible" class="hiddenDiv">
Stuff here
</div>
And here's my JavaScript:
function expandItem() {
if (document.getElementById("invisible").style.display == '') {
document.getElementById("invisible").style.display = 'block';
}
Any help is greatly appreciated!
Try This
<div id="visible" class="visibleDiv" onclick="expandItem()">
Stuff here
</div>
<div id="invisible" style="display:none;" class="hiddenDiv">
Stuff here
</div>
And make change in javascript
function expandItem() {
if (document.getElementById("invisible").style.display == 'none') {
document.getElementById("invisible").style.display = 'block';
}
yeah this should fetch the solution
function expandItem() {
if (document.getElementById("invisible").style.display == 'none' || document.getElementById("invisible").style.display == '') {
document.getElementById("invisible").style.display = 'block';
}
this line
document.getElementById("invisible").style.display == ''
is irrelavent , the main code to be executed is
document.getElementById("invisible").style.display == 'none'

Categories

Resources