ΠΡ ΡΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π² ΠΏΡΠΎΠ΅ΠΊΡ (ΠΊΠΎΠ΄ Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π½Π° GitHub β ΠΏΡΠΈΠΌ. ΡΠ΅Π΄.) ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½ΠΈΠ΅ WebViewNavigationAction, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ ΡΡΠΈ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ: Π½Π°Π·Π°Π΄, Π²ΠΏΠ΅ΡΠ΅Π΄, ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠ·ΠΈΡΡ, Π° Π·Π°ΡΠ΅ΠΌ ΡΠ°Π·ΠΎΠ±ΡΠ°Π»ΠΈΡΡ Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΠΈΠΌ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π½Π°Π²ΠΈΠ³Π°ΡΠΈΠ΅ΠΉ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΠ΅ΠΌ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ Ρ Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ Π² Swift. Π‘Π΅Π³ΠΎΠ΄Π½Ρ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ ΡΠ°ΡΡΠΌΠΎΡΡΠΈΠΌ ΡΠ°Π±ΠΎΡΡ Ρ JavaScript.
Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ local.html
Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΠ°ΠΏΠΊΡ www Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅. ΠΠ½ΡΡΡΡ ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ ΡΠ°ΠΉΠ» local.html ΡΠΎ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΡΠΌ:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>Local HTML</title>
<style>
body {
background: -webkit-linear-gradient(bottom left, #2b2f44 0%,#312442 100%);
text-align: center;
font-family: monospace;
font-weight: bold;
font-size: large;
}
.title {
color: #FFFFFF;
}
.container {
display: grid;
justify-content: center;
align-content: center;
grid-auto-flow: row;
gap: 12px;
}
.item {
max-width: 600px;
padding: 12px;
background: #000000;
border-radius: 5px;
color: #FFFFFF;
}
#ok {
background-color: #000000;
color: #FFFFFF;
font-size: medium;
padding: 12px;
}
</style>
</head>
<body>
<header>
<h1 class="title">Interaction with JavaScript</h1>
</header>
<div class="container">
<div class="item">
<h1>Swift</h1>
</div>
<div class="item">
<h1>JavaScript</h1>
</div>
<button id="ok">OK</button>
</div>
</body>
</html>
ΠΡΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π½Π΅ Π·Π°Π±ΡΠ΄ΡΡΠ΅ ΡΠΊΠ°Π·Π°ΡΡ create folder reference.
Π§ΡΠΎΠ±Ρ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ ΡΠ°ΠΉΠ» HTML, Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΡΠ°Π±ΠΎΡΠ°ΡΡ WebView, Π½ΠΎ Π΄Π»Ρ Π½Π°ΡΠ°Π»Π° ΠΎΠ±Π½ΠΎΠ²ΠΈΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ WebView Π² ContentView:
WebView(type: .local, url: "local", viewModel: viewModel)
ΠΠ΅ΡΠ½Π΅ΠΌΡΡ Π² WebView ΠΈ ΠΎΠ±Π½ΠΎΠ²ΠΈΠΌ Π»ΠΎΠ³ΠΈΠΊΡ Π² updateUIView:
func updateUIView(_ webView: WKWebView, context: Context) {
if let urlValue = url {
if type == .local {
if let localUrl = Bundle.main.url(forResource: urlValue, withExtension: "html", subdirectory: "www") {
webView.loadFileURL(localUrl, allowingReadAccessTo: localUrl.deletingLastPathComponent())
}
} else if type == .public {
if let requestUrl = URL(string: urlValue) {
webView.load(URLRequest(url: requestUrl))
}
}
}
}
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΌΠ΅ΡΠΎΠ΄:
func loadFileURL(_ URL: URL, allowingReadAccessTo readAccessURL: URL) -> WKNavigation?
ΠΡΠΎΡΠ΅ΡΡΠΈΡΡΠ΅ΠΌ ΡΡΠΎ Ρ Π½Π°Ρ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΎΡΡ!
Π Π·Π°ΡΠ΅ΠΌ ΠΎΠ½ΠΎ Π²ΡΠ΅?
ΠΠ° ΠΏΡΠ°ΠΊΡΠΈΠΊΠ΅ Π²ΡΡΡΠ΅ΡΠ°ΡΡΡΡ ΡΠ°ΠΊΠΈΠ΅ Π·Π°Π΄Π°ΡΠΈ, ΠΊΠΎΠ³Π΄Π° Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π³ΡΡΠ·ΠΈΡΡ Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΌ ΠΊΠΎΠ½ΡΠ΅Π½ΡΠΎΠΌ. ΠΠ½ΠΎΠ³Π΄Π° ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΡΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΠΈ ΡΠΊΡΡΡΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, <header> Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΠΈΠ·Π±ΡΡΠΎΡΠ½ΡΡ Π½Π°Π²ΠΈΠ³Π°ΡΠΈΡ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π Π΄ΡΡΠ³ΠΈΡ ΡΠ»ΡΡΠ°ΡΡ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°ΡΡ, ΡΡΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π½Π°ΠΆΠ°Π» Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡ OK (ΠΊΠΎΠ³Π΄Π° ΡΡΠΎ ΡΠΎΠ±ΡΡΠΈΠ΅ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»ΠΎ).
ΠΠΎΠ³Π΄Π° Π²Ρ Π±ΡΠ΄Π΅ΡΠ΅ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΠΊΠΎΠ΄ Π² WKWebView, global scope (Π³Π»ΠΎΠ±Π°Π»ΡΠ½Π°Ρ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ) ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΡ ΠΊ ΠΊΡΠ°Ρ Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈΠ·-Π·Π° ΠΎΡΠΈΠ±ΠΎΠΊ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΈ Ρ.ΠΏ.
ΠΠ°ΡΠ° ΡΠ»ΠΎΠ² ΠΎ global scope
ΠΠΎΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠΈΡΡΠΉΡΠ΅ Ρ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ . ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π²ΡΠ΅ΠΉ Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ document.title, ΠΊΠ°ΠΊ ΠΌΡ ΡΡΠΎ ΡΠΆΠ΅ Π΄Π΅Π»Π°Π»ΠΈ Π² ΠΏΡΠΎΡΠ»ΠΎΠΉ ΡΡΠ°ΡΡΠ΅. ΠΠ±ΡΡΠ²ΠΈΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ Ρ const, let.
ΠΡΠ»ΠΈ Π²Ρ Π²ΡΠΏΠΎΠ»Π½ΠΈΡΠ΅ Π² ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π· const title = document.title
, ΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΎΡΠΈΠ±ΠΊΡ. ΠΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΡΠ°Π²ΠΈΡΡ, Π΅ΡΠ»ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ const Π½Π° let ΠΈΠ»ΠΈ Π²Π²Π΅ΡΡΠΈ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΡ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ (local scope), Π·Π°ΠΊΠ»ΡΡΠΈΠ² ΠΊΠΎΠ΄ Π² ΡΠΈΠ³ΡΡΠ½ΡΠ΅ ΡΠΊΠΎΠ±ΠΊΠΈ:
{ const title = document.title; }
Π§ΡΠΎΠ±Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌ, ΡΡΠΎΠΈΡ ΠΎΠ±ΠΎΡΠ°ΡΠΈΠ²Π°ΡΡ ΠΊΠΎΠ΄ Π² ΡΡΠ½ΠΊΡΠΈΠΈ. ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ ΠΎΠ½ΠΈ Π΄Π°ΡΡ Π½Π°ΠΌ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π±ΡΡΡ ΡΠ²Π΅ΡΠ΅Π½Ρ, ΡΡΠΎ Π½Π΅ ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΡ ΠΎΡΠΈΠ±ΠΎΠΊ.
function getDocTittle() {
const title = document.title;
console.log(title);
}
getDocTitle();
Π‘Π΅Π»Π΅ΠΊΡΠΎΡΡ
Π§ΡΠΎΠ±Ρ ΠΏΡΠΎΠΈΠ·Π²Π΅ΡΡΠΈ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°ΠΌΠΈ Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ, Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π½Π° Π½ΠΈΡ ΡΡΡΠ»ΠΊΡ. Selectors API ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π½Π°ΠΌ ΠΏΡΠΎΡΡΠΎΠΉ ΠΈ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΡΠΉ ΡΠΏΠΎΡΠΎΠ± ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΠΈΠ· DOM (Document-Object-Model), ΡΠΎΠΏΠΎΡΡΠ°Π²Π»ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π·Π°Π΄Π°Π½Π½ΠΎΠΌΡ Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ΅ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Ρ ΡΠ΅Π»Π΅ΠΊΡΠΎΡΠΎΠ². Π‘ΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ Π΄Π²Π° ΠΌΠ΅ΡΠΎΠ΄Π°, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ ΠΊ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΡ (Document), ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ (Element), ΠΈ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ° (DocumentFragment):
- querySelector(selectors) Π²Π΅ΡΠ½Π΅Ρ ΠΏΠ΅ΡΠ²ΠΎΠ΅ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅. ΠΡΠ»ΠΈ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠΉ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ΠΎ, ΡΠΎ null.
- querySelectorAll(selectors) Π²Π΅ΡΠ½Π΅Ρ Π²ΡΠ΅ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΡ (NodeList), ΠΈΠ»ΠΈ ΠΏΡΡΡΠΎΠΉ NodeList, Π΅ΡΠ»ΠΈ ΠΈΡ
Π½Π΅Ρ.
ΠΠΎΠ³Π΄Π° ΡΠ°ΠΉΡΡ ΠΈΠΌΠ΅ΡΡ Ρ ΠΎΡΠΎΡΡΡ ΡΠ°Π·ΠΌΠ΅ΡΠΊΡ, ΡΠ°ΡΠ΅ Π²ΡΠ΅Π³ΠΎ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° (selectors) ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ CSS-ΠΊΠ»Π°ΡΡ, ID ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°, ΠΈΠΌΡ ΡΠ΅Π³Π° ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°. ΠΠ»Ρ Π΄Π»Ρ ΡΠΎΡΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π±ΠΎΠ»Π΅Π΅ ΡΠΎΡΠ½ΡΡ Π·Π°ΠΏΡΠΎΡΠΎΠ² ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ CSS-ΡΠ΅Π»Π΅ΠΊΡΠΎΡΠΎΠ².
Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ Π²ΡΠ΅ Π²ΡΡΠ΅ΠΈΠ·Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ΅ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ .
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π² <body> Π½Π° Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΠ΅ Ρ Π½Π°Ρ Π΅ΡΡΡ:
- <header> Π²Π½ΡΡΡΠΈ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ.
- <h1> c ΠΊΠ»Π°ΡΡΠΎΠΌ title.
- <div> β Π±Π»ΠΎΠΊ Ρ ΠΊΠ»Π°ΡΡΠΎΠΌ container, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡΡ:
- Π΄Π²Π° Π±Π»ΠΎΠΊΠ° <div> Ρ ΠΊΠ»Π°ΡΡΠΎΠΌ item, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡΡ:
- Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ <h1>;
- ΠΊΠ½ΠΎΠΏΠΊΠ° <button> Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ ok.
ΠΠΎΠ»ΡΡΠΈΠΌ Π½Π°Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ· ΡΠ΅Π³Π° <head>:
const h1 = document.querySelector('h1');
ΠΠ»Π°ΡΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±ΡΠΈΠ΅, Π° ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ Π²ΡΠ΅Π³Π΄Π° ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠ΅ Π²ΠΎ Π²ΡΠ΅ΠΌ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ΅, ΠΈ Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° Π² HTML Π΅ΡΡΡ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ Π°ΡΡΠΈΠ±ΡΡΡ.
ΠΡΡΠΈΠ±ΡΡ class β ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ . ΠΠ½ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ CSS ΠΈ JavaScript Π²ΡΠ±ΡΠ°ΡΡ ΠΈ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΡΠ΅Π»Π΅ΠΊΡΠΎΡΠΎΠ² CSS ΠΈΠ»ΠΈ ΡΡΠ½ΠΊΡΠΈΠΉ JavaScript.
ΠΡΠ»ΠΈ Ρ ΠΎΡΠΈΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΈΠΌΠ΅Π½Π½ΠΎ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ (title), ΡΠΎ Π»ΡΡΡΠ΅ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π±ΠΎΠ»Π΅Π΅ ΡΠΎΡΠ½ΡΠΌ Π·Π°ΠΏΡΠΎΡΠΎΠΌ. Π ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠΌ ΡΠ΅Π»Π΅ΠΊΡΠΎΡΠ΅, ΡΠΎΡΠΊΠ° ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΠΌΡ ΠΈΠΌΠ΅Π΅ΠΌ Π΄Π΅Π»ΠΎ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΊΠ»Π°ΡΡΠ°.
const title = document.querySelector('.title');
ΠΠ±Π° Π·Π°ΠΏΡΠΎΡΠ° Π²Π΅ΡΠ½ΡΠ»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ:
<h1 class="title">Interaction with JavaScript</h1>
ΠΠΎ Π²ΡΠΎΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΡ ΡΠΎΠΆΠ΅ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ Π½ΡΠΆΠ½ΠΎΠ΅, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΊΠ»Π°ΡΡΠ° title Π³ΠΎΠ²ΠΎΡΠΈΡ ΡΠ°ΠΌΠΎ Π·Π° ΡΠ΅Π±Ρ.
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΠΊΠ½ΠΎΠΏΠΊΡ Ρ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ ok:
const button = document.querySelector('#ok');
Π ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΠΎΠΌ ΡΠ΅Π»Π΅ΠΊΡΠΎΡΠ΅ ΡΠ΅ΡΠ΅ΡΠΊΠ° ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΡΡΠΎ ΠΈΠΌΡ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠ°.
Π Π΅Π·ΡΠ»ΡΡΠ°Ρ:
<button id="ok">OK</button>
ΠΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ Π·Π°ΠΏΡΠΎΡΠΎΠΌ, ΡΡΠΎΠ±Ρ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΠ΅Π³Π° div:
let divs = document.querySelectorAll("div")
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠΎΡΡΠΎΡΡΠΈΠΉ ΠΈΠ· ΡΡΠ΅Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² NodeList:
[div.container, div.item, div.item]
Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Π±ΠΎΠ»Π΅Π΅ ΡΠΎΡΠ½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² <h1> Π²Π½ΡΡΡΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² div.item:
let itemsContent = document.querySelectorAll("div.item h1");
C ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° forEach ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π±ΠΈΡΠ°ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ NodeList. ΠΡΠ²Π΅Π΄Π΅ΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π² ΠΊΠΎΠ½ΡΠΎΠ»Ρ:
itemsContent.forEach(function(title) { console.log(title.innerText)) }
Π‘ΠΊΡΡΡΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ²
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΠΎΠ±Ρ ΡΠΊΡΡΡΡ title, Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎΠΌ display:
title.style.display = 'none';
Π Π°Π·ΡΠΌΠ΅Π΅ΡΡΡ, ΠΏΡΠΈ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠΈ WebView ΡΠ»Π΅ΠΌΠ΅Π½Ρ ΡΠ½ΠΎΠ²Π° ΠΏΠΎΡΠ²ΠΈΡΡΡ.
Π‘ΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π»ΠΈ ΡΠ»Π΅ΠΌΠ΅Π½Ρ?
Π§Π°ΡΡΠΎ Π²ΡΡΡΠ΅ΡΠ°ΡΡΠ°ΡΡΡ Π·Π°Π΄Π°ΡΠ° β ΠΏΡΠΎΠ²Π΅ΡΠΊΠ° ΠΏΡΠΈΡΡΡΡΡΠ²ΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°. ΠΡΠ»ΠΈ Π²Ρ Π½Π΅ ΡΠΎΠ²ΡΠ΅ΠΌ ΡΠ²Π΅ΡΠ΅Π½Ρ Π² ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌΠΎΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅, ΠΎΠ±Π΅ΡΠ½ΠΈΡΠ΅ Π΅Π³ΠΎ Π² ΡΡΠ»ΠΎΠ²Π½ΡΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ if. ΠΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΏΠ΅ΡΠ²ΡΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π²ΡΠΎΡΠΎΠ³ΠΎ ΡΡΠΎΠ²Π½Ρ <h2>, ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π½Π΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ΅, ΠΈ ΡΠΊΡΡΡΡ Π΅Π³ΠΎ:
const h2 = document.querySelector('h2');
if(h2) { h2.style.display = 'none'; }
ΠΠ»ΠΈΠΊΠΈ ΠΈ ΡΠΎΠ±ΡΡΠΈΡ
JavaScript ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π½Π°ΠΌ ΠΌΠ΅ΡΠΎΠ΄ addEventListener, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ Π΄Π²Π° ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°:
- Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΡΠΎΠ±ΡΡΠΈΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, βclickβ.
- ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ΄, ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ ΡΠΎΠ±ΡΡΠΈΠ΅.
button.addEventListener('click', function(e) {
console.log(e);
console.log('OK Clicked');
});
ΠΡ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ ΡΠΎΠ±ΡΡΠΈΠ΅ click, ΠΈ ΠΏΠΎ Π½Π°ΠΆΠ°ΡΠΈΡ Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡ OK Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π² ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ: βOK Clickedβ.
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ Π΅, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΡΡΡ Π² ΡΡΠ½ΠΊΡΠΈΡ, ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ ΡΠ°ΠΌΠΎ ΡΠΎΠ±ΡΡΠΈΠ΅ click. Π ΡΠ°ΠΌΠΎΠΌΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΡΠ΅ΡΠ΅Π· e.target.
ΠΠ°ΠΊ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΈΠ»ΠΈ Π°ΡΡΠΈΠ±ΡΡΠ°?
Π‘ΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΏΠΎΡΠΎΠ±ΠΎΠ² Π² DOM API ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°, Π½ΠΎ Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ²ΠΎΠΈ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡΠΈ ΠΈ Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΈΡ. ΠΠΎΠΏΡΡΡΠΈΠΌ ΠΌΡ Ρ ΠΎΡΠΈΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΊΠΎΠ½ΡΠ΅Π½Ρ Π½Π°ΡΠ΅Π³ΠΎ Π½Π°Π·Π²Π°Π½ΠΈΡ title.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ ΡΠ²ΠΎΠΉΡΡΠ²:
- textContent
- innerText
title.innerText
ΠΈ title.textContent
Π² Π΄Π°Π½Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΠΎΠ΄Π½ΠΈ ΠΈ ΡΠ΅ ΠΆΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ. ΠΠ΄Π½Π°ΠΊΠΎ ΠΎΠ½ΠΈ Π²Π΅ΡΡΠΌΠ° ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ. textContent ΠΌΠΎΠΆΠ΅Ρ Π²Π΅ΡΠ½ΡΡΡ Π½Π°ΠΌ Π΄Π°ΠΆΠ΅ ΡΠ΅ΠΊΡΡΠΎΠ²ΠΎΠ΅ ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ Π±Π»ΠΎΠΊΠ° <style>.
Π§ΡΠΎΠ±Ρ ΡΠ°Π·Π½ΠΈΡΠ° Π±ΡΠ»Π° ΡΠ²Π½ΠΎ Π²ΠΈΠ΄Π½Π°, ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½Ρ HTML ΠΈ ΠΏΠΎΡΠΌΠΎΡΡΠΈΡΠ΅, ΡΡΠΎ Π±ΡΠ΄Π΅Ρ Π² ΡΡΠΈΡ ΡΠ²ΠΎΠΉΡΡΠ²Π°Ρ .
ΠΠΎΡΠΎΠΉ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ Π²ΡΡΠ°ΡΠΈΡΡ Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° <img> ΡΡΡΠ»ΠΊΡ Π½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠ°Ρ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π°ΡΡΠΈΠ±ΡΡΠ΅ src ΠΈΠ»ΠΈ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° <input>. Π‘Π΄Π΅Π»Π°ΡΡ ΡΡΠΎ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ:
let imgSrc = img.src;
const input = document.querySelector('#mylInput');
let inputValue = input.value
Run JS! Run!
Π ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ ΡΡΠ°ΡΡΠ΅ ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π»ΠΈ ΠΌΠ΅ΡΠΎΠ΄ evaluateJavaScript Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°. ΠΡΡΠ°Π½ΠΎΠ²ΠΈΠΌΡΡ Π½Π° Π½Π΅ΠΌ ΠΏΠΎΠΏΠΎΠ΄ΡΠΎΠ±Π½Π΅ΠΉ.
open func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Void)? = nil)
Π Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ ΡΠΊΠ°Π·Π°Π½ΠΎ, ΡΡΠΎ Π²ΡΠ·ΠΎΠ² ΡΡΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° ΡΠ°Π²Π½ΠΎΡΠ΅Π½Π΅Π½ Π²ΡΠ·ΠΎΠ²Ρ ΠΌΠ΅ΡΠΎΠ΄Π°, Π³Π΄Π΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ frame β nil ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΠ΅Ρ Π³Π»Π°Π²Π½ΡΠΉ ΡΡΠ΅ΠΉΠΌ, Π° Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ contentWorld β WKContentWorld.pageWorld:
public func evaluateJavaScript(_ javaScript: String, in frame: WKFrameInfo? = nil, in contentWorld: WKContentWorld, completionHandler: ((Result<Any, Error>) -> Void)? = nil)
ΠΠ°Π½Π½ΠΎΠ΅ ΡΠ»ΡΡΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΡΠΏΠ½ΠΎ Π½Π°ΡΠΈΠ½Π°Ρ Ρ iOS 14.
- WKFrameInfo ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΡΡΠ΅ΠΉΠΌΠ΅ Π½Π° ΡΡΡΠ°Π½ΠΈΡΠ΅.
- WKContentWorld β ΡΡΠΎΡ ΠΎΠ±ΡΠ΅ΠΊΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΊΠΎΠ΄Π° JavaScript, Ρ.Π΅. ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ ΠΊΠ°ΠΊ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΠ΅Π½ (namespace).
ΠΠΎΠ»ΡΡΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ· ΡΠ°ΠΏΠΊΠΈ ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ Π΅Π³ΠΎ Π² Π½Π°ΡΠ΅ΠΌ NavigationView. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΠ°ΠΉΠ» JSUserScripts.swift, Π³Π΄Π΅ Π½Π°ΠΏΠΈΡΠ΅ΠΌ ΡΡΠ΅Π½Π°ΡΠΈΠΈ JavaScript, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΌΠΎΠ΄ΠΈΡΠΈΡΠΈΡΠΎΠ²Π°ΡΡ ΡΡΡΠ°Π½ΠΈΡΡ ΠΈ Π·Π°Π±ΠΈΡΠ°ΡΡ ΠΈΠ· Π½Π΅Π΅ Π΄Π°Π½Π½ΡΠ΅.
ΠΠ°ΠΏΠΈΡΠ΅ΠΌ Π΄Π²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ Π΄Π»Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΈ ΡΠΊΡΡΡΠΈΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Π½Π° Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΠ΅:
let getHeaderTitle = """
function getHeaderTitle() {
const headerTitle = document.querySelector('h1.title');
return headerTitle.innerText;
}
getHeaderTitle();
"""
let hideHeaderTitle = """
function hideHeaderTitle() {
const headerTitle = document.querySelector('h1.title');
headerTitle.style.display = 'none';
}
hideHeaderTitle();
"""
Π’Π΅ΠΏΠ΅ΡΡ Π·Π°ΠΌΠ΅Π½ΠΈΠΌ ΡΡΠ°ΡΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ evaluateJavaScript ΡΠ»ΡΡΡΠ΅Π½Π½ΠΎΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print("didFinish")
self.parent.viewModel.isLoaderVisible.send(false)
webView.evaluateJavaScript(getHeaderTitle, in: nil, in: .defaultClient) { result in
switch result {
case .success(let value):
if let title = value as? String {
self.parent.viewModel.webTitle.send(title)
}
case .failure(let error):
print(error.localizedDescription)
}
}
webView.evaluateJavaScript(hideHeaderTitle, in: nil, in: .defaultClient)
}
Π‘Π²ΠΎΠΉΡΡΠ²ΠΎ .defaultClient
ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΠ΅Π½ (namespace) ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π΄Π»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
ΠΡΠ»ΠΈ Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π·Π°ΠΏΡΡΡΠΈΡΡ ΡΠΊΡΠΈΠΏΡ Π²Π½ΡΡΡΠΈ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π° ΠΈΠΌΠ΅Π½ ΡΠ΅ΠΊΡΡΠ΅ΠΉ Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ .page
webView.evaluateJavaScript(hideHeaderTitle, in: nil, in: .page)
Π’Π°ΠΊΠΆΠ΅ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π° ΠΈΠΌΠ΅Π½:
webView.evaluateJavaScript(hideHeaderTitle, in: nil, in: .world(name: "magic"))
Π Π½Π°ΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΡΠΎ ΠΈΠ·Π»ΠΈΡΠ΅ΡΡΠ²ΠΎ, Π½ΠΎ Π΅ΡΠ»ΠΈ Π±Ρ ΠΌΡ ΡΠΎΠ·Π΄Π°Π²Π°Π»ΠΈ Π²Π΅Π±-Π±ΡΠ°ΡΠ·Π΅Ρ Ρ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡΠΌΠΈ Π½Π° JavaScript, ΠΏΡΠΈΡΠ»ΠΎΡΡ Π±Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΠΎΠ΅ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΠ΅Π½ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ.
ΠΡΠ΅ ΠΎΠ΄ΠΈΠ½ ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠΈΡΠ΅Π» Π²ΠΌΠ΅ΡΡΠ΅ Ρ iOS 14:
public func callAsyncJavaScript(_ functionBody: String, arguments: [String : Any] = [:], in frame: WKFrameInfo? = nil, in contentWorld: WKContentWorld, completionHandler: ((Result<Any, Error>) -> Void)? = nil)
Π ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ functionBody, Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΡΡΠΎΠΊΠΈ ΠΌΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅ΠΌ ΡΠ°ΠΌΠΎ ΡΠ΅Π»ΠΎ ΡΡΠ½ΠΊΡΠΈΠΈ, Π° Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ arguments ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅, ΠΊΠΎΡΠΎΡΡΠ΅ Π±ΡΠ΄ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Ρ Π² ΡΡΠ½ΠΊΡΠΈΠΈ, ΡΡΠΎ ΠΎΡΠ΅Π½Ρ ΡΠ΄ΠΎΠ±Π½ΠΎ. Π’Π°ΠΊΠ°Ρ Π³ΠΈΠ±ΠΊΠΎΡΡΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π½Π°ΠΌ ΠΏΠ΅ΡΠ΅ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π±Π»ΠΎΠΊΠΈ ΠΊΠΎΠ΄Π° JavaScript.
ΠΠ°ΠΊ Π²ΠΈΠ΄Π½ΠΎ ΠΈΠ· Π½Π°Π·Π²Π°Π½ΠΈΡ, Async ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ ΡΡΡΠΎΠΊΠ° Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΡΡΠ΅Π½Π° ΠΊΠ°ΠΊ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½Π°Ρ ΡΡΠ½ΠΊΡΠΈΡ. Π ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ await ΠΈ ΡΠ°Π±ΠΎΡΠ°ΡΡ Ρ JavaScript-ΠΎΠ±Π΅ΡΠ°Π½ΠΈΡΠΌΠΈ (Promise). Π’Π°ΠΊΠ°Ρ ΡΠ΅Ρ Π½ΠΈΠΊΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ°, ΠΊΠΎΠ³Π΄Π° ΠΌΡ Π½Π΅ Π·Π½Π°Π΅ΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΈΠΌΠ΅Π½Π½ΠΎ Π±ΡΠ΄Π΅Ρ Π·Π°Π²Π΅ΡΡΠ΅Π½Π° ΡΠ°Π±ΠΎΡΠ° ΡΡΠ½ΠΊΡΠΈΠΈ ΠΈΠ»ΠΈ ΠΊΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΡΠΎ-ΡΠΎ Π·Π°ΠΏΡΡΡΠΈΡΡ ΡΠ΅ΡΠ΅Π· ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ setTimeout).
Π Π°ΡΡΠΌΠΎΡΡΠΈΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ²:
let hideAnyElement = """
const element = document.querySelector(selector);
element.style.display = 'none';
"""
let getElementInnerText = """
const element = document.querySelector(selector);
return element.innerText;
"""
ΠΡΠΏΠΎΠ»Π½ΠΈΠΌ JavaScript:
webView.callAsyncJavaScript(hideAnyElement, arguments: ["selector":"#ok"], in: nil, in: .defaultClient)
ΠΠΎΠ΄ ΡΡΠ°Π» ΡΠ»Π΅Π³Π°Π½ΡΠ½Π΅ΠΉ. Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΡΠ΅Π»Π΅ΠΊΡΠΎΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ² ΠΈ ΡΠΊΡΡΠ²Π°ΡΡ Π»ΡΠ±ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ.
ΠΠ°ΠΏΠΈΡΠ΅ΠΌ ΠΏΡΠΎΡΡΠΎΠ΅ ΠΎΠ±Π΅ΡΠ°Π½ΠΈΠ΅ (promise):
let setTimeoutFor = """
const myPromise = new Promise((resolve, reject) => {
window.setTimeout(function (){
resolve('foo');
}, timeout);
});
await myPromise;
return myPromise;
"""
ΠΡΠΏΠΎΠ»Π½ΠΈΠΌ JavaScript:
let timeout = 3000;
webView.callAsyncJavaScript(setTimeoutFor, arguments: [ "timeout":"\(timeout)"], in: nil, in: .defaultClient) { (result) in
switch result {
case .success(let response):
print("Done...");
print(response);
case .failure(let error):
print("Error...");
print(error)
}
}
ΠΠΎΡΠ»Π΅ ΡΡΠ΅Ρ ΡΠ΅ΠΊΡΠ½Π΄ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΡ ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ βfooβ Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.
Π’Π°ΠΊΡΡ ΠΊΠΎΠΌΠΌΡΠ½ΠΈΠΊΠ°ΡΠΈΡ Π½Π°ΠΌ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ ΡΠ΅Π°Π»ΠΈΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» WKScriptMessageHandler ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡ WKUserContentController, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ JavaScript Π² WKWebView. ΠΡΠΎΡΠΎΠΊΠΎΠ» WKScriptMessageHandler ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π²ΡΠ΅Π³ΠΎ ΠΎΠ΄Π½Ρ ΡΡΠ½ΠΊΡΠΈΡ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ· Π·Π°ΠΏΡΡΠ΅Π½Π½ΡΡ Π½Π° Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΠ΅ ΡΡΠ΅Π½Π°ΡΠΈΠ΅Π².
ΠΠ°ΠΏΠΈΡΠ΅ΠΌ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Coordinator, Π² ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΡΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ:
extension WebView.Coordinator: WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "messageAppHandler" {
if let body = message.body as? String {
print("Message body: \(body)")
}
}
}
}
Π ΠΌΠ΅ΡΠΎΠ΄Π΅ makeUIView (Π·Π΄Π΅ΡΡ ΠΌΡ ΡΠΎΠ·Π΄Π°Π΅ΠΌ WebView ΠΈ Π·Π°Π΄Π°Π΅ΠΌ Π΅Π³ΠΎ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ) ΡΠΊΠ°ΠΆΠ΅ΠΌ Π½Π°Ρ ΠΊΠ»Π°ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΈ Π΅Π³ΠΎ ΠΈΠΌΡ:
webView.configuration.userContentController.add(context.coordinator, contentWorld: .page, name: "messageAppHandler")
- ΠΡΠ³ΡΠΌΠ΅Π½Ρ name ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Π½Π°ΡΠ΅Π³ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ WKScriptMessageHandler. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ namΠ΅ (ΠΈΠΌΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ) ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ, ΠΊΠ°ΠΊΠΎΠΉ ΠΈΠΌΠ΅Π½Π½ΠΎ WKUserContentController ΠΎΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅.
- Π‘Π²ΠΎΠΉΡΡΠ²ΠΎ body ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ Π½Π°ΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ (ΡΡΡΠΎΠΊΡ ΠΈΠ»ΠΈ ΠΎΠ±ΡΠ΅ΠΊΡ JSON).
- ΠΠ° Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΠ΅, ΡΡΠΎΠ±Ρ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π½Π°ΡΠ΅ΠΌΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΡ, ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ Π²ΡΠ·Π²Π°ΡΡ Ρ Π½Π΅Π³ΠΎ ΠΌΠ΅ΡΠΎΠ΄ postMessage.
ΠΠΎΠ±Π°Π²ΠΈΠΌ ΡΠΊΡΠΈΠΏΡ Π½Π° Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ, ΠΈ ΠΎΡΠΏΡΠ°Π²ΠΈΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅:
<script type="text/javascript">
sendValueToApp();
function sendValueToApp() {
window.webkit.messageHandlers.messageAppHandler.postMessage('Hello from web page');
}
</script>
ΠΠ°ΠΏΡΡΡΠΈΠΌ ΠΈ ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ, ΡΡΠΎ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π½Π°ΡΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Ρ Π²Π΅Π±-ΡΡΡΠ°Π½ΠΈΡΡ Π² ΠΊΠΎΠ½ΡΠΎΠ»ΠΈ.
ΠΠ° ΡΡΠΎΠΌ ΠΏΠΎΠΊΠ° Π²ΡΠ΅. ΠΠΎΠ΄ ΠΏΡΠΎΠ΅ΠΊΡΠ° Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π½Π° Github.
P.S. Happy Code!
ΠΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