2011-01-19 33 views
9

việc triển khai vị trí địa lý khá tốt và có vài bước để quan sát nhưng chỉ khi thiếu điều, tôi đoán. Im không thể xem liệu người dùng có chấp nhận yêu cầu hay không (trước khi tôi nhận được đối tượng vị trí), tôi không biết nếu người dùng chỉ bỏ qua yêu cầu của tôi (trong thời gian chờ của tôi) hoặc yêu cầu bị mất (và gọi lại không thành công) được gọi là không có lý do).Phản hồi vị trí địa lý trong khi chấp nhận yêu cầu

Sẽ hữu ích khi đặt dấu thời gian khi người dùng chấp nhận yêu cầu, tôi không thể tìm thấy bất kỳ thứ gì mang lại cho tôi loại phản hồi đó.

Trả lời

6

Dựa trên sự hiểu biết mới của tôi về những gì bạn đang sau, bạn muốn một cái gì đó như thế này. (Tested: trong Opera - công trình, Firefox 3.6 & Chrome 8 - không quá nhiều (tôi cần thêm thời gian để debug))

Kịch bản: Trang cố gắng để có được vị trí ... nhưng người dùng bỏ qua dấu nhắc hoàn toàn do đó không có (chấp nhận hoặc từ chối) và vì yêu cầu vị trí không bao giờ được gửi đi, cũng không có thời gian chờ!

Dựa trên điều này, bạn có thể muốn thêm logic của riêng mình để xử lý trường hợp này. Vì mục đích của ví dụ này, tôi sẽ thử nghiệm phương thức "wrapper" của riêng mình. (Đối với kén cá chọn canh - Tôi không túng sử dụng globals vv Tôi chỉ cố gắng để có được một cái gì đó để làm việc)

navigator.geolocation.requestCurrentPosition = function(successCB, errorCB, timeoutCB, timeoutThreshold, options){ 
    var successHandler = successCB; 
    var errorHandler = errorCB; 
    window.geolocationTimeoutHandler = function(){ 
    timeoutCB(); 
    } 
    if(typeof(geolocationRequestTimeoutHandler) != 'undefined'){ 
    clearTimeout(window['geolocationRequestTimeoutHandler']);//clear any previous timers 
    } 
    var timeout = timeoutThreshold || 30000;//30 seconds 
    window['geolocationRequestTimeoutHandler'] = setTimeout('geolocationTimeoutHandler()', timeout);//set timeout handler 
    navigator.geolocation.getCurrentPosition(
    function(position){ 
     clearTimeout(window['geolocationRequestTimeoutHandler']); 
     successHandler(position); 
    }, 
    function(error){ 
     clearTimeout(window['geolocationRequestTimeoutHandler']); 
     errorHandler(error); 
    }, 
    options 
); 
}; 
function timeoutCallback(){ 
    alert('Hi there! we are trying to locate you but you have not answered the security question yet.\n\nPlease choose "Share My Location" to enable us to find you.'); 
} 
function successCallback(position){ 
    var msg = ''; 
    msg += 'Success! you are at: '; 
    msg += '\nLatitude: ' + position.coords.latitude; 
    msg += '\nLongitude: ' + position.coords.longitude; 
    msg += '\nAltitude: ' + position.coords.altitude; 
    msg += '\nAccuracy: ' + position.coords.accuracy; 
    msg += '\nHeading: ' + position.coords.heading; 
    msg += '\nSpeed: ' + position.coords.speed; 
    alert(msg); 
} 
function errorCallback(error){ 
    if(error.PERMISSION_DENIED){ 
    alert("User denied access!"); 
    } else if(error.POSITION_UNAVAILABLE){ 
    alert("You must be hiding in Area 51!"); 
    } else if(error.TIMEOUT){ 
    alert("hmmm we timed out trying to find where you are hiding!"); 
    } 
} 
navigator.geolocation.requestCurrentPosition(successCallback, errorCallback, timeoutCallback, 7000, {maximumAge:10000, timeout:0}); 

Khái niệm này là để thiết lập một bộ đếm thời gian đầu tiên (mặc định là 30 giây nếu không được thiết lập). Nếu người dùng không làm bất cứ điều gì trước khi bộ đếm thời gian hết hạn, một timeoutCallback được gọi.

