onmouseover works where onclick doesn't - AJAX

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • henryrhenryr
    New Member
    • Jun 2007
    • 103

    onmouseover works where onclick doesn't - AJAX

    I'm trying to log all links clicked. I'm just working this out so there may be some astoundingly bad methods. Please point out!

    It all works nicely though if I use mouseover events as the trigger. If I use click events then the AJAX bit breaks.

    Here's the code (mostly):

    Adding event listener to all links (firefox tells me errors but it works?!). When I switch from mouseover to click, the whole thing breaks down.
    [code=javascript]
    function listenAllLinks( ) {
    var a= document.getEle mentsByTagName( "a");
    for (x in a) {
    a[x].addEventListen er("mouseover", exit,true);
    }
    }
    [/code]

    Exit function which gets the AJAX object and makes the URL for the PHP script. Then does the AJAX magic bit.
    [code=javascript]
    function exit() {
    xmlHttp=GetXmlH ttpObject();
    if (xmlHttp==null) {
    //alert ("Browser does not support HTTP Request")
    return
    }

    var script= "exit.php";
    var exitPage= escape(this);
    var url=script+"?ex it_page="+exitP age+"&sid="+Mat h.random();

    xmlHttp.onready statechange=sta teChanged;
    xmlHttp.open("G ET",url,true) ;
    xmlHttp.send(nu ll);
    }
    }
    function stateChanged() {
    if (xmlHttp.readyS tate==4 || xmlHttp.readySt ate=="complete" ) {
    if (xmlHttp.respon seText==0) {
    //alert('error');
    }
    else {
    //alert('success' );
    }
    }
    }
    function GetXmlHttpObjec t() {
    var xmlHttp=null;
    try { // Firefox, Opera 8.0+, Safari
    xmlHttp=new XMLHttpRequest( );
    }
    catch (e) { //Internet Explorer
    try { xmlHttp=new ActiveXObject(" Msxml2.XMLHTTP" ); }
    catch (e) { xmlHttp=new ActiveXObject(" Microsoft.XMLHT TP"); }
    }
    return xmlHttp;
    }
    [/code]

    I'm a bit mystified as to why it's happy with mouseover and not with click. I suspect that it might be that the click loads a new page so maybe the server is cancelling requests that are unfinished and starting with the new ones before my script has recorded the link clicked.

    The other oddity is that on my localhost it works but on my live site it doesn't.

    Does anyone know how I can fix this or perhaps a slightly different approach?

    Thanks in advance!

    Henry

    Using apache 2, php 5, mysql 5 (local), apache2 php 4.3 mysql4.1 (live)
  • epots9
    Recognized Expert Top Contributor
    • May 2007
    • 1352

    #2
    are u using "click" or "onclick"? cuz onclick is the correct one.

    Comment

    • henryrhenryr
      New Member
      • Jun 2007
      • 103

      #3
      Hi Epots9

      Thanks for your reply! I read that when using addEventListene r you should use click for onclick. I just gave it a try with onclick but it then didn't register the event.

      Comment

      • pbmods
        Recognized Expert Expert
        • Apr 2007
        • 5821

        #4
        Heya, Henry.

        You are correct. The standard addEventListene r() uses 'click', 'mouseover', etc.

        Epots, you are also correct. Microsoft's attachEvent() uses 'onclick', 'onmouseover', etc.

        To answer your question, you might want to open a new window that sends the request and then closes itself when it finishes. Trying to execute code as the User is leaving the page is unpredictable at best. Trying to make the browser wait for a response from the server while the User is trying to leave the page, well....

        Comment

        • henryrhenryr
          New Member
          • Jun 2007
          • 103

          #5
          Hi Pbmods

          Thanks for clarifying that.

          I am now 100% sure that the problem lies with the new page loading and cancelling the completion of my php script called by the AJAX.

          I have changed the JS event to mousedown and tested by triggering the event without clicking on the link. The script runs correctly in this case. When I properly click though, the script fails to update the database.

          I think that it only needs about 200ms extra to complete so I am trying to find a way to delay the "unload" until the AJAX is complete.

          Does anyone know a quick way to delay the unload? I'm currently investigating onbeforeunload but I'm not sure this will meet the need.

          Thanks in advance!

          Henry

          Comment

          • pbmods
            Recognized Expert Expert
            • Apr 2007
            • 5821

            #6
            Heya, Henry.

            Originally posted by henryrhenryr
            Does anyone know a quick way to delay the unload? I'm currently investigating onbeforeunload but I'm not sure this will meet the need.
            Thank goodness there is no way to do this! Browsing the web is already annoying enough as it is!

            Have you tried opening a new window? It's not failsafe, as many browser pop-up blockers will prevent this. But it is more reliable than waiting for an AJAX call when the User is trying to leave.

            I suppose you could make all your clicks call the AJAX function that returns false, and then when the AJAX call comes back, THEN redirecting the page.

            Though your Users will probably be frustrated when it takes 1-2 seconds for a 'click' to 'register'. You may end up logging too many clicks!

            The other alternative is to do your calculations on the server side. For example, you can use $_SERVER['HTTP_REFERER'] in PHP.

            The one downside to this is that you won't know where they go after they leave your site. But you will know where they are coming from to get to your site, which might be more valuable information.

            Comment

            • henryrhenryr
              New Member
              • Jun 2007
              • 103

              #7
              Originally posted by pbmods
              Thank goodness there is no way to do this! Browsing the web is already annoying enough as it is!
              I take this point most definitely. It's a good thing although it's giving me a headache!

              Originally posted by pbmods
              Have you tried opening a new window?
              This is my fallback option. If I simply can't get it to work. But if google analytics can do it with their urchinTracker() function then so can I!!!

              Originally posted by pbmods
              I suppose you could make all your clicks call the AJAX function that returns false, and then when the AJAX call comes back, THEN redirecting the page.
              This is what I'm going to try. I'll make it as lean as possible to cut the time.

              I don't suppose you know of a way to get a script to run in the background on the server. I'm thinking something like a request sent to the server from the client. The server could even store that request and do it all later. That would be the perfect solution but how to get the server to do this?

              Thanks for your help!

              Comment

              • henryrhenryr
                New Member
                • Jun 2007
                • 103

                #8
                Solved!

                I have settled on the following:

                1. I found out that if I use the onclick event and return false, it cancels the normal click but I can keep the HTML nice and un-javascripted.

                2. I got the PHP script to echo the destination URL on success.

                3. The AJAX function then uses window.location to redirect to the URL when the AJAX is complete:

                [code=javascript]
                function exit(e) {
                // records click information using ajax
                source = findSourceEleme nt(e); //makes sure this is the right element
                tag = source.tagName;
                var id,label,target ;

                if( tag == 'IMG') {
                if( source.parentNo de.tagName == 'A' ) {
                target = source.parentNo de.href;
                }
                }

                if( tag == 'A' ) {
                target = source.href;
                }

                if( tag == 'INPUT' ) {
                if( source.getAttri bute('type') == 'submit' ) {
                target = getFormTarget( source ); //gets the form action attribute
                }
                else {
                target = 'script';
                }
                }

                xmlHttp=GetXmlH ttpObject();
                if (xmlHttp==null) {
                //alert ("Browser does not support HTTP Request")
                return
                }

                var script= "ajax/analytics_exit. php"; //the php script which records the exit data
                target = escape( target );
                var url=script+"?va pk="+window.vap k+"&exit_page=" +target+"&rand= "+Math.random() ;

                xmlHttp.onready statechange=sta teChanged;
                xmlHttp.open("G ET",url,true) ;
                xmlHttp.send(nu ll);

                return false;
                }

                function stateChanged() {
                if (xmlHttp.readyS tate==4 || xmlHttp.readySt ate=="complete" ) {
                var r=xmlHttp.respo nseText;
                if (r.indexOf('htt p://')==0) {
                window.location =r;
                }
                }
                }
                [/code]

                Thanks for your help.

                Comment

                • pbmods
                  Recognized Expert Expert
                  • Apr 2007
                  • 5821

                  #9
                  Heya, Henry.

                  Glad to hear you got it working! Good luck with your project, and if you ever need anything, post back anytime :)

                  Comment

                  Working...