Why does innerHTML^=1 work in onclick , although the idea should be this.innerHTML^=1 ?

 /* ignore css */ p { float: left; font-size: 4em; width: 2em; line-height: 2em; border: 1px solid; text-align: center; margin: 0; cursor: pointer; background: silver; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } p + p { margin-left: .125em; } 
 <p onclick=innerHTML^=1>0 <p onclick=this.innerHTML^=1>0 

  • What is this leapfrog? Any template engine? Or is it natural xor? =) - vp_arth
  • Apparently, onclick is executed in the context of with(this) . - vp_arth
  • one
    I seem to have missed something in my life ... Where does it apply and where to read? Give the link, please :) - Denis Bubnov
  • one
    internal raw uncompiled handler . There is not quite with - Grundy
  • one
    @Grundy, and who will write the answer? ;) - Qwertiy

3 answers 3

The internal raw uncompiled handler is stupid with the following information:

  • Uncompiled script body
  • The place of origin of the script body if it is necessary to report an error

When the user agent (user agent) receives the current value of the H event handler, it must complete these steps:

  1. If the value of H is an internal raw uncompiled handler, run these substeps:

    1. If H is an element's event handler, then let element be an element, and document be an element's Document.

      Otherwise, H is the event handler for the Window object: let element be null, and let document be the Document most recently associated with this Window object.

    2. If document is not in the context of browsing, or if scripting is enabled for the document context of browsing, then return null and abort the algorithm for obtaining the current value of the event handler.

    3. Let body be the uncompiled script body in an internal raw uncompiled handler.

    4. Let location be the place from which the script body originates, as specified by the internal raw uncompiled handler.

    5. If element is not null and element has a form owner, let the form owner be the form owner . Otherwise, let the form owner be null.

    6. Let script settings be a script settings object created for a Window object with which document is currently associated.

    7. Get the script execution environment for javascript from script settings .

    8. If the body not disassembled as a FunctionBody, or if an early error is detected during the parsing, then follow these substeps:

      1. Set H to null.

      2. Report an error for the corresponding script with the corresponding position (line number and column number) specified in location , using the global object specified in script settings as the target. If the error is still not processed after this, then it can be reported to the user.

      3. Skip lower by step end.

      Note: FunctionBody is defined in ECMAScript edition 5 section 13 Function Definition. Error Early error is defined in ECMAScript edition 5 section 16 Errors. [ECMA262]

    9. If body begins with a Directive Prologue containing Use Strict Directive, then let strict be true, otherwise, let strict be false.

      Note: The terms "Directive Prologue" and "Use Strict Directive" are defined in the ECMAScript edition 5 section 14.1 Directive Prologues and the Use Strict Directive. [ECMA262]

    10. Using the script execution environment obtained above, create a function object (as defined in ECMAScript edition 5 section 13.2 Creating Function Objects), with:

      Parameter List FormalParameterList

      • If H is the Window object's onerror event handler:

        • Let the function have 5 arguments: event , source , lineno , colno, and error .
      • Otherwise:

        • Let the function have one event argument.
      • FunctionBody: function body FunctionBody:

        • The result of body parsing is higher.
      • Lexical Scope Environment:

        1. Let Scope be the result of NewObjectEnvironment ( document , global environment ).
        2. If the form owner not null, let Scope be the result of NewObjectEnvironment ( >form owner , Scope ).
        3. If element not null, let Scope be the result of NewObjectEnvironment ( element , Scope ).

        Note: NewObjectEnvironment () is defined in ECMAScript edition 5 section 10.2.2.3 NewObjectEnvironment (O, E). [ECMA262]

      • Boolean flag Strict

        • The value is strict .
      • Let function be this new function.

    11. Let script a new script.

    12. Let the script entry code point be function .

    13. Let the script settings object be script settings .

    14. Set H to function .

  2. End : Return the value H.

  • 2
    @Grundy, check it out. - user207618
  • @Other, no, I would have translated differently :-) - Grundy
  • one
    @Grundy, I think they wouldn’t have translated at all - copy-paste and figure it out myself :) - user207618
  • @Other, not true :-) look, I have in the answers there are references to the specification with the translation :) - Grundy
  • @Grundy, once in the blue moon ... - user207618

If it is short and on the fingers, then using inline handlers implicitly generates something like this:

 with(document) with(currentElement.form) with(currentElement) currentElement.addEventListener("click", function (event) { // Тут содержимое атрибута onclick }) 

A more formal algorithm can be seen at the link Grundy provided: https://www.w3.org/TR/html5/webappapis.html#internal-raw-uncompiled-handler

    In support of my version that the onxxxx attributes are executed approximately like with (this) eval(script) quote a snippet:

      var el = document.createElement('P'); el.a='Ok'; el.setAttribute('onclick', 'console.info(a, this.a)'); el.click(); 

    As you can see, this even works with the newly created property.

    Why and where to find the specification for this do not know.
    Also, I do not exclude that this does not work in all browsers.

    • My version works in FF, Chrome, IE 11, Oper 12. This one did not check, but I think it will turn out the same. It is more interesting to me exactly where it says that it should work :) - Qwertiy
    • Unlike eval, inline handlers are compiled. - Pavel Mayorov