1

Okay, so I am trying to make a quiz where you enter some code and the quiz executes the code to see if what you typed is the same as the answer.

Here is the code and this is how the webpage looks like:

questions = "PRINT HELLO"
document.getElementById("Question").innerHTML = questions
function check(){
  document.getElementById("answertext").innerHTML = eval(document.getElementById("answerbox").value)
 
}
#answerbox{
  width:100%;
  height:500px;
  font-size:25px;
}
<h1>QUIZZZ</h1>

<h2 id = Question>JAVASCRIPT CONSOLE AND EXERCISES</h1>

<h1 id = "hi"></h1>

<textarea rows="4" cols="50" id = "answerbox">
//put your answer here
</textarea>
<textarea rows= '4' cols = "50" id = "answertext">lol</h1>
</textarea>
<input type = "submit" onclick = "check()">

Run the code to see I want the user to enter a document.write() statement inside the textbox, and have the evaluated code to be shown in the smaller multiline text box.

Try to put a document.write() statement in the textbox and run it. You should see a new page instead of the answer written in the text box.

I know that document.write is a bad practice to output things in javascript, and I know that you can edit raw HTML, but is there any other way a user can print a message without doing any of these choices?

Code_Ninja
  • 1,633
  • 1
  • 12
  • 32
Abhiraam Eranti
  • 185
  • 1
  • 12

3 Answers3

2

Don't use eval.

Using eval is considered to be a bad practice. Read more for Why here. You can ask your user to just return the answer using a return statement as shown below, instead of asking them to do something complicated like document.write().

// Ask them to do this:
var codeFromTheAnswerBox = "var answer = 'HELLO'; return answer;"
// instead of this:
// var codeFromTheAnswerBox = "var answer = 'HELLO'; document.write(answer)";

// execute user's code
var code = new Function(codeFromTheAnswerBox);
var returnValue = code();

// Now do whatever you want to do with the answer like the following
alert("Your answer is " + returnValue);
UtkarshPramodGupta
  • 5,248
  • 4
  • 21
  • 44
  • but `new Function("document.write('the answer...')")` does not return any usable thing and all of elements will be lost; exactly similar using `eval` method. is it right? – Hassan Sadeghi Aug 14 '18 at 05:52
  • doing `var functionName = new Function("#some code string")` would just create a new function by the name `functionName` with the given code string. It is like doing `functionName() { // Code from your code string }`. This is the preffered way of executing a string code over using eval function. @HassanSadeghi – UtkarshPramodGupta Aug 14 '18 at 06:56
  • Yes; I worked with it before. But I mean, despite the use of it, this problem will continue to exist. after calling the created function with `new Function(...)`, if answer equals to `document.write('TheExecutedAnswer')`, all elements will be replace with `TheExecutedAnswer` and all elements will be lost. thanks. – Hassan Sadeghi Aug 14 '18 at 07:24
  • @HassanSadeghi Read the first 4 lines of my code carefully and you'll know what I'm recommending to do. :) – UtkarshPramodGupta Aug 14 '18 at 07:28
  • Okay. Thank you dear friend. – Hassan Sadeghi Aug 14 '18 at 07:43
  • This works very well. +1 for warning me for the eval(). But can you do the dangerous stuff that you normally do for eval with functions() – Abhiraam Eranti Aug 14 '18 at 19:59
0

You can use .append instead of document.write()

document.body.append("Hello World!", document.createElement('p'));

If you go to the Console tab of the DevTools in your browser, you can type javascript code and press enter to execute it. You will get helpful error messages that should help you with your project.

JasonB
  • 5,747
  • 2
  • 13
  • 25
0

Ok. I realized your problem.

You can use iframe for this purpose. Add an iframe with an id similar 'answerIframe' instead of #answertext element.

Then move your #answertext element to a separated html and set address of iframe to it.

In iframe:

window.check=function(){
      document.getElementById("answertext").innerHTML = 
  eval(document.answer);
}

And add a button to your iframe too. for iframe's button set this:

onclick="window.check()"

Add an Id to iframe's button similar: iframe_bt.

Now, when user clicks on button (in current page, no iframe) must call this (new check function in your main page):

 function check(){

document.getElementById('#answerIframe').contentWindow.document.answer=document.getElementById("answerbox").value;

 document.getElementById('#answerIframe').contentWindow.document.getElementById('#iframe_bt').click();
}

Also in your iframe, call a function in document's onload and add answertext dynamically if is not exists (because document.write) or reset the iframe before execute per answer.

Another way is replacing the document.write with other code similar: elem.insertAdjacentHtml(..) or etc before execute it.

Excuse me for any mistake, i typed with my cellphone. I did not have a tool to test it, but the method and its generalities are correct.

Hassan Sadeghi
  • 1,276
  • 2
  • 5
  • 13