簡體   English   中英

如何在webapp中禁用iOS“Shake to Undo”

[英]How to disable iOS “Shake to Undo” in a webapp

我正在構建一個游戲作為iPad的webapp。 它結合了一個搖動動作來觸發其中一個屏幕的事件,但是,由於它還有一個信息收集表單,有時搖動動作會觸發惱人的“搖動撤消”對話框。 當用戶到達搖動動作時,用戶輸入的表單輸入甚至不再存在於DOM中,所以在我看來不應該觸發撤銷功能,但不幸的是它是。 沒有辦法將它包裝在本機包裝器(PhoneGap或其他)中,所以我想知道是否有人知道是否可以通過CSS或JavaScript禁用特定網頁/應用程序的此功能?

謝謝。

此博客描述了使用DeviceMotionEvent偵聽器進行的非常簡單的抖動檢測:

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

嘗試使用以下代碼禁用撤消事件發生:

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

我還可以想到另一件事就是在完成后將文本輸入轉換為只讀項目。 據推測,只讀輸入字段不能使用撤銷功能,但我還沒有測試過。 奇怪的是,即使輸入不再是DOM的一部分,該功能也會觸發。

我不確定是否可以通過CSS中的-webkit-屬性來防止抖動操作。 以下是webkit特定CSS屬性的列表(可能不包含100%可訪問的屬性)。

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

對於PhoneGap,我剛剛插入了這一行:[UIApplication sharedApplication] .applicationSupportsShakeToEdit = NO; 在webViewDidFinishLoad類中,它為我創造了奇跡。

只需轉到MainViewController.m並將webViewDidFinishLoad更改為如下所示:

- (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];
}

我最近遇到了這個問題,同時開發了一個用戶使用WebSockets配對設備的游戲。 遺憾的是,上述解決方案都不起作用。

簡而言之,游戲涉及用戶通過手機上的表格訂閱頻道。 一旦訂閱,他們就會動搖設備並在他們的桌面上播放一個場景。 問題是每當有人震動iOS設備時,都會彈出“撤消打字”警報。

以下是我為此問題找到的唯一兩個解決方案。

  1. 防止您的輸入失去焦點。 如果輸入是表單的一部分,這將要求您阻止表單提交。 您還必須在任何錨點上偵聽“touchstart”而不是“click”,並防止touchstart事件傳播。 這樣可以防止錨點獲得焦點,輸入也不會失去焦點。 這種方法肯定有一些缺點。

  2. 向窗口添加“keydown”事件處理程序並阻止事件傳播。 這可以防止任何值插入到iOS設備上的輸入中。 我還必須創建一個將鍵碼映射到正確字符的對象。 這是我結束的路線,因為我輸入的所有內容都是6個字符的代碼所以我只需要數字。 如果你需要的不僅僅是數字,這可能是一個痛苦的屁股。 在按鍵時,通過鍵碼捕獲該字符並設置輸入值。 這讓iOS認為沒有任何值通過鍵盤輸入到輸入中,所以沒有任何東西可以撤消。

請記住,防止keydown事件傳播不會阻止在股票android瀏覽器上輸入,因此它將正常運行。 但這沒關系,因為這不是一個Android問題。 您可以通過偵聽輸入本身的輸入事件來防止插入重復值,並在收到此事件時刪除keydown偵聽器。

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

Objective-C的

只需在“ - (BOOL)應用程序:(UIApplication *)應用程序中添加代碼行didFinishLaunchingWithOptions:(NSDictionary *)launchOptions”

[application setApplicationSupportsShakeToEdit:NO];

Swift 2.x

在appDelegate.swift didFinishLaunchingWithOptions方法中添加單行代碼

func應用程序(應用程序: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
}

請參閱: 如何阻止UITextField響應搖動手勢?

對於phonegap,請在AppDelegate.m中的webViewFinishLoad方法中設置此屬性

第一解決方案

最簡單的方法是使用這個插件:

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

二解決方案

如果你不想使用上面的插件,那么你應該通過打開MainViewController.m手動完成它,並將webViewDidFinishLoad更改為如下所示:

- (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];
}

第三種方案

這是我設計的另一個解決方案,禁用“Shake To Undo”,它可以處理文本輸入。 請注意,不允許用戶插入表情符號。

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

也許嘗試event.preventDefault(); 在您的DeviceMotionEvent偵聽器中?

看看Stack Overflow,我可以看到其他人已成功使用CSS禁用默認“事件”(奇怪)。

防止默認按iOS而不是默認拖動iOS MobileSafari?

將輸入放入iframe,在不需要輸入時重新加載iframe。

我找到了一致的解決方法:您可以在框架中托管文本輸入。 完成輸入后,從頁面中刪除框架。 這似乎可以解決問題。

function resetIframe() {
  // Remove the old frame
  document.body.removeChild(frame);

  // Create a new frame that has an input internally
  frame = document.createElement('iframe');
  frame.src = '/html-with-input.html';
  frame.style = 'border: 0; height: 30px; width: 200px;'
  document.body.appendChild(frame);

  // When the frame is ready, grab a reference to the input
  frame.addEventListener('load', () => {  
    const input = frame.contentDocument.body.querySelector('input');
    console.log(frame, frame.contentDocument.body)

    // When the input changes, grab the value
    input.addEventListener('input', e => {
      document.getElementById('output').innerText = e.target.value;
    });
  });
}

這是一個概念證明: https//codepen.io/joshduck/full/RJMYRd/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM