Automated Click Event not executing href for hyperlinks

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Frinavale
    Recognized Expert Expert
    • Oct 2006
    • 9749

    Automated Click Event not executing href for hyperlinks

    This has to be one of the most frustrating controls I've ever designed.

    First I couldn't stop the __doPostback method from executing for DropDownLists (ie select elements).

    Now the __doPostback method will not execute for LinkButtons (hyperlinks that call the __doPostback method as their href) when I reissue the mouse click event.


    The same technique I used to stop and then re-issue the __doPostback for a DropDownList wont work for the issue with LinkButtons....

    I figured I'd mention it now before I went down some crazy path again that leads me to nowhere.

    (This thread is split off of this thread)
  • iam_clint
    Recognized Expert Top Contributor
    • Jul 2006
    • 1207

    #2
    Well don't use an asplinkbutton then use a regular link and append event to it.

    Comment

    • Frinavale
      Recognized Expert Expert
      • Oct 2006
      • 9749

      #3
      Originally posted by iam_clint
      Well don't use an asplinkbutton then use a regular link and append event to it.
      Hmm you would think that would work except for some reason regular hyperlinks are experiencing the same thing...except that instead of a JavaScript function not being called, the hyperlink simply doesn't link the user to the URL the href.

      It's almost as if the dispatchEvent() method isn't dispatching the event.

      I tried removing all code that "resets" the original event to make sure that this wasn't messing up the new event being dispatched, but this didn't make a difference.

      Comment

      • Frinavale
        Recognized Expert Expert
        • Oct 2006
        • 9749

        #4
        Hmm...

        It's not working in this simple example either.

        Code:
        <html>
        <head>
        
        <script type="text/JavaScript">
        function automatedClick()
        {
          var link = document.getElementById('sayHiLink');
          alert(link);
          var clickEvent = document.createEvent('MouseEvents');
          clickEvent.initEvent('click', true, true, document.defaultView,
                                 1, 0, 0, 0, 0, false, false, 
                                 true, false, 0, null);
          var done = link.dispatchEvent(clickEvent);
          alert(done);
        
          
        }
        function sayHi(){
          alert("hi!");
        }
        </script>
        
        </head>
        <body onload="automatedClick();">
        
        
        <a href="javascript:sayHi();" id="sayHiLink">hi</a>
        
        
        
        </body>
        </html>

        Comment

        • Frinavale
          Recognized Expert Expert
          • Oct 2006
          • 9749

          #5
          I've been doing a lot of reading about events.

          Some events can be cancelled. For these events a default action is associated with the event.

          For hyperlinks, the default action is to activate the hyperlink. Before this default action happens the DOM implementation checks for event listeners registered to receive the event. Those event listeners have the option to cancel or allow the default action to take place.


          Now, what's interesting is that I am not cancelling the default action of the hyperlink at all. I'm actually issuing an event that I thought should activate the default action but apparently this is not the case.

          (I've only been testing in FireFox so this might be different for other browsers, depending on their DOM implementation) .

          Anyways, I started trying out a few things. I discovered that if I apply an event listener to the hyperlink that this event listener is executed during the dispatched mouse event; however, the default action (the href) is not executed.

          Here's the code that I've been playing with:

          Code:
          <html>
          <head>
           
            <script type="text/JavaScript">
              function automatedClick(e)
              {
                var myEvt = document.createEvent('MouseEvents');
             
                myEvt.initMouseEvent(
               'click'         // event type
               ,true           // indicates whether or not the event bubbles
               ,true           // indicates whether or not the event can be cancelled
               ,window         // the event's abstract view (should always be window)
               ,1              // mouse click count (or event "detail")
               ,0              // event's screen x coordinate
               ,0              // event's screen y coordinate
               ,0              // event's client x coordinate
               ,0              // event's client y coordinate
               ,false          // whether or not CTRL was pressed during event
               ,false          // whether or not ALT was pressed during event
               ,false          // whether or not SHIFT was pressed during event
               ,false          // whether or not the meta key was pressed during event
               ,1              // indicates which button (if any) caused the mouse event (1 = primary button)
               ,null          // relatedTarget (only applicable for mouseover/mouseout events)
              ); 
          
                var link = document.getElementById('sayHiLink');
                var done = document.getElementById('sayHiLink').dispatchEvent(myEvt);
                if(done){
                  alert("The event dispatched successfully.");
                }else{
                  alert("There was a problem dispatching event.");
                }
              }
              function sayHi(){
                alert("Default action: hi!");
              }
              function anotherHi(){
                alert("EventListener: another hi...");
              }
          </script>
           
          </head>
          <body>
           
            <input type="button" id="sayHiButton" value="click me" />
            <br />
            <a href="javascript:sayHi();" id="sayHiLink">hi</a>
           
            <script>
              var btn= document.getElementById('sayHiButton');
              btn.addEventListener('click', automatedClick, false); 
          
              var lnk= document.getElementById('sayHiLink');
              sayHiLink.addEventListener('click', anotherHi, false); 
            </script>
           
          </body>
          </html>
          Just to make sure that this wasn't only true for when the default action of the hyperlink is to execute a JavaScript function, I modified the code so that the default action of the hyperlink was to load http://www.google.com. The same thing happens: the event listener is executed...but the hyperlink's default action (to load google) did not execute.

          Code:
          <html>
          <head>
           
            <script type="text/JavaScript">
              function automatedClick(e)
              {
                var myEvt = document.createEvent('MouseEvents');
             
                myEvt.initMouseEvent(
               'click'         // event type
               ,true           // indicates whether or not the event bubbles
               ,true           // indicates whether or not the event can be cancelled
               ,window         // the event's abstract view (should always be window)
               ,1              // mouse click count (or event "detail")
               ,0              // event's screen x coordinate
               ,0              // event's screen y coordinate
               ,0              // event's client x coordinate
               ,0              // event's client y coordinate
               ,false          // whether or not CTRL was pressed during event
               ,false          // whether or not ALT was pressed during event
               ,false          // whether or not SHIFT was pressed during event
               ,false          // whether or not the meta key was pressed during event
               ,1              // indicates which button (if any) caused the mouse event (1 = primary button)
               ,null          // relatedTarget (only applicable for mouseover/mouseout events)
              ); 
          
                var link = document.getElementById('theLink');
                var done = document.getElementById('theLink').dispatchEvent(myEvt);
                if(done){
                  alert("The event dispatched successfully.");
                }else{
                  alert("There was a problem dispatching event.");
                }
              }
              function linkClickEventHandler(){
                alert("Click Event Handled by EventListener.");
              }
          </script>
           
          </head>
          <body>
           
            <input type="button" id="sayHiButton" value="click me" />
            <br />
            <a href="http://www.google.com" id="theLink">Google</a>
           
            <script>
              var btn= document.getElementById('sayHiButton');
              btn.addEventListener('click', automatedClick, false); 
          
              var lnk= document.getElementById('theLink');
              lnk.addEventListener('click', linkClickEventHandler, false); 
            </script>
           
          </body>
          </htm>
          I'm going to keep investigating this mystery....so any input about what's going on would really help.

          Thanks

          -Frinny

          Comment

          • Frinavale
            Recognized Expert Expert
            • Oct 2006
            • 9749

            #6
            I am starting to think that firing a hyperlink's default action is impossible by dispatching a JavaScript mouse click event.

            I am guessing that this is a security feature to prevent cross site scripting attacks from redirecting users to pages without their knowledge.

            I'm not certain why I cannot do this, but I'm abandoning the issue....chalki ng it up to be one of those things that you simply cannot do.

            -Frinny

            Comment

            • Frinavale
              Recognized Expert Expert
              • Oct 2006
              • 9749

              #7
              I never solve the mystery but I solved my problem.

              I checked if there was a value in the href of the link element, then to execute the event I either called the JavaScript value provided for the href property or I preformed a JavaScript redirect to the value provided as the href property.

              It feels like a hack but it's working.
              Here's an example:
              Code:
              <html>
              <head>
               
                <script type="text/JavaScript">
                  function automatedClick(e)
                  {
                    var myEvt = document.createEvent('MouseEvents');
                    var link;
                    link = document.getElementById('theLink2');
                    //the following tests the redirect case.
                    //link = document.getElementById('theLink');
                    myEvt.initMouseEvent('click', false, false, window, 1, 0, 0, 0, 0, false, false, false, false ,1 ,null);   
                    link.dispatchEvent(myEvt);
                    if(link.href != null && link.href != ''){
                      if(link.href.search("JavaScript")>0){
                        //call JavaScript Function
                      }else{
                        //redirect 
                        window.location = link.href;
                      }
                    }
                  }
                  function linkClickEventHandler(){
                    alert("Click Event Handled by EventListener.");
                  }
                  function sayHi(){
                     alert("Hi!");
                  }
              </script>
               
              </head>
              <body>
               
                <input type="button" id="sayHiButton" value="click me" />
                <br />
                <a href="http://www.google.com" id="theLink">Google</a>
                <br />
                <a href="javascript:sayHi();" id="theLink2">JavaScript</a>
               
                <script>
                  var btn= document.getElementById('sayHiButton');
                  btn.addEventListener('click', automatedClick, false); 
               
                  var lnk= document.getElementById('theLink');
                  lnk.addEventListener('click', linkClickEventHandler, false); 
                </script>
               
              </body>
              </htm>
              -Frinny

              Comment

              • iam_clint
                Recognized Expert Top Contributor
                • Jul 2006
                • 1207

                #8
                Some browsers will allow an automated click on a link..
                such as IE you can use the element.click()
                Firefox i don't think you can..

                Way around it is read the href attribute and do window.location =href

                Comment

                • Frinavale
                  Recognized Expert Expert
                  • Oct 2006
                  • 9749

                  #9
                  Thanks iam_clint!

                  That's precisely what I'm doing in my above posted code snippet.

                  I have a feeling that once I get this working for FireFox it's not going to work in IE....I think the events are going to be issued more than once....but I'll cross that bridge when I get to it.

                  Comment

                  • Frinavale
                    Recognized Expert Expert
                    • Oct 2006
                    • 9749

                    #10
                    I figured I'd share the solution that works in IE as well as other browsers:
                    Code:
                    <html>
                    <head>
                     
                      <script type="text/JavaScript">
                        function automatedClick(e)
                        {    
                          var link;
                          link = document.getElementById('theLink2');
                     
                          //the following tests the redirect case.
                          //link = document.getElementById('theLink');
                     
                          try{
                            var myEvt = document.createEvent('MouseEvents');
                            myEvt.initMouseEvent('click', false, false, window, 1, 0, 0, 0, 0, false, false, false, false ,1 ,null);   
                            link.dispatchEvent(myEvt);
                          }catch(ex){
                             myEvt= document.createEventObject();
                                    myEvt.detail = 0;
                                    myEvt.screenX = 0;
                                    myEvt.screenY = 0;
                                    myEvt.clientX = 0;
                                    myEvt.clientY = 0;
                                    myEvt.ctrlKey = false;
                                    myEvt.altKey = false;
                                    myEvt.shiftKey = true;
                                    myEvt.metaKey = false;
                                    myEvt.button = 1;
                                    myEvt.relatedTarget = null;
                             link.fireEvent('onclick', myEvt);
                          }
                          if(link.href != null && link.href != ''){
                            if(link.href.search("JavaScript")>0){
                              //call JavaScript Function
                              eval(link.href);
                            }else{
                              //redirect 
                              window.location = link.href;
                            }
                          }
                        }
                        function linkClickEventHandler(){
                          alert("Click Event Handled by EventListener.");
                        }
                        function sayHi(){
                           alert("Hi!");
                        }
                    </script>
                     
                    </head>
                    <body>
                     
                      <input type="button" id="sayHiButton" value="click me" />
                      <br />
                      <a href="http://www.google.com" id="theLink">Google</a>
                      <br />
                      <a href="javascript:sayHi();" id="theLink2">JavaScript</a>
                     
                      <script>
                        var btn= document.getElementById('sayHiButton');  
                        var lnk= document.getElementById('theLink');
                        var lnk2= document.getElementById('theLink2');
                     
                        try{
                              btn.addEventListener('click', automatedClick, false); 
                              lnk.addEventListener('click', linkClickEventHandler, false); 
                              lnk2.addEventListener('click', linkClickEventHandler, false);
                        }
                        catch(ex) {
                            btn.attachEvent('onclick', automatedClick); 
                            lnk.attachEvent('onclick', linkClickEventHandler); 
                            lnk2.attachEvent('onclick', linkClickEventHandler);
                        }
                     
                      </script>
                     
                    </body>
                    </htm>

                    Comment

                    Working...