Подтвердить что ты не робот

Как отключить iOS "Встряхнуть, чтобы отменить" в webapp

Я создаю игру как webapp для iPad. Он включает в себя действие shake для запуска события для одного из экранов, но поскольку он также имеет форму сбора информации, иногда это действие встряхивания вызывает раздражающее диалоговое окно "Встряхнуть для отмены". Ввод формы, введенный пользователем, даже не существует в DOM, когда пользователь достигает действия shake, поэтому, на мой взгляд, функция Undo не должна запускаться, но, к сожалению, это не так. Нет никакого способа, чтобы это можно было обернуть в нативной оболочке (PhoneGap или другой), поэтому мне было интересно, знает ли кто-нибудь, можно ли вообще отключить эту функцию для определенной веб-страницы/приложения через CSS или JavaScript?

Спасибо.

4b9b3361

Ответ 1

Недавно я столкнулся с этой проблемой при разработке игры, в которой пользователь соединяет устройства с помощью WebSockets. К сожалению, ни одно из упомянутых выше решений не работает.

Короче говоря, в игре участвовал пользователь, подписывающийся на канал через форму на своем телефоне. После подписания они будут встряхивать устройство, и сценарий будет воспроизводиться на рабочем столе. Проблема заключалась в том, что в любое время, когда кто-то сотрясал iOS-устройство, всплывало предупреждение "undo typing".

Вот только два решения, которые я нашел для этой проблемы.

  • Предотвратите потерю фокуса. Это потребует от вас предотвращения отправки формы, если вход является частью формы. Вы также должны прослушивать "touchstart" вместо "click" на любых якорях и предотвращать распространение события touchstart. Это предотвратит захват фокуса, а ваш вход потеряет фокус. Этот подход имеет определенные недостатки.

  • Добавьте обработчик события "keydown" в окно и предотвратите распространение события. Это предотвращает внесение любых значений во входные данные на устройствах iOS. Мне также пришлось создать объект, который сопоставил ключевые коды с соответствующим символом. Это маршрут, который я закончил, потому что все, что мне нужно было на моем входе, было 6-символьным кодом, поэтому мне нужны только номера. Если вам нужно больше, чем просто цифры, это может быть болью в заднице. На клавише вниз зацепите этого символа с помощью кода клавиши и установите значение ввода. Это подводит iOS к мысли, что никакое значение никогда не было вставлено во вход через клавиатуру, поэтому нет ничего, что можно было бы отменить.

Имейте в виду, что предотвращение распространения события keydown не препятствует вводу в браузер Android Android, поэтому он будет нормально функционировать. Но это нормально, так как это не проблема с Android. Вы можете предотвратить добавление повторяющихся значений, прослушивая входное событие на самом входе и удаляя прослушиватель клавиатуры, если это событие получено.

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

Ответ 2

В этом блоге описывается очень простое обнаружение тряски с помощью прослушивателя 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();
});

Есть еще одна вещь, о которой я могу думать, которая будет заключаться в том, чтобы повернуть ввод текста в элемент readonly после того, как вы закончите с ним. Предположительно, поле ввода только для чтения не может использовать функцию отмены, хотя я ее не тестировал. Странно, что функция срабатывает даже после того, как вход больше не является частью DOM.

Я не уверен, что предотвращение действия shake можно выполнить с помощью свойств -webkit- в CSS. Ниже приведен список специфических свойств webkit CSS (которые могут не содержать 100% доступных свойств).

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

Ответ 3

Для PhoneGap я просто вставил эту строку:   [UIApplication sharedApplication].applicationSupportsShakeToEdit = НЕТ; в классе 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];
}

Ответ 4

Objective-C

Просто добавьте строку кода внутри приложения "- (BOOL): (приложение UIApplication *) doneFinishLaunchingWithOptions: (NSDictionary *) launchOptions"

[application setApplicationSupportsShakeToEdit:NO];

Swift 2.x

Добавьте одну строку кода в метод appDelegate.swift doneFinishLaunchingWithOptions

func application (application: 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
}

Ответ 5

Возможно, попробуйте event.preventDefault(); в вашем прослушивателе DeviceMotionEvent?

Оглядываясь на переполнение стека, я вижу, что другим людям удалось отключить "события" по умолчанию с помощью CSS (как ни странно).

Предотвращение по умолчанию Нажмите, но не по умолчанию Перетащите в iOS MobileSafari?

Ответ 7

Первое решение

Самый простой способ - использовать этот плагин:

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", который работает с текстовыми вводами. обратите внимание, что пользователям не разрешается вставлять emojis.

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

Ответ 8

Поместите ввод в iframe, перезагрузите iframe, когда вам не нужен вход.