-2

Here is the code I simplified, but the nature of the problem is the same:

var counter=0;

function test(){
    window.onclick="return;";
    t.value=counter;
    counter++;
    setTimeout(test,1000);
}

t=document.createElement("textarea");
document.body.insertBefore(t, document.body.firstChild);
test();

Sets up a timer, however, as you can see, the clock does not stop (i.e. function exits) after I clicked the window. So where is the problem?

Edit: The motivation of this question comes from:Early exit from function?

Edit^2: Then there is noway to make 'onlick' trigger the returning value of test()? (i.e. equivalent of asking whether a function can return as its super-function)

Community
  • 1
  • 1
user2386986
  • 119
  • 5
  • Really, did you write this yourself, and if so why would anything happen when clicking the window? The return is a string that has nothing to do with the timeout ? – adeneo Jun 05 '14 at 03:03
  • `onclick` takes a function! – tymeJV Jun 05 '14 at 03:04
  • @tymeJV It can also take a string of Javascript, which will be evaluated. – Barmar Jun 05 '14 at 03:06
  • 1
    @Barmar: Only the attribute, I think. `.onclick` needs to be assigned a function. – Bergi Jun 05 '14 at 03:07
  • http://jsfiddle.net/Nz23K/ – adeneo Jun 05 '14 at 03:07
  • @Bergi Thanks, I stand corrected. I thought the attribute and property were equivalent. – Barmar Jun 05 '14 at 03:11
  • Why would `return;` stop the function? `return;` isn't in the scope of `test()`. – Derek 朕會功夫 Jun 05 '14 at 03:11
  • @Barmar: [It doesn't seem to be specified](http://www.w3.org/TR/html5/webappapis.html#event-handlers) what happens when a string is getting assigned. Opera at least does nothing, haven't tested other browsers yet. – Bergi Jun 05 '14 at 03:12
  • I tried `window.onclick = 'alert("click!")'` in Chrome, it did nothing. – Barmar Jun 05 '14 at 03:18
  • Yep, the equivalent event handling DOM properties need functions. Like many other HTML attributes, event handling attributes are processed and converted to functions for the DOM properties. This can be seen by doing something like `
    ` and `console.log(divRef.onclick)`.
    – Felix Kling Jun 05 '14 at 03:19

3 Answers3

2

That function has long since exited when you're trying to call return. JavaScript isn't going to throw itself into a time machine and prevent the setTimer call from being executed. It's too late for that.

What you need to do is cancel the timer, and in order to do that you have to save a handle to it:

var counter = 0;
var timer;

function test(){
    window.onclick = function() {
      if (timer) { clearTimeout(timer) }
    }

    t.value=counter;
    counter++;
    timer = setTimeout(test,1000);
}
tadman
  • 208,517
  • 23
  • 234
  • 262
1

Every ten minutes, you tell your wife "if you see a postman, do nothing.". Unsurprisingly, when she sees a postman, she does nothing.

Basically, what you're doing is identical, but less secure, way of writing this:

window.onclick = function() {
  return;
}

i.e. when a click is detected, it executes a function that does nothing but return. It has nothing to do with the function test.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • Actually, I'm unsure if setting the property `onclick` as a string will work: http://jsfiddle.net/kLvfX/ So technically, they are not identical (if it did work, the scope will be different and they are still not identical.) – Derek 朕會功夫 Jun 05 '14 at 03:18
  • @Derek朕會功夫: Yeah, you might be right. I abandoned string event handlers years ago, not sure any more what works and what doesn't. – Amadan Jun 05 '14 at 04:03
  • Sorry for off-topic, but this answer has reminded me a joke I think is worth sharing... http://s2.quickmeme.com/img/c9/c9ec3d95bb16919cfb1e2f90c9eafe12f6ef7b85771428561a7f8265ac2d6f4e.jpg – Lukas May 17 '16 at 16:35
0

In the statement:

window.onclick="return;";

the string "return;" is assigned to the window.onclick property, which will replace the current value (whatever that might be).

If your intention was to end execution of the test function, then a return statement is required:

return;

The return keyword must appear as the start of a statement, it can't be assigned.

RobG
  • 142,382
  • 31
  • 172
  • 209