-3

<p>2 + 4 = <span onclick='this.document.getElementsByTagName("p").item(0).innerHTML = eval(2+4)'>답</span></p>
<p>4 * 20 + 64 = <span onclick='this.document.getElementsByTagName("p").item(1).innerHTML = eval(4*20+64)'>답</span></p>
<p>20 / 5 - 8 * 2 = <span onclick='this.document.getElementsByTagName("p").item(2).innerHTML = 20/5 - 8*2'>답</span></p>

I want to click “답” to output answers to mathematical expressionsbut, doesn't work

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 3
    **Danger**: `eval` is inefficient, hard to debug, very dangerous if it ever gets near user input, and *utterly pointless* for doing what you are doing here. – Quentin Jun 16 '20 at 10:22
  • Make this in more steps: create a function as a click handler and call it with onclick. Put a `console.log("it works")` in the function and nothing else. Open the console (most browsers: right click -> inspect element -> select the console tab) and see if the message appears when you click. After that add your logic step by step. – Vlad V Jun 16 '20 at 10:23
  • Span elements are not designed to be interactive controls (e.g. screen readers don't announce them as things you can click on and they don't appear in the document tab order by default). If you want something to click on to trigger some JavaScript then **use a button**, that's what they are designed for. – Quentin Jun 16 '20 at 10:23

3 Answers3

0

document is a global, not a property of a span element. Don't use this.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

You just need to remove the keyword this from the this.documentdocument.getElementsByTagName.

Why?

document is a global variable representing any web page loaded in the browser and serves as an entry point into the web page's content, which is the DOM tree. A span is an Html element that is stored in the DOM tree.

By using the this keyword, you are trying to access a property of span, and not to the document variable.

Follows a fully working example.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>DOM 객체 변경 - 내용 변경</title>
    </head>

    <body>
        <h1>계산해봅시다.</h1>
        <hr>

        <p>2 + 4 = <span onclick='document.getElementsByTagName("p").item(0).innerHTML = eval(2+4)'>답</span></p>
        <p>4 * 20 + 64 = <span onclick='document.getElementsByTagName("p").item(1).innerHTML = eval(4*20+64)'>답</span></p>
        <p>20 / 5 - 8 * 2 = <span onclick='document.getElementsByTagName("p").item(2).innerHTML = 20/5 - 8*2'>답</span></p>
    </body>
</html>

Instead of getting the respective dom element from the dom tree, you can use the span properties and only change the span using value the innerHtml or textContent like this:

<!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>DOM 객체 변경 - 내용 변경</title>
        </head>

        <body>
            <h1>계산해봅시다.</h1>
            <hr>

            <p>2 + 4 = <span onclick='this.innerHTML = eval(2+4)'>답</span></p>
            <p>4 * 20 + 64 = <span onclick='this.innerHTML = eval(4*20+64)'>답</span></p>
            <p>20 / 5 - 8 * 2 = <span onclick='this.innerHTML = 20/5 - 8*2'>답</span></p>
        </body>
    </html>

Check out here the diferences between innerHtml and textContent

Ricardo Rocha
  • 14,612
  • 20
  • 74
  • 130
0

In a onclick attribute, this represents the target element (of the event), so it is not window, but the clicked span.

So you could do just this.innerHTML = 2+4, ...etc. In fact, I would prefer using this.textContent here, as you don't plan to inject HTML encoding, but plain text.

BTW: no eval is needed.

<p>2 + 4 = <span onclick='this.textContent = 2+4'>답</span></p>
<p>4 * 20 + 64 = <span onclick='this.textContent = 4*20+64'>답</span></p>
<p>20 / 5 - 8 * 2 = <span onclick='this.textContent = 20/5 - 8*2'>답</span></p>

And to make it more dynamic, you could use eval, so that you don't need to repeat the formula:

document.addEventListener("click", function(e) {
    if (e.target.className == "calc") {
        let formula = e.target.parentNode.textContent.split("=")[0];
        e.target.textContent = eval(formula);
    }
});
<p>2 + 4 = <span class="calc">답</span></p>
<p>4 * 20 + 64 = <span class="calc">답</span></p>
<p>20 / 5 - 8 * 2 = <span class="calc">답</span></p>

Note that the JavaScript in this case needs to be in script tag.

trincot
  • 317,000
  • 35
  • 244
  • 286