Ghi chú:

  1. Một số giao diện người dùng (ví dụ như iPhone/iPad/iPod Safari) có thể làm cho Allow/Deny phương thức nhanh chóng - do đó người dùng có thể không thực sự tiếp tục cho đến khi họ chọn một cái gì đó (tôi muốn đề xuất chỉ để những người dùng này một mình và để giao diện người dùng mặc định xử lý mọi thứ
  2. Nếu người dùng Cho phép yêu cầu (muộn), thời gian chờ vẫn có thể kích hoạt trước khi phản hồi trở lại - Tôi không nghĩ bạn có thể làm gì
  3. Mã trên chỉ là một ví dụ ... nó cần làm sạch.
+0

giải pháp tuyệt vời, tôi đoán rằng sẽ điền vào trường hợp "thiếu" trong API đó. Có lẽ họ cũng sẽ mở rộng nó, nó vẫn là một dự thảo và có thể là một phản hồi quan trọng (không buộc người dùng chấp nhận thay vì quản lý trang web của bạn). Cảm ơn rất nhiều vì đã dành thời gian cho nó, bệnh cố gắng tạo ra một giải pháp crossbrowser ổn định;) – Maertz

+1

1, giải pháp rất thanh lịch. – fmark

+1

@tetra Vui lòng đăng lại liên kết đến giải pháp crossbrowser ổn định của bạn khi hoàn thành. – fmark

5

Nó là một phần của Geolocation API:

// navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options); 
navigator.geolocation.getCurrentPosition(
    function(position){ 
    //do something with position; 
    }, function(){ 
    //handle condition where position is not available 
    //more specifically you can check the error code... 
    //error.code == 1 
    if(error.PERMISSION_DENIED){ 
     alert("you denied me! "); 
    } 
}); 

Nếu bạn chỉ định errorCallback ... sau đó bạn có thể theo dõi nếu người dùng đã từ chối cung cấp quyền truy cập.

thể error codes bao gồm:

error.PERMISSION_DENIED (numeric value 1) 
error.POSITION_UNAVAILABLE (numeric value 2) 
error.TIMEOUT    (numeric value 3) 
+1

hi scunliffe, chức năng gọi lại chỉ được gọi khi người dùng chấp nhận hoặc từ chối quyền nhưng tôi cần một cái gì đó cung cấp cho tôi phản hồi khi người dùng chấp nhận yêu cầu trước khi thời gian chờ được kích hoạt.Đó là vấn đề của tôi, bạn có thể kích hoạt yêu cầu nhưng người dùng có thể bỏ qua nó và bạn sẽ không bao giờ biết điều gì sẽ xảy ra vì thời gian chờ chỉ kích hoạt khi người dùng chấp nhận yêu cầu – Maertz

+0

@tetra - có thể tôi đang thiếu thứ gì đó sau. Khi tôi sử dụng mã trên ... Nếu tôi từ chối yêu cầu, mã lỗi 'error.PERMISSION_DENIED' được đặt (giá trị là 1) vì vậy tôi biết người dùng đã từ chối mã đó. Nếu người dùng không cho phép thực hiện cuộc gọi ... thì nó sẽ tắt và nhận các liên kết. – scunliffe

+0

@tetra - thực sự tôi nghĩ rằng tôi biết những gì bạn đang sau. (Tôi đang thử nghiệm một số mã để thực hiện những gì bạn cần ...) – scunliffe

5

Tested nó thành công trong FF 3.5, Opera 10.6, Chrome8, IE6-8 ..

var succeed = function(obj) { 
    navigator.geolocation.received = true; 
    !navigator.geolocation.timedout?alert('GOT YAH'):alert('GOT YAH but user was to slow'); 
}; 
var failed = function(obj) { 
    navigator.geolocation.received = true; 
    !navigator.geolocation.timedout?alert('just failed'):alert('failed and user was to slow as well, tzz ._.'); 
}; 
var timedout = function() { 
    navigator.geolocation.timedout = true; // could be used for other callbacks to trace if its timed out or not 
    !navigator.geolocation.received?alert('Request timed out'):null;  
} 

// Extend geolocation object 
if (navigator.geolocation ) { 
    navigator.geolocation.retrievePermission = function retrievePermission(succeed,failed,options,timeout) { 
     this.received = false;    // reference for timeout callback 
     this.timedout = false;    // reference for other callbacks 
     this.getCurrentPosition.apply(this,arguments); // actual request 

     // Trigger timeout with its function; default timeout offset 5000ms 
     if (timeout) { 
      setTimeout(timeout.callback,timeout.offset || 5000); 
     } 
    } 

    // New location request with timeout callback 
    navigator.geolocation.retrievePermission(succeed,failed,{},{ 
     offset: 10000, // miliseconds 
     callback: timedout 
    }); 

// Awesome thingy is not implemented 
} else { 
    alert('geolocation is not supported'); 
} 

Với cách giải quyết chúng tôi biết nếu hết thời gian chờ yêu cầu, thậm chí khi gọi lại succeess/thất bại được gọi sau đó.

Các vấn đề liên quan