【问题标题】:iOS 11.3 WKWebView: input.focus() doesn't do anythingiOS 11.3 WKWebView:input.focus() 没有做任何事情
【发布时间】:2018-03-31 12:40:42
【问题描述】:

自从更新到 iOS 11.3 后,HTML 输入字段无法再使用 JavaScript .focus() 聚焦,除非函数调用紧跟在触摸交互之后(过去可以随时使用 .focus())。有已知的解决方法吗?

【问题讨论】:

    标签: javascript html ios safari wkwebview


    【解决方案1】:

    向元素添加点击功能以调用焦点功能就可以了。还是有更好的解决方案?

    <html>
    <head>
            <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
            <meta charset="UTF-8">
            <meta name="apple-mobile-web-app-capable" content="yes" />
            <meta name="apple-mobile-web-app-status-bar-style" content="black">
            <meta name="format-detection" content="telephone=no, email=no">            
    </head>
    <body>
        <input id="test" type="text" placeholder="test" />
        <input id="test2" type="text" placeholder="test" />
    
        <script src="https://cdn.bootcss.com/fastclick/1.0.6/fastclick.js"></script>
        <script>
            window.FastClick.attach(document.body);
            document.getElementById('test').onclick = function(e) {
              // works fine
              e.target.focus();
            };
            document.getElementById('test2').onclick = function(e) {
              // not working
              setTimeout(function() {
                e.target.focus();
              }, 50)
            };
        </script>
    </body>
    </html>
    

    【讨论】:

    • 你能解释一下你的答案吗
    • 只需添加onclick触发焦点
    【解决方案2】:

    focus()之前调用blur().....

    【讨论】:

      【解决方案3】:

      这是我们目前在应用程序开发框架中使用的代码,用于使 input.focus() 工作。确认在 App Store 中工作并被 Apple 接受:

      Class class = NSClassFromString(@"WKContentView");
      NSOperatingSystemVersion iOS_11_3_0 = (NSOperatingSystemVersion){11, 3, 0};
      NSOperatingSystemVersion iOS_12_2_0 = (NSOperatingSystemVersion){12, 2, 0};
      NSOperatingSystemVersion iOS_13_0_0 = (NSOperatingSystemVersion){13, 0, 0};
      
      if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_13_0_0]) {
          SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:");
          Method method = class_getInstanceMethod(class, selector);
          IMP original = method_getImplementation(method);
          IMP override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
          ((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
          });
          method_setImplementation(method, override);
      }
      else if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_12_2_0]) {
          SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:");
          Method method = class_getInstanceMethod(class, selector);
          IMP original = method_getImplementation(method);
          IMP override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
          ((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
          });
          method_setImplementation(method, override);
      }
      else if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_11_3_0]) {
          SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:");
          Method method = class_getInstanceMethod(class, selector);
          IMP original = method_getImplementation(method);
          IMP override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
              ((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
          });
          method_setImplementation(method, override);
      } else {
          SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:");
          Method method = class_getInstanceMethod(class, selector);
          IMP original = method_getImplementation(method);
          IMP override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, id arg3) {
              ((void (*)(id, SEL, void*, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3);
          });
          method_setImplementation(method, override);
      }
      

      【讨论】:

      • 您好,七,您能告诉我您在代码库中的确切位置插入了这些行吗?谢谢。
      • Hello Louis -- 在初始化 WKWebView 之后。但是,从那时起,该代码已针对较新的 iOS 版本进行了扩展……现在将对其进行更新。
      【解决方案4】:

      似乎他们已经向 repo 推送了一些更新:

      https://github.com/ionic-team/cordova-plugin-wkwebview-engine/pull/171#issuecomment-377824347

      因此,请确保删除 cordova ios 平台,添加最新版本的 wkwebview:cordova-plugin-ionic-webview 1.1.19,然后添加 npm install 并添加平台 ios。我刚刚测试过它就像一个魅力。

      【讨论】:

      • 我没有使用 Cordova,但经过多次谷歌搜索后,我已经找到了一种新的方式来嘶嘶作响(或者它是嘶嘶作响?)相关的 WebKit 功能。还是非常感谢!
      • @SevenSystems 您能否分享您找到的解决方案?到目前为止,我们也不使用 Cordova,并且一直在解决这个问题。
      猜你喜欢
      • 2012-09-07
      • 2016-10-02
      • 2013-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多