0

I am working on a page which is using Vanilla JavaScript and unfortunately I am only knowledgeable with jQuery. I have a function attached to my anchor tags to toggle additional content and I want to change aria-expanded from false to true on the anchor when it is clicked and then back to false when it is clicked again.

Here's what I've tried:

<script type="text/javascript">
    function toggleMe(a) {
        var t = this;
        var e = document.getElementById(a);
        if (!e) return true;
        if (e.style.display == "none") {
            t.setAttribute('aria-expanded', 'true');
            e.style.display = "block"
        }
        else {
            t.setAttribute('aria-expanded', 'false');
            e.style.display = "none"
        }
        return true;
    }
</script>

<a onclick="return toggleMe('content1')" aria-expanded="false">Expand content</a>

<div style="display: none" id="content1">
  <p>Expanded content here</p>
</div>

2
  • Did you mean you're not knowledgeable with jQuery? Commented Aug 1, 2017 at 16:21
  • 1
    this refers to the window object, because you are using "old-school" event handling via HTML attributes. Either pass this in as a parameter as well, use bind as suggested in an answer ... or maybe use at least "vanilla JS" event handler binding, meaning addEventListener & Co. ... Commented Aug 1, 2017 at 16:23

2 Answers 2

2

Your issue is in this line:

var t = this;

By default the value of this is the window object. You can pass the value directly in the inline definition like:

<a onclick="return toggleMe('content1', this)" aria-expanded="false">Expand content</a>

function toggleMe(a, currEle) {
    var t = currEle;
    var e = document.getElementById(a);
    if (!e) return true;
    if (e.style.display == "none") {
        t.setAttribute('aria-expanded', 'true');
        e.style.display = "block"
    }
    else {
        t.setAttribute('aria-expanded', 'false');
        e.style.display = "none"
    }
    return true;
}
<a onclick="return toggleMe('content1', this)" aria-expanded="false">Expand content</a>

<div style="display: none" id="content1">
    <p>Expanded content here</p>
</div>

Sign up to request clarification or add additional context in comments.

Comments

1

As per your current implementation this in the function toggleMe() refers to window not to current element(anchor).

You can use .bind() to set the context

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

<a onclick="return toggleMe.bind(this)('content1')" aria-expanded="false">Expand content</a>

OR, .call()

The call() method calls a function with a given this value and arguments provided individually.

<a onclick="return toggleMe.call(this, 'content1')" aria-expanded="false">Expand content</a>

<script type="text/javascript">
    function toggleMe(a) {
        var t = this;
        var e = document.getElementById(a);
        if (!e) return true;
        if (e.style.display == "none") {
            t.setAttribute('aria-expanded', 'true');
            e.style.display = "block"
        }
        else {
            t.setAttribute('aria-expanded', 'false');
            e.style.display = "none"
        }
        return true;
    }
</script>

<a onclick="return toggleMe.bind(this)('content1')" aria-expanded="false">Expand content</a>

<div style="display: none" id="content1">
  <p>Expanded content here</p>
</div>

1 Comment

Thank you for your answer and detailed explanation, appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.