Assigning same onclick dynamically and statically

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • RobG

    Assigning same onclick dynamically and statically


    I have a function whose parameter is a reference the element that called it:

    function someFunction(el )
    {
    ...
    }

    The function is assigned to the onclick event of some elements in the
    HTML source:

    <input ... onclick="someFu nction(this);" ...>

    and dynamically to others:

    elRef.onclick = someFunction;


    When someFunction() is called from the statically-assigned onclick, el
    is a reference to the element. But when it has been added dynamically,
    el will be either undefined (IE) or 'event' (Mozilla et al).

    To assign the right value to el, I can test if el exists and if it does,
    whether its constructor is some type of HTML element or 'Event'. But IE
    doesn't support the constructor property for elements (or have I just
    not found it yet?) nor does it understand 'Event' the way Mozilla does.

    Anyhow, the following test does the job:

    function someFunction(el )
    {
    var el=(!el || (el.constructor && Event == el.constructor) )? this : el;
    ...

    If el is undefined:
    - have IE dynamically added event, el is assigned the value of 'this'

    If el is defined
    - have IE statically added event, el is assigned the value of el
    OR
    - have Mozilla:
    - if el.constructor is Event, have dynamically added event,
    el is assigned the value of this
    - if el.constructor is not Event, have statically added event,
    el is assigned the value of el


    It works, but seems long winded and dependent on the vagaries of the two
    event models. As a result, I've been using:

    var el = (el && el.nodeName)? el : this;

    This seems much simpler - if el is defined and has a nodeName, use it.
    Otherwise, use this.

    Rather than detecting if the function was passed a reference to 'event'
    or not, it sees if an element was passed. It works and assigns a
    reference to the element whether called from the statically or
    dynamically attached function.

    Is that reasonable logic, or should the first method be used? Or is
    there a better way of doing what I'm after?


    Some sample code:


    <input type="button" value="Replace onclick" onclick="
    replaceOnclick( this);
    alert('Old onclick replaced');
    ">

    <script type="text/javascript">
    function replaceOnclick( el)
    {
    // Short version
    var el = (el && el.nodeName)? el : this;

    // Long version (wrapped for posting)
    // var el = ( !el || (el.constructor
    && Event == el.constructor) )? this : el;

    el.onclick = replaceOnclick;
    alert( el.nodeName + ': new onclick');
    }
    </script>




    --
    Rob
  • Martin Honnen

    #2
    Re: Assigning same onclick dynamically and statically



    RobG wrote:

    [color=blue]
    > <input ... onclick="someFu nction(this);" ...>
    >
    > and dynamically to others:
    >
    > elRef.onclick = someFunction;[/color]

    You need
    elRef.onclick = function (evt) {
    someFunction(th is);
    };
    then to have the same as that onclick attribute in the HTML markup creates.

    --

    Martin Honnen

    Comment

    • VK

      #3
      Re: Assigning same onclick dynamically and statically


      RobG wrote:[color=blue]
      > I have a function whose parameter is a reference the element that called it:
      >
      > function someFunction(el )
      > {
      > ...
      > }
      >
      > The function is assigned to the onclick event of some elements in the
      > HTML source:
      >
      > <input ... onclick="someFu nction(this);" ...>
      >
      > and dynamically to others:
      >
      > elRef.onclick = someFunction;
      >
      >
      > When someFunction() is called from the statically-assigned onclick, el
      > is a reference to the element. But when it has been added dynamically,
      > el will be either undefined (IE) or 'event' (Mozilla et al).
      >
      > To assign the right value to el, I can test if el exists and if it does,
      > whether its constructor is some type of HTML element or 'Event'. But IE
      > doesn't support the constructor property for elements (or have I just
      > not found it yet?) nor does it understand 'Event' the way Mozilla does.[/color]

      Another (clearer??) way:

      function someFunction() {
      var el = someFunction.ar guments[1] ||
      someFunction.ar guments[0].target;
      ...
      }

      <input ... onclick="someFu nction(null,thi s);" ...>

      elRef.onclick = someFunction;

      I say that Mozilla/3W way demostrates its big flaw here: it leads to
      the left/right arguments' shift in functions depending on how they are
      being called: from the program stream or by event listeners. That's a
      pain for distributed libraries.

      Comment

      • RobG

        #4
        Re: Assigning same onclick dynamically and statically

        VK wrote:[color=blue]
        > RobG wrote:
        >[color=green]
        >>I have a function whose parameter is a reference the element that called it:
        >>
        >> function someFunction(el )
        >> {
        >> ...
        >> }
        >>
        >>The function is assigned to the onclick event of some elements in the
        >>HTML source:
        >>
        >> <input ... onclick="someFu nction(this);" ...>
        >>
        >>and dynamically to others:
        >>
        >> elRef.onclick = someFunction;
        >>
        >>
        >>When someFunction() is called from the statically-assigned onclick, el
        >>is a reference to the element. But when it has been added dynamically,
        >>el will be either undefined (IE) or 'event' (Mozilla et al).
        >>
        >>To assign the right value to el, I can test if el exists and if it does,
        >>whether its constructor is some type of HTML element or 'Event'. But IE
        >>doesn't support the constructor property for elements (or have I just
        >>not found it yet?) nor does it understand 'Event' the way Mozilla does.[/color]
        >
        >
        > Another (clearer??) way:
        >
        > function someFunction() {
        > var el = someFunction.ar guments[1] ||
        > someFunction.ar guments[0].target;
        > ...
        > }
        >
        > <input ... onclick="someFu nction(null,thi s);" ...>
        >
        > elRef.onclick = someFunction;[/color]

        I don't think that's an improvement - it introduces peculiarities at
        both ends.
        [color=blue]
        >
        > I say that Mozilla/3W way demostrates its big flaw here: it leads to
        > the left/right arguments' shift in functions depending on how they are
        > being called: from the program stream or by event listeners. That's a
        > pain for distributed libraries.
        >[/color]

        The 'flaw', if there is one, is that there are two models - I can't
        comment on whether one is better than the other.

        Martin's suggestion is fine, I've used it frequently but it seems a bit
        of a hack to use an anonymous function to call another function (I guess
        views on that differ).

        Incidentally, nice you see you're back contributing :-)


        --
        Rob

        Comment

        • VK

          #5
          Re: Assigning same onclick dynamically and statically

          > VK wrote:[color=blue]
          > ... it leads to the left/right arguments' shift in functions depending on...[/color]

          Correcting myself as a wrong wording and explanation: there is not any
          *shift* here. The first argument in each function (3W model) is
          reserved for the Event data. You can use it for other purposes but it
          will be like sitting on someone place ready to leave at any moment. As
          soon as your function is called by an event listener, the first
          argument will contain the Event data no matter what kind of argument
          your function was really expecting. We may call it "a different
          approach" or "an unforseen oops of the chosen model", it's really a
          question of preferences :-)
          So wrappers from anonymous functions (despite their semi-ugliness)
          would be a choice I guess.

          [color=blue]
          > the following test does the job:
          > function someFunction(el )
          > {
          > var el=(!el || (el.constructor && Event == el.constructor) )? this : el;[/color]

          There must be some surrounding code missing because here (and in the
          other variant) you assign window object to el in IE case (this ==
          window.self within named function body). That doesn't seem your aim.

          [color=blue]
          > Incidentally, nice you see you're back contributing :-)[/color]
          ;-)

          Comment

          Working...