13

iPad用のウェブアプリとしてゲームを作っています。画面の1つでイベントをトリガーするシェイクアクションが組み込まれていますが、情報収集フォームもあるため、そのシェイクアクションによって迷惑な「シェイクして元に戻す」ダイアログがトリガーされることがあります。ユーザーが入力したフォーム入力は、ユーザーがシェイクアクションに到達したときに、DOMに存在しなくなったため、元に戻す機能はトリガーされるべきではありませんが、残念ながらトリガーされます。これをネイティブラッパー(PhoneGapまたはその他)でラップする方法はないので、CSSまたはJavaScriptを使用して、特定のWebページ/アプリでこの機能を無効にできるかどうか誰かが知っているかどうか疑問に思いました。

ありがとう。

4

9 に答える 9

9

このブログでは、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();
});

私が考えることができるもう1つのことは、テキスト入力を使い終わった後で読み取り専用アイテムに変換することです。おそらく、私はテストしていませんが、読み取り専用の入力フィールドは元に戻る機能を利用できません。入力がDOMの一部でなくなった後でも、機能が起動するのは奇妙なことです。

CSSの-webkit-プロパティを使用してシェイクアクションを防止できるかどうかはわかりません。これは、Webkit固有のCSSプロパティのリストです(アクセス可能なプロパティの100%が含まれていない場合があります)。

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

于 2011-06-29T12:42:10.777 に答える
9

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];
}
于 2013-05-09T11:39:56.323 に答える
4

最近、ユーザーがWebSocketを使用してデバイスをペアリングするゲームを開発しているときに、この問題に遭遇しました。残念ながら、上記の解決策はどれも機能しません。

つまり、このゲームでは、ユーザーが携帯電話のフォームを介してチャンネルに登録する必要がありました。サブスクライブすると、デバイスを振ると、デスクトップでシナリオが実行されます。問題は、誰かがiOSデバイスを振ると、「入力解除」アラートがポップアップすることでした。

これが私がこの問題のために見つけた唯一の2つの解決策です。

  1. 入力がフォーカスを失うのを防ぎます。これにより、入力がフォームの一部である場合、フォームの送信を防ぐ必要があります。また、アンカーを「クリック」する代わりに「タッチスタート」をリッスンし、タッチスタートイベントが伝播しないようにする必要があります。これにより、アンカーがフォーカスを獲得し、入力がフォーカスを失うのを防ぎます。このアプローチには確かにいくつかの欠点があります。

  2. 「キーダウン」イベントハンドラーをウィンドウに追加し、イベントが伝播しないようにします。これにより、iOSデバイスの入力に値が挿入されるのを防ぎます。また、キーコードを適切な文字にマップするオブジェクトを作成する必要がありました。入力に必要なのは6文字のコードだけだったので、数字だけが必要だったので、これが私が行き終えたルートです。数字だけでは足りない場合、これはお尻の痛みかもしれません。キーダウン時に、キーコードを介してその文字を取得し、入力の値を設定します。これにより、iOSは、キーボードを介して入力に値が挿入されたことがないため、元に戻すことはできないと思い込ませます。

キーダウンイベントが伝播しないようにしても、標準の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); 
于 2013-04-24T17:17:42.587 に答える
4

Objective-C

「-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions」内にコード行を追加するだけです。

[application setApplicationSupportsShakeToEdit:NO];

スイフト2.x

appDelegate.swiftdidFinishLaunchingWithOptionsメソッドに1行のコードを追加します

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
}
于 2014-08-05T15:19:58.383 に答える
1

おそらくevent.preventDefault();、DeviceMotionEventリスナーで試してみてください。

Stack Overflowを見回すと、他の人がCSSを使用してデフォルトの「イベント」を無効にすることに成功していることがわかります(奇妙なことに)。

iOS MobileSafariでデフォルトのプレスを防止しますが、デフォルトのドラッグは禁止しますか?

于 2011-06-29T12:06:49.967 に答える
1

参照:UITextFieldがシェイクジェスチャに応答しないようにする方法は?

phonegapの場合、AppDelegate.mのwebViewFinishLoadメソッド内でこのプロパティを設定します

于 2012-10-05T00:01:51.120 に答える
1

最初の解決策

最も簡単な方法は、このプラグインを使用することです。

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

2番目の解決策

上記のプラグインを使用したくない場合は、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];
}

3番目の解決策

これは、テキスト入力で機能する「ShakeToUndo」を無効にするように設計した別のソリューションです。ユーザーは絵文字を挿入できないことに注意してください。

<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>
于 2017-04-18T20:19:07.863 に答える
1

一貫して機能する回避策を見つけました。フレームでテキスト入力をホストできます。入力が完了したら、ページからフレームを削除します。これでうまくいくようです。

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/

于 2018-06-21T10:09:23.683 に答える
0

入力をiframeに入れ、入力が不要なときにiframeをリロードします。

于 2016-03-15T06:19:23.950 に答える