2011-06-29 39 views
12

Tôi đang xây dựng một trò chơi dưới dạng ứng dụng web cho iPad. Nó kết hợp một hành động lắc để kích hoạt một sự kiện cho một trong các màn hình, nhưng, vì nó cũng có một hình thức thu thập thông tin, đôi khi hành động lắc kích hoạt hộp thoại "Shake to Undo" gây phiền nhiễu. Biểu mẫu đầu vào mà người dùng đã nhập thậm chí không tồn tại trong DOM nữa khi người dùng đạt được hành động lắc, vì vậy trong đầu tôi, chức năng Hoàn tác không được kích hoạt, nhưng thật không may là nó. Không có cách nào có thể được gói trong một trình bao bọc gốc (PhoneGap hoặc khác), vì vậy tôi đã tự hỏi nếu có ai biết nếu nó có thể vô hiệu hóa chức năng này cho một trang web/ứng dụng cụ thể, thông qua CSS hay JavaScript?Cách tắt iOS "Lắc để hoàn tác" trong một ứng dụng web

Cảm ơn.

Trả lời

4

Gần đây tôi đã chạy vào vấn đề này trong khi phát triển một trò chơi mà một cặp người sử dụng thiết bị sử dụng WebSockets. Thật không may, không có giải pháp nào được đề cập ở trên.

Tóm lại, trò chơi liên quan đến người dùng đăng ký kênh thông qua biểu mẫu trên điện thoại của họ. Sau khi đăng ký, họ sẽ lắc thiết bị và một kịch bản sẽ phát ra trên màn hình của họ. Vấn đề là bất cứ khi nào ai đó lắc thiết bị iOS, cảnh báo "hoàn tác nhập" sẽ bật lên.

Dưới đây là hai giải pháp mà tôi đã tìm thấy cho vấn đề này.

  1. Ngăn đầu vào của bạn khỏi bị mất tiêu điểm. Điều này sẽ yêu cầu bạn ngăn chặn việc gửi biểu mẫu nếu đầu vào là một phần của biểu mẫu. Bạn cũng phải nghe "touchstart" thay vì "click" trên bất kỳ neo nào và ngăn sự kiện touchstart truyền bá. Điều này sẽ ngăn không cho neo đó tập trung và đầu vào của bạn khỏi mất tập trung. Cách tiếp cận này có một số nhược điểm cho chắc chắn.

  2. Thêm trình xử lý sự kiện "keydown" vào cửa sổ và ngăn sự kiện lan truyền. Điều này ngăn không cho bất kỳ giá trị nào được chèn vào đầu vào trên thiết bị iOS. Tôi cũng đã phải tạo một đối tượng ánh xạ mã phím tới ký tự thích hợp. Đây là con đường tôi đã kết thúc vì tất cả những gì tôi cần trong đầu vào của tôi là mã 6 ký tự nên tôi chỉ cần số. Nếu bạn cần nhiều hơn chỉ là con số này có thể là một nỗi đau trong ass. Khi nhấn phím, hãy lấy ký tự đó qua mã khóa và đặt giá trị của đầu vào. Điều này khiến cho iOS nghĩ rằng không có giá trị nào được chèn vào đầu vào thông qua bàn phím nên không có gì để hoàn tác.

Hãy nhớ ngăn ngừa sự kiện keydown truyền bá không ngăn đầu vào trên trình duyệt android cổ phiếu, vì vậy nó sẽ hoạt động bình thường. Nhưng đó là OK vì đây không phải là một vấn đề android. Bạn có thể ngăn không cho các giá trị trùng lặp được chèn vào bằng cách lắng nghe sự kiện đầu vào trên chính đầu vào và xóa trình nghe keydown nếu sự kiện này được nhận.

var codes = { 
    48: 0, 
    49: 1, 
    50: 2, 
    51: 3, 
    52: 4, 
    53: 5, 
    54: 6, 
    55: 7, 
    56: 8, 
    57: 9 
}, 
myInput = document.getElementById("myInput"); 

var keydownHelper = function (e) { 
    e.preventDefault(); 
    myInput.removeEventListener("input", inputHelper); 

    var val = myInput.value; 

    // Delete 
    if (e.keyCode === 8 && val.length) { 
    myInput.value = val.slice(0, val.length - 1); 
    return; 
    } 

    // If not a number, do nada 
    if (typeof codes[e.keyCode] === "undefined") { return; } 

    val += codes[e.keyCode]; 
    myInput.value = val; 
}; 

var inputHelper = function (e) { 
    e.preventDefault(); 
    window.removeEventListener("keydown", keydownHelper); 
}; 

myInput.addEventListener("input", inputHelper); 
window.addEventListener("keydown", keydownHelper); 
+0

Cảm ơn bạn đã chia sẻ! Tôi không ở vị trí để thiết lập một trường hợp thử nghiệm ngay bây giờ, nhưng câu trả lời của bạn dường như được nghiên cứu rất tốt và làm những gì tôi đã yêu cầu trong câu hỏi ban đầu, vì vậy tôi chấp nhận nó là đúng nếu không có ai bất kỳ phản đối nào :) –

1

Có thể thử event.preventDefault(); trong DeviceMotionDener listener của bạn?

Nhìn xung quanh Stack Overflow, tôi có thể thấy những người khác đã vô hiệu hóa thành công "sự kiện" mặc định bằng cách sử dụng CSS (kỳ quặc).

