jQuery ajaxfunction无法在Safari中运行(Firefox,Chrome,IE还可以)

我不是javascript wiz,但是我有点疑惑它是如何在三个主流浏览器中工作,但不是Safari …这个代码有什么问题吗? 基本上我只是在给定的URL上使用它与php / mysql回调一起来跟踪链接点击。

Drupal.behaviors.NodeDownloadCounter = function() { $('a.ndc-link').click(function() { $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name); return true; }); }; 

在这里使用Drupal行为而不是

 $(document).ready(function() { 

(正确的Drupal方法),但我已经尝试了两种方式,它没有任何区别。

我也尝试删除“return true”,但没有效果。


好的,进一步的测试表明,点击触发警报可以在Safari中运行:

 $('a.ndc-link').click(function() { alert('testing (ignore)'); $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name); return true; }); 

但仍然没有记录到mysql。 这是我的回调函数:

 function node_download_counter_log($nid) { global $user; $timestamp = time(); $title = db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $nid)); db_query("INSERT INTO {node_download_counter} (nid, title, download_count, last_download, last_uid) VALUES (%d, '%s', %d, %d, %d) ON DUPLICATE KEY UPDATE download_count=download_count+1, last_download = %d, last_uid = %d", $nid, $title, 1, $timestamp, $user->uid, $timestamp, $user->uid); db_query("INSERT INTO {node_download_counter_log} (nid, title, uid, timestamp) VALUES (%d, '%s', %d, %d)", $nid, $title, $user->uid, $timestamp); } 

听起来问题是浏览器在数据发布完成之前正在更改页面。 您可以尝试添加return false以查看它是否开始工作。 如果是这样,您需要在跟踪链接之前添加一个短暂的延迟。

更新:因为它的工作原理尝试在“return true”之前添加以下内容

 if(jQuery.browser.safari){ setTimeout("window.location.href= '"+this.href+"'",500); return false; } 

好的,根据我们上面评论的对话,试试吧

 $('a.ndc-link').click(function() { var href = this.href; $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name, function() { window.location.href = href; } ); return false; }); 

首先,你必须小心不要将你的处理程序多次附加到每个'a.ndc-link' ,一种方法是用自定义类标记元素。

 Drupal.behaviors.NodeDownloadCounter = function() { $('a.ndc-link:not(.node-download-counter-processed)').addClass('node-download-counter-processed').click(function(event) { // ... }); }; 

我认为这不起作用的一个原因是,因为它关闭页面以打开链接目标,Safari将在实际发送到服务器之前取消$.post请求。 返回false并调用event.preventDefault (事件是事件处理程序的第一个参数)应该可以防止这种情况发生,但也会阻止浏览器实际加载链接的目标。 解决此问题的一种方法是推迟页面更改,直到POST请求完成。

 Drupal.behaviors.NodeDownloadCounter = function() { $('a.ndc-link:not(.node-download-counter-processed)').addClass('node-download-counter-processed').click(function(event) { var link = this; event.preventDefault(); $.post('http://www.pixeledmemories.com/node-download-counter/log/' + this.name, function() { window.location.href = link.href; }); return false; }); }; 

但这只有在POST请求中没有错误时才有效。

更好的解决方案是劫持链接目标的服务器端处理程序以添加单击日志记录,然后调用原始处理程序。