Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript “如何禁用iOS”;“摇动以松开”;在网络应用程序中_Javascript_Ios_Ipad_Html_Iphone Web App - Fatal编程技术网

Javascript “如何禁用iOS”;“摇动以松开”;在网络应用程序中

Javascript “如何禁用iOS”;“摇动以松开”;在网络应用程序中,javascript,ios,ipad,html,iphone-web-app,Javascript,Ios,Ipad,Html,Iphone Web App,我正在为iPad开发一款网络应用程序。它包含一个震动动作来触发其中一个屏幕的事件,但是,由于它也有一个信息收集表单,有时震动动作会触发恼人的“震动撤销”对话框。用户输入的表单在用户到达shake操作时甚至不存在于DOM中,因此在我看来,不应该触发Undo函数,但不幸的是,它确实存在。无法将其包装在本机包装器(PhoneGap或其他)中,因此我想知道是否有人知道是否可以通过CSS或JavaScript对特定网页/应用禁用此功能 谢谢。也许可以尝试事件.preventDefault()在您的设备Mo

我正在为iPad开发一款网络应用程序。它包含一个震动动作来触发其中一个屏幕的事件,但是,由于它也有一个信息收集表单,有时震动动作会触发恼人的“震动撤销”对话框。用户输入的表单在用户到达shake操作时甚至不存在于DOM中,因此在我看来,不应该触发Undo函数,但不幸的是,它确实存在。无法将其包装在本机包装器(PhoneGap或其他)中,因此我想知道是否有人知道是否可以通过CSS或JavaScript对特定网页/应用禁用此功能


谢谢。

也许可以尝试
事件.preventDefault()
在您的设备MotionEvent侦听器中

环顾堆栈溢出,我可以看到其他人已经成功地使用CSS禁用了默认的“事件”(奇怪的是)


本博客介绍了一种使用DeviceMotionEvent listener的非常简单的震动检测:

请尝试以下代码以禁用以撤消发生的事件:

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();
});
我能想到的另一件事是,在完成文本输入后,将其转换为只读项。据推测,只读输入字段不能使用undo函数,尽管我还没有测试过它。奇怪的是,即使在输入不再是DOM的一部分之后,也会触发该特性

我不确定是否可以通过CSS中的-webkit-properties来防止震动。以下是特定于webkit的CSS属性列表(可能不包含100%的可访问属性)

参见:


对于phonegap,在AppDelegate.m中的webViewFinishLoad方法中设置此属性。我最近在开发一个用户使用WebSocket配对设备的游戏时遇到了此问题。不幸的是,上述解决方案都不起作用

简言之,游戏涉及用户通过手机上的表单订阅频道。一旦订阅,他们就会摇动设备,并在桌面上播放一个场景。问题是,每当有人晃动iOS设备时,“撤消键入”警报就会弹出

以下是我为这个问题找到的唯一两个解决方案

  • 防止您的输入失去焦点。如果输入是表单的一部分,则需要阻止表单提交。您还必须侦听任何锚上的“touchstart”而不是“click”,并防止touchstart事件传播。这将防止该锚获得焦点,并防止您的输入失去焦点。这种方法肯定有一些缺点

  • 向窗口添加一个“keydown”事件处理程序,并防止事件传播。这可以防止任何值插入到iOS设备上的输入中。我还必须创建一个对象,将关键码映射到适当的角色。这就是我结束这条路线的原因,因为我只需要输入6个字符的代码,所以我只需要数字。如果你需要的不仅仅是数字,这可能会让你头疼。在按下键时,通过键码勾住该字符并设置输入值。这让iOS误以为没有任何值通过键盘插入到输入中,因此没有什么可撤销的

  • 请记住,阻止keydown事件传播并不会阻止stock 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); 
    

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

    目标-C

    只需在“-(BOOL)application:(UIApplication*)application didnishlaunchingwithoptions:(NSDictionary*)launchOptions”中添加一行代码

    Swift 2.x

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
        application.applicationSupportsShakeToEdit = false
        return true
    }
    
    在appDelegate.swift didFinishLaunchingWithOptions方法中添加单行代码

    func应用程序(应用程序:UIApplication,didFinishLaunchingWithOptions启动选项:[NSObject:AnyObject]?)->Bool{

    Swift 3.x

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
        application.applicationSupportsShakeToEdit = false
        return true
    }
    

    将输入放入iframe,在不需要输入时重新加载iframe。

    第一种解决方案

    最简单的方法是使用此插件:

    第二种解决方案

    如果不想使用上述插件,则应手动打开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];
    }
    
    - (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>
    
    
    textArea=document.getElementById(“textArea”);
    textArea.onkeypress=函数(事件){
    event.preventDefault();
    var nationUnicode=event.which;
    var utf8=encodeURIComponent(String.fromCharCode(parseInt(nationUnicode,10));
    if(utf8.search(“%EF”)!=0)//值不是表情符号
    textArea.value=textArea.value+String.fromCharCode(nationUnicode);
    }
    textArea.onkeydown=函数(事件){
    如果(event.keyCode==8){
    event.preventDefault();
    var txtval=textArea.value;
    textArea.value=txtval.slice(0,-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;
        });
      });
    }
    

    这里有一个概念证明:

    好主意,但不幸的是运气不佳。即使在连接(或使用Zepto的代理)时也是如此