Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialSeth Stephenson
8,050 PointsWeird question about some extra code I added (conditional ternary operator) and an unexpected behavior
I added this ternary to the function that will, addition to the div id "toggleList" display being set to none, change the button text to "Reveal List". When clicked again the "toggleList" display will be set to "block" and the button text will be set to "Hide List". The functionality works as expected, but only after you click the button once and it does nothing. In pursuit of clarity, you click the button once, nothing happens. Click the button again and the "toggleList" div display is set to none and the button text is set to "Reveal List". Click the button again and everything resets to its previous state. The button will continue to work as expected until the page is refreshed.
I added an inline style to the index.html file:
<button id="toggleList" style="display:block">Hide List</button>
I then removed the inline style and added an additional condition to my ternary and this fixed the extra click behavior. I've included both versions of the app.js file bellow. Can anyone clue me in to what's causing this behavior? I am boggled, but would really like to figure this out. Thanks for any help!
app.js file with the extra click:
const toggleList = document.getElementById('toggleList');
const listDiv = document.querySelector('.list');
const input = document.querySelector('input');
const p = document.querySelector('p.description');
const button = document.querySelector('button.description');
toggleList.addEventListener('click', () => {
(listDiv.style.display == 'block')
?
(listDiv.style.display = 'none')
&&
(document.getElementById('toggleList').textContent = 'Reveal List')
:
(listDiv.style.display = 'block')
&&
(document.getElementById('toggleList').textContent = 'Hide List');
});
button.addEventListener('click', () => {
p.innerHTML = input.value + ':';
});
app.js file with expected behavior:
const toggleList = document.getElementById('toggleList');
const listDiv = document.querySelector('.list');
const input = document.querySelector('input');
const p = document.querySelector('p.description');
const button = document.querySelector('button.description');
toggleList.addEventListener('click', () => {
(listDiv.style.display == '') || (listDiv.style.display == 'block')
?
(listDiv.style.display = 'none')
&&
(document.getElementById('toggleList').textContent = 'Reveal List')
:
(listDiv.style.display = 'block')
&&
(document.getElementById('toggleList').textContent = 'Hide List');
});
button.addEventListener('click', () => {
p.innerHTML = input.value + ':';
});
And, here is the entire index.html file w/o the inline style (this is used to achieve the expected behavior):
<!DOCTYPE html>
<html>
<head>
<title>JavaScript and the DOM</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1 id="myHeading">JavaScript and the DOM</h1>
<p>Making a web page interactive</p>
<button id="toggleList">Hide List</button>
<div class="list">
<p class="description">Things that are purple:</p>
<input type="text" class="description">
<button class="description">Change List Description</button>
<ul>
<li>grapes</li>
<li>amethyst</li>
<li>lavender</li>
<li>plums</li>
</ul>
</div>
<script src="app.js"></script>
</body>
</html>
And, just in case, here is the style.css file:
@import 'https://fonts.googleapis.com/css?family=Lato:400,700';
body {
color: #484848;
font-family: 'Lato', sans-serif;
padding: .45em 2.65em 3em;
line-height: 1.5;
}
h1 {
margin-bottom: 0;
}
h1 + p {
font-size: 1.08em;
color: #637a91;
margin-top: .5em;
margin-bottom: 2.65em;
padding-bottom: 1.325em;
border-bottom: 1px dotted;
}
ul {
padding-left: 0;
list-style: none;
}
li {
padding: .45em .5em;
margin-bottom: .35em;
display: flex;
align-items: center;
}
input,
button {
font-size: .85em;
padding: .65em 1em;
border-radius: .3em;
outline: 0;
}
input {
border: 1px solid #dcdcdc;
margin-right: 1em;
}
div {
margin-top: 2.8em;
padding: 1.5em 0 .5em;
border-top: 1px dotted #637a91;
}
p.description,
p:nth-of-type(2) {
font-weight: bold;
}
/* Buttons */
button {
color: white;
background: #508abc;
border: solid 1px;
border-color: rgba(0, 0, 0, .1);
cursor: pointer;
}
button + button {
margin-left: .5em;
}
p + button {
background: #52bab3;
}
.list button + button {
background: #768da3;
}
.list li button + button {
background: #508abc;
}
li button:first-child {
margin-left: auto;
background: #52bab3;
}
.list li button:last-child {
background: #768da3;
}
li button {
font-size: .75em;
padding: .5em .65em;
}
Thanks again!
1 Answer
Steven Parker
231,271 PointsWhile block mode is the default for the element, the "display" style is not initially set to "block". The original setting is just empty.
So your first click might not make any visible change, but it sets the display mode explicitly to "block". Then the subsequent clicks toggle the mode as expected.
Adding the extra test for an empty string or presetting the value to "block" is what fixed the issue. You could also fix the issue by toggling between "" and "none" instead of "block" and "none".
Dave StSomeWhere
19,870 PointsDave StSomeWhere
19,870 PointsHi Seth,
Please check the Markdown Cheatsheet below for posting your code .
Also, if you post your html and css it will be easier to evaluate your code.
Thanks,