Prevent default Press but not default Drag in iOS MobileSafari?

9

Blog này mô tả một phát hiện rung rất đơn giản bằng cách sử dụng người nghe DeviceMotionEvent:

http://www.jeffreyharrell.com/blog/2010/11/creating-a-shake-event-in-mobile-safari/

Hãy thử đoạn mã sau để vô hiệu hóa hoàn tác sự kiện xảy ra:

window.addEventListener('devicemotion', function (e) { 
    // This is where you put your code for dealing with the shake event here 

    // Stop the default behavior from triggering the undo dialog (hopefully) 
    e.preventDefault(); 
}); 

Có là một điều khác mà tôi có thể nghĩ đến đó là biến đầu vào văn bản thành một từ chỉ đọc m sau khi bạn hoàn thành nó. Có lẽ, một lĩnh vực đầu vào chỉ đọc không thể sử dụng chức năng hoàn tác, mặc dù tôi đã không thử nghiệm nó. Thật lạ khi tính năng này kích hoạt ngay cả sau khi đầu vào không còn là một phần của DOM.

Tôi không chắc chắn nếu ngăn chặn hành động lắc có thể được thực hiện thông qua các thuộc tính -webkit- trong CSS. Dưới đây là danh sách các thuộc tính CSS cụ thể của webkit (có thể không chứa 100% thuộc tính có thể truy cập được).

http://qooxdoo.org/documentation/general/webkit_css_styles

+0

+1 từ tôi, ví dụ hay. –

+0

Ý tưởng hay, nhưng không may mắn thay. Ngay cả khi gắn (hoặc sử dụng chức năng ủy nhiệm của Zepto) sự kiện cho chính các phần tử đầu vào, hộp thoại Hoàn tác vẫn bật lên. –

+0

Ồ, và việc thiết lập đầu vào thành chỉ đọc vẫn làm cho hộp thoại bật lên, thật không may. –

7

Đối với PhoneGap Tôi chỉ chèn dòng này: [UIApplication sharedApplication] .applicationSupportsShakeToEdit = NO; trong lớp webViewDidFinishLoad và nó làm việc kỳ diệu cho tôi.

Chỉ cần đi đến MainViewController.m và thay đổi webViewDidFinishLoad trông như thế này:

- (void)webViewDidFinishLoad:(UIWebView*)theWebView 
{ 
    // Black base color for background matches the native apps 
    theWebView.backgroundColor = [UIColor blackColor]; 

[UIApplication sharedApplication].applicationSupportsShakeToEdit = NO; 

    return [super webViewDidFinishLoad:theWebView]; 
} 
3

Objective-C

Chỉ cần thêm dòng mã bên trong "- (BOOL) ứng dụng :(UIApplication *) didFinishLaunchingWithOptions ứng dụng: (NSDictionary *) launchOptions"

[application setApplicationSupportsShakeToEdit:NO]; 

Swift 2.x

Thêm dòng mã trong appDelegate.swift didFinishLaunchingWithOptions phương pháp

func ứng dụng (ứng dụng: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

application.applicationSupportsShakeToEdit = false 
    return true 
} 

Swift 3.x

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 

    application.applicationSupportsShakeToEdit = false 
    return true 
} 
+1

100% hoạt động này! –

0

Đặt đầu vào vào khung nội tuyến, tải lại iframe khi bạn không cần đầu vào.

1

giải pháp đầu tiên

Cách đơn giản nhất là sử dụng plugin này:

https://github.com/nleclerc/cordova-plugin-ios-disableshaketoedit

giải pháp thứ hai

Nếu bạn không muốn sử dụng các plugin trên thì bạn nên làm điều đó bằng tay bằng cách mở MainViewController.m và thay đổi webViewDidFinishLoad trông như thế này:

- (void)webViewDidFinishLoad:(UIWebView*)theWebView 
{ 
    // Black base color for background matches the native apps 
    theWebView.backgroundColor = [UIColor blackColor]; 

[UIApplication sharedApplication].applicationSupportsShakeToEdit = NO; 

    return [super webViewDidFinishLoad:theWebView]; 
} 

giải pháp thứ ba

đó là một giải pháp tôi được thiết kế để vô hiệu hóa "Shake Để Undo" mà hoạt động trên đầu vào văn bản. lưu ý rằng người dùng không được phép chèn biểu tượng cảm xúc.

<body> 
    <textarea cols="40" rows="8" name="textarea" id="textarea"></textarea> 

    <script> 
    textArea = document.getElementById("textarea"); 

    textArea.onkeypress = function(event){ 
     event.preventDefault(); 
     var nationUnicode=event.which; 
     var utf8=encodeURIComponent(String.fromCharCode(parseInt(nationUnicode, 10))); 
     if (utf8.search("%EF") != 0) //value is not an Emoji 
      textArea.value= textArea.value + String.fromCharCode(nationUnicode); 
    } 

    textArea.onkeydown = function (event){ 
     if (event.keyCode == 8){ 
      event.preventDefault(); 
      var txtval = textArea.value; 
      textArea.value = txtval.slice(0, - 1); 
     } 
    } 
    </script> 
</body> 
+0

cảm ơn bạn rất nhiều vì giải pháp 3! Chính xác những gì tôi đang tìm kiếm! Một số biểu tượng cảm xúc có vẻ đang hoạt động (ví dụ: flash) – vinni

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