473,406 Members | 2,745 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

onmouseover works where onclick doesn't - AJAX

103 100+
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.
Expand|Select|Wrap|Line Numbers
  1. function listenAllLinks() {
  2.   var a= document.getElementsByTagName("a");
  3.   for (x in a) {
  4.     a[x].addEventListener("mouseover",exit,true);
  5.   }
  6. }
  7.  
Exit function which gets the AJAX object and makes the URL for the PHP script. Then does the AJAX magic bit.
Expand|Select|Wrap|Line Numbers
  1. function exit() {
  2.     xmlHttp=GetXmlHttpObject();
  3.     if (xmlHttp==null) {
  4.       //alert ("Browser does not support HTTP Request")
  5.       return
  6.     }
  7.  
  8.     var script= "exit.php";
  9.     var exitPage= escape(this);
  10.     var url=script+"?exit_page="+exitPage+"&sid="+Math.random();
  11.  
  12.     xmlHttp.onreadystatechange=stateChanged;
  13.     xmlHttp.open("GET",url,true);
  14.     xmlHttp.send(null);
  15.   }
  16. }
  17. function stateChanged() {
  18.   if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
  19.     if (xmlHttp.responseText==0) {
  20.       //alert('error');
  21.     }
  22.     else {
  23.       //alert('success');
  24.     }
  25.   }
  26. }
  27. function GetXmlHttpObject() {
  28.   var xmlHttp=null;
  29.   try { // Firefox, Opera 8.0+, Safari
  30.     xmlHttp=new XMLHttpRequest();
  31.     }
  32.   catch (e) { //Internet Explorer
  33.     try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); }
  34.     catch (e) { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); }
  35.   }
  36.   return xmlHttp;
  37. }
  38.  
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)
Aug 23 '07 #1
8 3275
epots9
1,351 Expert 1GB
are u using "click" or "onclick"? cuz onclick is the correct one.
Aug 23 '07 #2
henryrhenryr
103 100+
Hi Epots9

Thanks for your reply! I read that when using addEventListener you should use click for onclick. I just gave it a try with onclick but it then didn't register the event.
Aug 23 '07 #3
pbmods
5,821 Expert 4TB
Heya, Henry.

You are correct. The standard addEventListener() 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....
Aug 23 '07 #4
henryrhenryr
103 100+
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
Aug 29 '07 #5
pbmods
5,821 Expert 4TB
Heya, Henry.

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.
Aug 29 '07 #6
henryrhenryr
103 100+
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!

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!!!

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!
Aug 29 '07 #7
henryrhenryr
103 100+
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:

Expand|Select|Wrap|Line Numbers
  1. function exit(e) {
  2.   // records click information using ajax
  3.   source = findSourceElement(e); //makes sure this is the right element
  4.   tag = source.tagName;
  5.   var id,label,target;
  6.  
  7.   if( tag == 'IMG') {
  8.     if( source.parentNode.tagName == 'A' ) {
  9.       target = source.parentNode.href;
  10.     }
  11.   }
  12.  
  13.   if( tag == 'A' ) {
  14.     target = source.href;
  15.   }
  16.  
  17.   if( tag == 'INPUT' ) {
  18.     if( source.getAttribute('type') == 'submit' ) {
  19.       target = getFormTarget( source ); //gets the form action attribute
  20.     }
  21.     else {
  22.       target = 'script';
  23.     }
  24.   }
  25.  
  26.     xmlHttp=GetXmlHttpObject();
  27.     if (xmlHttp==null) {
  28.       //alert ("Browser does not support HTTP Request")
  29.       return
  30.     }
  31.  
  32.     var script= "ajax/analytics_exit.php"; //the php script which records the exit data
  33.     target = escape( target );
  34.     var url=script+"?vapk="+window.vapk+"&exit_page="+target+"&rand="+Math.random();
  35.  
  36.     xmlHttp.onreadystatechange=stateChanged;
  37.     xmlHttp.open("GET",url,true);
  38.     xmlHttp.send(null);
  39.  
  40.   return false;
  41. }
  42.  
  43. function stateChanged() {
  44.   if (xmlHttp.readyState==4 || xmlHttp.readyState=="complete") {
  45.     var r=xmlHttp.responseText;
  46.     if (r.indexOf('http://')==0) {
  47.       window.location=r;
  48.     }
  49.   }
  50. }
  51.  
Thanks for your help.
Aug 29 '07 #8
pbmods
5,821 Expert 4TB
Heya, Henry.

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

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: Tim | last post by:
Hope someone in the big wide world can help... What I want to do is have an image slideshow which automatically scrolls through a series of images very fast, then pauses when you move your mouse...
7
by: Samir | last post by:
I would like to get a little window (101x73) to appear on onmouseover and go away onmouseout. the onclick works. <html> <head> <meta http-equiv="Content-Language" content="en-us"> <meta...
7
by: Richard | last post by:
I know I can have like <a href="#" onclick="dothis" onmouseover="dothat"> But how do you properly code two mouseover's in one statement? <a href="#" onmousever="dothis" onmouseover="dothat"> As...
1
by: Martin Chen | last post by:
First, apologies up front, I just started futzing with javascript so be prepared for naivate. I have a web page, in a frame set, that has a table-menu bar in javascript. It relies on the "movein"...
5
by: Martin Chen | last post by:
I have a frame set (as per MS FrontPage 2000). It has a contents and a main frame. The contents frame has a menu bar written with with javascript (in the context of a table). In IE6.1 everything...
2
by: Daz | last post by:
Hi everyone. I think my problem is a simple one, but I am completely baffled as to how to pull it off. I have a piece of code like so... document.write( "<img id=\"slideshow_toggle\"...
3
by: equazcion | last post by:
Hi, I have an image reference (IMG) in my page that changes depending on the value of a database field. Clicking the image triggers an Ajax call to change the database field (toggles the field...
3
by: =?Utf-8?B?RGVlcGE=?= | last post by:
Hi All, I have a webform in asp.net framework 1.1 where the dropdownlist is populated with list of locations from the database. The depending on the list selected, the user will be able to see...
9
by: octophobik | last post by:
Hello, I have a PHP page that populates the page with images and a little bit of text under each image based on who's session is accessing the page. It also has for each image an...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.