Как внедрить обратный вызов JavaScript для обнаружения события onclick, используя iOS WKWebView? - PullRequest
0 голосов
/ 09 декабря 2018

Я использую WKWebView, чтобы показать веб-сайт с HTML-кодом, включающим три кнопки.Я хочу запустить код Swift в собственном приложении при нажатии определенной кнопки.

О HTML

Три кнопки выглядят следующим образом:

<input type="button" value="Edit Info" class="button" onclick="javascript:GotoURL(1)">
<input type="button" value="Start Over" class="button" onclick="javascript:GotoURL(2)">
<input type="button" value="Submit" class="button" onclick="javascript:GotoURL(3)">

GotoURL функция, которую они вызывают, выглядит следующим образом:

function GotoURL(site)
{
    if (site == '1')
        document.myWebForm.action = 'Controller?op=editinfo';
    if (site == '2')
        document.myWebForm.action = 'Controller?op=reset';
    if (site == '3')
        document.myWebForm.action = 'Controller?op=csrupdate';
    document.myWebForm.submit();
}

Текущая WKWebView Реализация

Когда я нажимаю любую из кнопок в веб-просмотре, эта функция вызывается на моем WKNavigationDelegate:

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    // ...?
}

Но, конечно, navigation непрозрачен и поэтому не содержит информации о том, на какую из трех кнопок нажал пользователь.

Какой самый простой способ определить, когда эта кнопканажал?

Я хочу отвечать, когда пользователь нажимает Отправить и игнорирует другие нажатия кнопок.

Я вижу некоторые другие подходы к переполнению стека с использованием WKUserContentController, но ониПохоже, что веб-сайт требует для вызова что-то вроде:

window.webkit.messageHandlers.log.postMessage("submit");

Я не контролирую этот веб-сайт, поэтому я не могу добавить эту строку в исходный код, и я не знаю лучший способ добавить его вправильное место, используя WKWebView.

Ответы [ 3 ]

0 голосов
/ 12 декабря 2018

Вы можете ввести код JS с помощью функции evaluateJavaScript() в WKWebView.Вы можете захватить все события onclick с помощью следующего кода JS, который обнаруживает только нажатие кнопки submit.Все оригинальные обработчики событий также будут запущены - не беспокойтесь!

document.addEventListener("click", function(e)
{
    e = e || window.event;
    //if(e.target.value == 'Submit') //you can identify this button like this, but better like:
    if(e.target.getAttribute('onclick') == 'javascript:GotoURL(3)')
    //if this site has more elements with onclick="javascript:GotoURL(3)"
    //if(e.target.value == 'Submit' && e.target.getAttribute('onclick') == 'javascript:GotoURL(3)')
    {
        console.log(e.target.value);
        //if you need then you can call the following line on this place too:
        //window.webkit.messageHandlers.log.postMessage("submit");
    }
});

//DO NOT add the next line in your code! It is only for my demo - buttons need this in my demo for execution
function GotoURL(site){}//DO NOT add this line! It is only for my demo!
<input type="button" value="Edit Info" class="button" onclick="javascript:GotoURL(1)">
<input type="button" value="Start Over" class="button" onclick="javascript:GotoURL(2)">
<input type="button" value="Submit" class="button" onclick="javascript:GotoURL(3)">
0 голосов
/ 13 декабря 2018

Пользовательские сценарии - это JS, которые вы вставляете на свою веб-страницу либо в начале загрузки документа, либо после завершения загрузки документа.Пользовательские сценарии являются чрезвычайно мощными, поскольку они позволяют настраивать веб-страницу на стороне клиента, позволяют внедрять прослушиватели событий и могут даже использоваться для внедрения сценариев, которые, в свою очередь, могут вызывать обратный вызов в приложении Native.Следующий фрагмент кода создает пользовательский сценарий, который внедряется в конце загрузки документа.Пользовательский сценарий добавляется к экземпляру WKUserContentController, который является свойством объекта WKWebViewConfiguration.

// Create WKWebViewConfiguration instance
  var webCfg:WKWebViewConfiguration= WKWebViewConfiguration()

  // Setup WKUserContentController instance for injecting user script
  var userController:WKUserContentController= WKUserContentController()

  // Get script that's to be injected into the document
  let js:String= buttonClickEventTriggeredScriptToAddToDocument()

  // Specify when and where and what user script needs to be injected into the web document
  var userScript:WKUserScript =  WKUserScript(source: js, 
                                         injectionTime: WKUserScriptInjectionTime.AtDocumentEnd
                                         forMainFrameOnly: false)

  // Add the user script to the WKUserContentController instance
  userController.addUserScript(userScript)

  // Configure the WKWebViewConfiguration instance with the WKUserContentController
  webCfg.userContentController= userController;

Ваша веб-страница может публиковать сообщения в собственном приложении с помощью метода window.webkit.messageHandlers.<name>.postMessage (<message body>).Здесь «имя» - это имя отправляемого сообщения.JS может отправить обратно любой объект JS в качестве тела сообщения, и объект JS будет автоматически сопоставлен с соответствующим собственным объектом Swift.Следующий фрагмент кода JS отправляет обратно сообщение, когда происходит событие нажатия кнопки на кнопке с идентификатором «ClickMeButton».

varbutton = document.getElementById("clickMeButton");
button.addEventListener("click", function() {
            varmessageToPost = {'ButtonId':'clickMeButton'};
            window.webkit.messageHandlers.buttonClicked.postMessage(messageToPost);
        },false);

Чтобы получать сообщения, отправленные вашей веб-страницей, ваше собственное приложение должно реализоватьпротокол WKScriptMessageHandler.Протокол определяет один обязательный метод.Экземпляр WKScriptMessage, возвращаемый в обратном вызове, может быть запрошен для получения подробной информации о отправляемом сообщении.

func userContentController(userContentController: WKUserContentController,
                           didReceiveScriptMessage message: WKScriptMessage) {

        if let messageBody:NSDictionary= message.body as? NSDictionary{
            // Do stuff with messageBody
        }

    }

Наконец, собственный класс, который реализует протокол WKScriptMessageHandler, должен зарегистрироваться в качестве обработчика сообщений с WKWebView следующим образом:

// Add a script message handler for receiving  "buttonClicked" event notifications posted 
// from the JS document
userController.addScriptMessageHandler(self, name: "buttonClicked")
0 голосов
/ 09 декабря 2018

Вы всегда можете ввести исходный код, используя evaluateJavaScript(_:) в веб-представлении.Оттуда либо замените обработчик событий на кнопках (отправив сообщение и затем вызвав исходную функцию в новом обработчике), либо добавьте обработчик событий на кнопках или элемент-предок, который фиксирует события щелчка и публикует сообщение.(Исходный обработчик событий также будет запущен.)

document.getElementById("submit-button").addEventListener("click", function () {
   window.webkit.messageHandlers.log.postMessage("submit");
});

Если у кнопок нет идентификатора, вы можете добавить обработчик в документ, который фиксирует все (всплывающие) события щелчка, а затем отправляет сообщениев зависимости от цели события (используя текст или местоположение кнопки в качестве определителя).

...