简体   繁体   中英

Get ID of Clicked Link & Change Its Class

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.

Example

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]);

Demo

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM