2017-04-25 21 views
10

I nie dlatego moje pytanie jest oznaczony jako duplikat this one, najpierw wykonanie kodu JavaScript z evaluateJavaScript jak pytanie tytułowe pokazuje, które to jest zupełnie różne od tego quesiton. Co więcej zauważyłem, że wypróbowałem odpowiedź w tym pytaniu bez powodzenia na końcu mojego ciała pytania.alert() nie działa w WKWebview evaluateJavaScript()

Używam wkwebview.evaluateJavaScript() funciton do wykonywania javascript w widoku wkwebview z swift3. Jednak alert() nie otworzyło okna dialogowego alertu. I nie ma żadnych błędów i problemów. Chociaż mogę użyć evaluateJavaScript() do wykonania kodu javascript w celu zmodyfikowania zawartości strony.

class WebViewController: UIViewController, WKScriptMessageHandler, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate { 
    var wk:WKWebView! 
    self.wk.navigationDelegate = self 
    self.wk.uiDelegate = self 
    self.wk.scrollView.delegate = self 
    self.wk.customUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:53.0) Gecko/20100101 Firefox/53.0" 

    ... 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     ... 
     let config = WKWebViewConfiguration() 
     self.wk = WKWebView(frame: CGRect(x: frame.minX, y: frame.minY+20, width: frame.width, height: frame.height-70), configuration: config) 
     self.wk.navigationDelegate = self 
     ... 
    } 


    ... 
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 
     print("Finished navigation to url \(String(describing: webView.url))") 
     //self.wk.evaluateJavaScript("document.getElementById('test').innerHTML = 'sssssssssssssss';", completionHandler: nil)   //this works well 
     self.wk.evaluateJavaScript("alert('aaaaaaa');", completionHandler: nil)  //this not show the alert dialog 
    } 
    ... 
} 

ja również odnoszą się do tego post i answer, podczas gdy pytanie nie jest na evaluateJavaScript. Dodaję WKUIDelegate dla mojego WebViewController i dodaje self.wk.uiDelegate = self do mojego viewDidLoad(), ale nic się nie zmienia.

dodane, poniżej konsoli. Log() umieść dziennik w konsoli, a alert() nie pojawi się w oknie dialogowym. I działa również sterownik UIAlertController.

self.wk.evaluateJavaScript("alert('aa');console.log('1234');var rect = document.getElementById('liveMovie').getBoundingClientRect();[rect.left, rect.top];") { 
    (result, error) -> Void in 
    if((result) != nil) 
    { 
     self.player?.view?.frame.origin.x = (result as! Array)[0] 
     self.player?.view?.frame.origin.y = (result as! Array)[1] 
    } 
} 

let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) 
alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in 
    if(true) 
    { 
    } 
})) 
+1

masz żadnej wzmianki o 'runJavaScriptAlertPanelWithMessage' metody delegata. Czy możesz dodać ten kod do swojego pytania? – Onato

+0

Nie użyłem tej metody w moim kodzie. 'UIAlertController' może działać w moim kodzie, ale' evaluateJavaScript' nie może 'alert()' –

+1

Dlatego to nie działa wtedy. Ta metoda jest wywoływana podczas uruchamiania javascript i 'alert()'. W tej metodzie zależy, czy zdecydujesz, co z tym zrobić. Zobacz przykład w odpowiedzi połączonej poniżej. – Onato

Odpowiedz

4

Istnieje działający przykład w this answer. Wygląda na to, że prawdopodobnie nie zaimplementowano poprawnie metody WKUIDelegate.

1

To moja wina. Nie mam zbyt dużego doświadczenia z WKWebview. Mam doświadczenie z Androidem XWalkview, i tam wykonać alert nie trzeba wdrożyć alert z kodem java. Więc tutaj też nie trafiłem, że nie muszę szybko i szybko wykonać alertdelegate.

Od answer of Onato, nauczyłem Swift wykonać alertprompt i confirm, straciłem realizacji tych delegata. Więc odnosimy się do this answer, dodaj poniżej implementację, wszystko działa.

func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, 
      completionHandler: @escaping() -> Void) { 

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet) 
    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in 
     completionHandler() 
    })) 

    present(alertController, animated: true, completion: nil) 
} 


func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, 
      completionHandler: @escaping (Bool) -> Void) { 

    let alertController = UIAlertController(title: nil, message: message, preferredStyle: .actionSheet) 

    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in 
     completionHandler(true) 
    })) 

    alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in 
     completionHandler(false) 
    })) 

    present(alertController, animated: true, completion: nil) 
} 


func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, 
      completionHandler: @escaping (String?) -> Void) { 

    let alertController = UIAlertController(title: nil, message: prompt, preferredStyle: .actionSheet) 

    alertController.addTextField { (textField) in 
     textField.text = defaultText 
    } 

    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: { (action) in 
     if let text = alertController.textFields?.first?.text { 
      completionHandler(text) 
     } else { 
      completionHandler(defaultText) 
     } 
    })) 

    alertController.addAction(UIAlertAction(title: "Cancel", style: .default, handler: { (action) in 
     completionHandler(nil) 
    })) 

    present(alertController, animated: true, completion: nil) 
} 
3

Przede wszystkim trzeba zaimplementować wymagane metody WKUIDelegate, w twoim przypadku trzeba zaimplementować:

 optional func webView(_ webView: WKWebView, 
     runJavaScriptAlertPanelWithMessage message: String, 
      initiatedByFrame frame: WKFrameInfo, 
      completionHandler: @escaping() -> Void) 
    { 
    // parameter **message** will hold your actual alert message. 

    // Write Your Customised code to display the alert message 

    }