2

I'm making a simple data url maker and I'm wondering why the code for my clear button isn't working, when other sections with the exact same code are working.

function go() {
  var string = document.getElementById("input").value;
  var encodedString = btoa(string);
  document.getElementById("output").value = "data:text/html;base64," + encodedString;
}

function copy() {
  var copyText = document.getElementById("output");
  copyText.select();
  copyText.setSelectionRange(0, 99999)
  document.execCommand("copy");
}

function clear() {
  document.getElementById("output").value = "";
  document.getElementById("input").value = "";
}

var input = document.getElementById("input");
input.addEventListener("keyup", function(event) {
  if (event.keyCode === 13) {
    event.preventDefault();
    document.getElementById("go").click();
  }
});
<p>
<input id="input" type="text" placeholder="HTML here" value="">
<button onclick="clear()">&#x1f7aa;</button>
<button id="go" onclick="go()">Convert</button>
<p>
<input type="text" placeholder="Output here" id="output">
<button onclick="copy()">Copy text</button>

Near the bottom, the function called 'clear' isn't working. When I hit the button which calls that function, nothing happens.

However, I'm using the exact same code in the function 'go', which is working.

6
  • Why are you using ancient JS and HTML? Don't use on... html attributes, use addEventListener in JS context. Also, don't use <br>, we have CSS, you're using it, so add margin/padding where appropriate. Commented Mar 22, 2020 at 1:46
  • 1
    Your code will work if you use a function name other than "clear", like maybe "clearInputs". Commented Mar 22, 2020 at 1:47
  • Thank you, @Pointy! I've changed it and it works now. Commented Mar 22, 2020 at 1:49
  • @Pointy I suppose clear is a global JavaScript function? Commented Mar 22, 2020 at 1:49
  • 1
    The namespace in the browser is polluted, and even moreso when you use "onfoo" event handlers. This is one of the good reasons to stop assigning event handlers that way. Commented Mar 22, 2020 at 1:57

2 Answers 2

3

When you use an inline handler, the handler is wrapped inside two with statements: one for the element the handler is on, and one for the document. Your code is doing something like:

with (document) {
  with (button) {
    clear();
  }
}

But clear exists on the document:

console.log(document.clear);

So, when you reference an identifier named clear, it never gets out of the withs, so the function that you called clear never runs.

Use a different variable name, like clearInputAndOutput:

function go() {
  var string = document.getElementById("input").value;
  var encodedString = btoa(string);
  document.getElementById("output").value = "data:text/html;base64," + encodedString;
}

function copy() {
  var copyText = document.getElementById("output");
  copyText.select();
  copyText.setSelectionRange(0, 99999)
  document.execCommand("copy");
}

function clearInputAndOutput() {
  document.getElementById("output").value = "";
  document.getElementById("input").value = "";
}
var input = document.getElementById("input");
input.addEventListener("keyup", function(event) {
  if (event.keyCode === 13) {
    event.preventDefault();
    document.getElementById("go").click();
  }
});
button {
  font-family: 'Baloo 2', cursive;
  background-color: lightgrey;
}

input {
  font-family: 'Baloo 2', cursive;
}
<link href="https://fonts.googleapis.com/css?family=Baloo+2&display=swap" rel="stylesheet">
<input id="input" type="text" size="160" placeholder="HTML here" value="">
<button onclick="clearInputAndOutput()">&#x1f7aa;</button>
<button id="go" onclick="go()">Convert</button>
<br><br>
<input type="text" placeholder="Output here" id="output" size="160">
<button onclick="copy()">Copy text</button>

But it would be far better to attach the event handler properly using Javascript. Inline handlers have too many scoping and escaping problems, and are best avoided. Use addEventListener instead, and you won't have to worry about name collisions or global variable problems:

const [clearBtn, goBtn, copyBtn] = document.querySelectorAll('button');
clearBtn.addEventListener('click', () => {
  document.getElementById("output").value = "";
  document.getElementById("input").value = "";
});
goBtn.addEventListener('click', () => {
  var string = document.getElementById("input").value;
  var encodedString = btoa(string);
  document.getElementById("output").value = "data:text/html;base64," + encodedString;
});
copyBtn.addEventListener('click', () => {
  var copyText = document.getElementById("output");
  copyText.select();
  copyText.setSelectionRange(0, 99999)
  document.execCommand("copy");
});

var input = document.getElementById("input");
input.addEventListener("keyup", function(event) {
  if (event.keyCode === 13) {
    event.preventDefault();
    document.getElementById("go").click();
  }
});
button {
  font-family: 'Baloo 2', cursive;
  background-color: lightgrey;
}

input {
  font-family: 'Baloo 2', cursive;
}
<link href="https://fonts.googleapis.com/css?family=Baloo+2&display=swap" rel="stylesheet">
<input id="input" type="text" size="160" placeholder="HTML here" value="">
<button>&#x1f7aa;</button>
<button id="go">Convert</button>
<br><br>
<input type="text" placeholder="Output here" id="output" size="160">
<button>Copy text</button>

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

3 Comments

Thank you for the answer! I was really confused. I have one more question though: When I run my code on this page, or on another hosting page everything works. However, when I put the code onto a base64 encoded data: url, the buttons suddenly stop working. Why might this be?
See the snippet in your question - it doesn't look to work here (because document.clear exists). What hosting page does it work on, do you have a link so I can see for myself? Seems pretty odd, I'd expect it to always fail (or always succeed), given the same browser.
Yeah, @CertainPerformance. I put the code into a site called w3schools.com, where it worked, but when I encoded it into base64 and made it into a data: url, none of the JS worked which is weird. It doesn't matter that much, because I'm now hosting it on Github, but here's a link if you're curious. (If you want to see the data url version, just copy the code on the right into the box in the top left.)
2

As a solution, you can change the function name "clear" to something else. It may be mistaken with default functions of JavaScript with the same name, e.g. document.clear

Comments

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.