2010-07-05 3 views
1

저는 3 개의 주요 브라우저에서 작동하는 방법에 대해 의아해하지만 약간의 의문점이 있습니다. 이 코드에 문제가 있습니까? 기본적으로 나는 링크 클릭을 추적하기 위해 주어진 url에서 php/mysql 콜백과 함께 이것을 사용하고있다.jQuery ajax 함수가 Safari (Firefox, Chrome, IE okay)에서 작동하지 않습니다.

Drupal.behaviors.NodeDownloadCounter = function() { 

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

}; 
대신

$(document).ready(function() { 

(올바른 드루팔 방법)의 여기 드루팔 동작을 사용

그러나 나는 그것을 두 가지를 시도하고 그 차이를 만들지 않습니다.

"return true"는 제거했지만 아무런 효과가 없습니다.

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

하지만 여전히 아무것도 MySQL의에 기록되고 있지 :


좋아, 추가 시험은 경고 Safari에서 작업을 수행하는 클릭 트리거를 갖는 것을 알 수있다. 다음은 콜백 함수입니다.

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); 

} 
+0

왜 'true true'를 반환해야합니까? 그냥 호기심 .. – Reigel

+0

좋은 질문 Reigel ... 내가 말했듯이, 나는 자바 스크립트 wiz 아니에요 ... 나는 "반환 진정한"튜토리얼 에서이 기본 코드를 가져 갔는데 ... 필요하지 않습니다? –

+0

사파리가 좋은 링크에있는 서버에서 응답을 보여주기 때문에 오류 콘솔을 확인하고 클릭 한 다음 되돌아온 것을 볼 수 있습니다.따라서 Ajax 호출에서 값을 반환하고 예상 한 응답을 얻고 있는지 확인하십시오. – spinon

답변

3

문제는 브라우저가 데이터 게시물을 완성하기 전에 페이지를 변경하는 것과 같습니다. return false를 추가하여 작업이 시작되는지 확인할 수 있습니다. 그렇다면 링크를 따라 가기 전에 짧은 지연을 추가해야합니다.

업데이트 : 작동하기 때문에 "return true;"다음을 추가하십시오. 당신이 그것을 할 각 'a.ndc-link', 하나의 방법에 한 번 이상 처리기 더 부착하지 않도록주의 할 필요가 t에 의견에 우리의 대화를 기반으로 좋아

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

정말 고마워요! "return false;"추가 실제로 Safari에서 코드가 작동합니다 ... 링크가 실제로 따라 가지 않는다는 것만 제외하면. 이 작업을 수행하기 위해 얼마나 지연을 추가해야합니까? 또한 Safari가 Firefox/Chrome/IE와는 다른 방식으로 정보를 게시하는 것으로 보이는 것 같지 않습니까? 페이지로드가 가능한 한 빨리 이루어지면 한 브라우저에 대해 지연을 수동으로 추가해야하는 것이 이상하게 보입니다. –

+0

jQuery.browser.safari를 사용하여 Safari에 대한 제한 시간을 선택적으로 추가 할 수 있습니다. 위의 편집을 참조하십시오. Reigel의 솔루션을 사용하면 모든 브라우저에서 언로드가 지연됩니다. –

+0

@Aaron - 예'setTimeout'은 작동 할 수 있습니다 ...하지만 OP는'$ .post()'의'callback'을 사용할 수 있습니다 ... 콜백은 링크 요청 후 실행됩니다. '$ .post()'가 끝나고 ... jQuery.browser가 이제 다소 비추천입니다;) – Reigel

2

, 위,

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

그리고 Reigel 솔루션에 대해 감사 드리며 항상 촬영했습니다! 그것은 잘 작동합니다. 세 가지 제안이 모두 작동하므로 어떤 솔루션을 사용해야하는지 알기가 어렵습니다. 단순함과 개별적으로 사파리를 처리한다는 사실 때문에 Aaron과 함께 갈 것이라고 생각합니다.하지만 솔루션이 더 나은 이유를 설명 할 수 있다면 모든면에서 귀찮습니다. 다시 한 번 감사드립니다! –

+0

nahh ... 단순함은 아름다움입니다. 그런 다음 다른 솔루션으로 바꿀 수 있습니다. 문제를 만났을 때 .. :) 건배! 하지만 여전히 내 것이 좋다고 ... – Reigel

1

전나무 시도 요소에 맞춤 클래스를 태그하는 것입니다. 나는이 작동하지에 대한 참조

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

한 이유는 링크 대상을 열 페이지를 닫기 때문에이 실제로 서버로 전송되기 전에, 사파리는 $.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 요청에 오류가없는 경우에만 작동합니다.

더 나은 해결 방법은 클릭하여 로깅을 추가하고 원래 처리기를 호출하도록 링크 대상의 서버 측 처리기를 납치하는 것입니다.

+0

FYI,'event.preventDefault();'는'return false'와 거의 같습니다 ... (이 문제에서) 둘 다 할 필요는 없습니다 ... – Reigel

+0

핸들러를 두 번 이상 부착하는 것에 대해 지적 해 주셔서 감사합니다. 그리고 솔루션에 감사드립니다! 그것은 잘 작동합니다. 세 가지 제안이 모두 작동하므로 어떤 솔루션을 사용해야하는지 알기가 어렵습니다. 단순함과 개별적으로 사파리를 처리한다는 사실 때문에 Aaron과 함께 갈 것이라고 생각합니다.하지만 솔루션이 더 나은 이유를 설명 할 수 있다면 모든면에서 귀찮습니다. 다시 한 번 감사드립니다! –

관련 문제