【问题标题】:jQuery ajax function not working in Safari (Firefox, Chrome, IE okay)jQuery ajax 功能在 Safari 中不起作用(Firefox、Chrome、IE 可以)
【发布时间】:2010-07-05 05:48:22
【问题描述】:

我不是 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 true?只是好奇..
  • 问得好 Reigel...就像我说的,我不是 javascript 向导...我从一个教程中获取了这个基本代码,该教程最后有“return true”...在没必要?
  • 我会检查错误控制台,因为 safari 会在一个不错的链接中显示从服务器返回的响应,您可以单击该链接然后查看返回的内容。所以尝试从 ajax 调用中返回一个值,看看你是否得到了你期望的响应。
  • 抱歉,我缺乏专业知识 spinon...您能否详细说明如何执行您的建议?非常感谢您的帮助!
  • 你能删除return true;...我认为不应该在那里...只有return false;主要使用...如果你希望你的页面不跳转到其他页面单击该锚点时...

标签: javascript jquery ajax drupal safari


【解决方案1】:

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

更新: 由于它有效,请尝试在“return true;”之前添加以下内容

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

【讨论】:

  • 非常感谢亚伦!添加“return false;”确实使代码在 Safari 中工作......除了链接当然没有实际遵循。我究竟应该如何添加延迟才能完成这项工作?另外,Safari 处理发布信息的方式似乎与 Firefox/Chrome/IE 不同,这不是有点奇怪吗?不得不为一个浏览器手动添加延迟似乎很奇怪(当页面加载速度显然更可取时)。
  • 您可以使用 jQuery.browser.safari 选择性地为 Safari 添加超时。请参阅我上面的编辑。使用 Reigel 的解决方案会延迟所有浏览器中的卸载。
  • @Aaron - 是的setTimeout 可能会工作......但可以肯定的是,OP 可以使用$.post() 的callback...... callback 将在请求之后运行$.post() 中的链接完成...并且 jQuery.browser 现在有些弃用了 ;)
  • 除非出现服务器错误或者数据库速度慢;在这种情况下,它将挂起很长时间,使用户无法移动到另一个页面。
【解决方案2】:

好的,根据我们上面关于 cmets 的对话,试试

$('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;
});

【讨论】:

  • 感谢 Reigel 提供的解决方案,感谢您花费的所有时间!它工作得很好。很难知道该采用哪种解决方案,因为所有三个建议都有效。我想我会选择 Aaron's,因为它很简单,而且它单独处理 Safari,但如果你能解释为什么你的解决方案更好,我会全力以赴。再次感谢!
  • nahh...简单就是美..当您遇到问题时,您可以更改为这些其他解决方案.. :) 干杯!但我还是说我的很好……
【解决方案3】:

首先,您必须小心不要将处理程序多次附加到每个'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 请求中没有错误的情况下才有效。

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

【讨论】:

  • 仅供参考,event.preventDefault(); 与 return false 几乎相同......你不必同时做这两个(在这个问题中)......
  • 感谢您提出不止一次附加处理程序的要点——完全忘记了这一点!并感谢您的解决方案!它工作得很好。很难知道该采用哪种解决方案,因为所有三个建议都有效。我想我会选择 Aaron's,因为它很简单,而且它单独处理 Safari,但如果你能解释为什么你的解决方案更好,我会全力以赴。再次感谢!
猜你喜欢
  • 2013-01-04
  • 2012-02-17
  • 1970-01-01
  • 2012-11-03
  • 2011-04-13
  • 2011-02-20
  • 1970-01-01
  • 2010-11-06
  • 2013-04-30
相关资源
最近更新 更多