I put together a single-page "web app" using HTML, CSS, and JavaScript. There's 3 links, when a user clicks a link it shows content for that link and hides content for the other links. When a link is clicked it should change to bold but it doesn't. I did some research and found that I should use:
// Bold selected link
this.className = "selectedLink";
within my function to get the clicked link's ID but it is not working. Why can't I get the ID of the clicked link within my function? I want to keep my HTML, CSS, and JavaScript separate.
Fiddle: http://jsfiddle.net/ZYEUV/
<style>
.selectedLink {
font-weight: bold;
}
</style>
<p><a href="#" id="linkPage1" class="selectedLink">Example Page 1</a> | <a href="#" id="linkPage2">Example Page 2</a> | <a href="#" id="linkPage3">Example Page 3</a></p>
<div id="page1">
<h1>Example Page 1</h1>
<p>Content goes here.</p>
</div>
<div id="page2">
<h1>Example Page 2</h1>
<p>Content goes here.</p>
</div>
<div id="page3">
<h1>Example Page 3</h1>
<p>Content goes here.</p>
</div>
<script>
var pages = [page1, page2, page3];
// Displays page and hides all other pages
function goToPage(pageID) {
console.log(pageID);
// Display page
for (var i = 0; i < pages.length; i++) {
if (pageID == pages[i].id) {
// Show page
pages[i].style.display = "block";
// Bold selected link
this.className = "selectedLink";
} else {
console.log(pages[i]);
// Hide page
pages[i].style.display = "none";
// Unbold unselected link
this.className = "selectedLink";
}
}
}
linkPage1.onclick = function () {
goToPage("page1");
};
linkPage2.onclick = function () {
goToPage("page2");
};
linkPage3.onclick = function () {
goToPage("page3");
};
goToPage("page1");
</script>
You miss something :) http://jsfiddle.net/ZYEUV/3/
JS:
var pages = [page1, page2, page3];
var links = [linkPage1, linkPage2, linkPage3];
// Displays page and hides all other pages
function goToPage(pageID) {
console.log(pageID);
// Display page
for (var i = 0; i < pages.length; i++) {
if (pageID == pages[i].id) {
// Show page
pages[i].style.display = "block";
// Bold selcted link
links[i].className = "selectedLink";
} else {
console.log(pages[i]);
// Hide page
pages[i].style.display = "none";
// Unbold unselected link
links[i].className = "";
}
}
}
linkPage1.onclick = function () {
goToPage("page1");
};
linkPage2.onclick = function () {
goToPage("page2");
};
linkPage3.onclick = function () {
goToPage("page3");
};
goToPage("page1");
The problem you were having setting the className is related to how the function is being called.
In your event handler for the click, the this
context is the anchor. However, when you call goToPage()
the this
context is window
.
You could remedy that by changing the call to goToPage
to
goToPage.call(this, "page1");
However, you then bump into the next issue which is that this
now refers to the recently clicked anchor. Because of that, there was no way, with your current logic, to remove the selectedLink
class.
The quick solution is to refactor your code a bit to match the pattern you have already established by using the pages array.
Script:
var pages = [page1, page2, page3];
var links = [linkPage1, linkPage2, linkPage3];
// Displays page and hides all other pages
function goToPage(pageID, evt) {
console.log(pageID);
// Display page
for (var i = 0; i < pages.length; i++) {
if (pageID == pages[i].id) {
// Show page
pages[i].style.display = "block";
// Bold selcted link
links[i].className = "selectedLink";
} else {
console.log(pages[i]);
// Hide page
pages[i].style.display = "none";
// Unbold unselected link
links[i].className = "";
}
}
}
Alternate Approach
By changing your markup a bit, you can reduce some of the repetition in your code and simplify adding new pages.
In your HTML, add a data-page attribute to your links:
<a href="#" id="linkPage1" class="selectedLink" data-page="page1">…</a>
With that change, your script can be refactored to something like this:
// List of links with a data-page attribute
var links = document.querySelectorAll("a[data-page]");
var pages = {};
function clickHandler() {
var page = this.dataset.page;
for(var i = 0; i < links.length; ++i) {
links[i].className = "";
pages[links[i].dataset.page].style.display = "none";
}
this.className = "selectedLink";
pages[page].style.display = "block";
}
// Setup handlers in a loop (maybe use addEventListener here instead)
// Store map of pages by id
for(var i = 0; i < links.length; ++i) {
links[i].onclick = clickHandler;
pages[links[i].dataset.page] = document.getElementById(links[i].dataset.page);
}
// Call the click handler with the context of the link to initialize
links[0].onclick.call(links[0]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.