28 сСнтября 2021

🍏 ВзаимодСйствиС SwiftUI с Π²Π΅Π±ΠΎΠΌ. Π§Π°ΡΡ‚ΡŒ 3: JavaScript – инструкция для Π½ΠΎΠ²ΠΈΡ‡ΠΊΠΎΠ²

ΠœΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ с 9 Π»Π΅Ρ‚Π½ΠΈΠΌ стаТСм.
Π’ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΌΡ‹ Ρ€Π°Π·Π»ΠΎΠΆΠΈΠ»ΠΈ ΠΏΠΎ ΠΏΠΎΠ»ΠΎΡ‡ΠΊΠ°ΠΌ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ Π² WebView. Π‘Π°ΠΌΠΎΠ΅ врСмя Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ, ΠΊΠ°ΠΊ ΠΏΠΎΠ΄Ρ€ΡƒΠΆΠΈΡ‚ΡŒ SwiftUI с JavaScript, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π±Π΅Π· этого языка программирования Π½Π΅ обходится Π½ΠΈ ΠΎΠ΄ΠΈΠ½ соврСмСнный сайт ΠΈΠ»ΠΈ мобильноС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.
🍏 ВзаимодСйствиС SwiftUI с Π²Π΅Π±ΠΎΠΌ. Π§Π°ΡΡ‚ΡŒ 3: JavaScript – инструкция для Π½ΠΎΠ²ΠΈΡ‡ΠΊΠΎΠ²

ΠœΡ‹ ΡƒΠΆΠ΅ Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ (ΠΊΠΎΠ΄ доступСн Π½Π° GitHub – ΠΏΡ€ΠΈΠΌ. Ρ€Π΅Π΄.) пСрСчислСниС WebViewNavigationAction, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ описываСт Ρ‚Ρ€ΠΈ дСйствия: Π½Π°Π·Π°Π΄, Π²ΠΏΠ΅Ρ€Π΅Π΄, ΠΏΠ΅Ρ€Π΅Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ, Π° Π·Π°Ρ‚Π΅ΠΌ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ с ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ интСрфСйсом прилоТСния, Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠ΅ΠΉ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ с Π²Π΅Π±-страницы Π² Swift. БСгодня Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ рассмотрим Ρ€Π°Π±ΠΎΡ‚Ρƒ с JavaScript.

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ local.html

ΠŸΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΈΠΌ простой Ρ„Π°ΠΉΠ» HTML ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΠΌ Π΅Π³ΠΎ Π² WebView.

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΠ°ΠΏΠΊΡƒ www Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅. Π’Π½ΡƒΡ‚Ρ€ΡŒ ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ Ρ„Π°ΠΉΠ» local.html со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ содСрТимым:

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?
    
Π’Π°ΠΆΠ½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚!
Если readAccessURL ссылаСтся Π½Π° ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ», Ρ‚ΠΎ Webkit смоТСт Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΅Π³ΠΎ; Ссли это дирСктория, Ρ‚ΠΎ ΠΈ Ρ„Π°ΠΉΠ»Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Ρ‹ WebKit. Π’ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ ΠΌΡ‹ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ„Π°ΠΉΠ» ΠΈ всС описываСм Π²Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π³ΠΎ (стили, скрипты).

ΠŸΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΡƒΠ΅ΠΌ Ρ‡Ρ‚ΠΎ Ρƒ нас ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ!

А Π·Π°Ρ‡Π΅ΠΌ ΠΎΠ½ΠΎ всС?

На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‚ΡΡ Ρ‚Π°ΠΊΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ, ΠΊΠΎΠ³Π΄Π° Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Π²Π΅Π±-страницу с ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ΠΎΠΌ. Иногда ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ содСрТимого ΠΈ ΡΠΊΡ€Ρ‹Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, <header> Π²Π΅Π±-страницы, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ добавляСт ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½ΡƒΡŽ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΡŽ Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅. Π’ Π΄Ρ€ΡƒΠ³ΠΈΡ… случаях Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π°ΠΆΠ°Π» Π½Π° ΠΊΠ½ΠΎΠΏΠΊΡƒ OK (ΠΊΠΎΠ³Π΄Π° это событиС ΠΏΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»ΠΎ).

ΠžΡ‚Π»Π°Π΄ΠΊΠ° JavaScript
Π”Π°Π»Π΅Π΅ ΠΌΡ‹ рассмотрим ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с JavaScript ΠΈΠ· Swift, ΠΈ Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚. Если Π²Ρ‹ Π΅Ρ‰Π΅ Π½Π΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с Web тСхнологиями, Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΊΠ°ΠΊ JavaScript, HTML, CSS, Ρ‚ΠΎ Π½ΠΈΡ‡Π΅Π³ΠΎ ΡΡ‚Ρ€Π°ΡˆΠ½ΠΎΠ³ΠΎ. Π― расскаТу тСорСтичСский ΠΌΠΈΠ½ΠΈΠΌΡƒΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π·Π½Π°Ρ‚ΡŒ. ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ сцСнарии JavaScript Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, я Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ ΠΈΡ… Π² Π±Ρ€Π°ΡƒΠ·Π΅Ρ€Π΅. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ инструмСнты Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΈ протСстируйтС ΠΊΠΎΠ΄ Π² консоли.

Когда Π²Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚Π΅ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π² WKWebView, global scope (глобальная ΠΎΠ±Π»Π°ΡΡ‚ΡŒ видимости) ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠΎΠΉ, которая ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΠΊΡ€Π°Ρ…Ρƒ прилоТСния ΠΈΠ·-Π·Π° ошибок ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ³ΠΎ объявлСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ Ρ‚.ΠΏ.

ΠŸΠ°Ρ€Π° слов ΠΎ global scope

Π’ JavaScript ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ const для объявлСния констант ΠΈ let – для ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. Π’Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ var, Π½ΠΎ здСсь Ρ‚ΠΎΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ особСнности, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ привСсти Π² Π·Π°ΠΌΠ΅ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ.

ΠŸΠΎΡΠΊΡΠΏΠ΅Ρ€ΠΈΠΌΠ΅Π½Ρ‚ΠΈΡ€ΡƒΠΉΡ‚Π΅ с объявлСниСм ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. НапримСр, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ всСй Π²Π΅Π±-страницы 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();
    
Если Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Ρ‚ΡŒΡΡ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ области видимости (scope), ΠΏΡ€ΠΎΡ‡Ρ‚ΠΈΡ‚Π΅ этот пост.

Π‘Π΅Π»Π΅ΠΊΡ‚ΠΎΡ€Ρ‹

Π§Ρ‚ΠΎΠ±Ρ‹ произвСсти ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ дСйствия с элСмСнтами Π²Π΅Π±-страницы, Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π° Π½ΠΈΡ… ссылку. 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');
    
ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² нашСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π΅ самый ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ, Ρ‚ΠΎ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ Π½ΡƒΠΆΠ½ΠΎΠ΅. А Ссли Π² <head> ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ»ΠΈ Π΄Π²Π° Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°? НапримСр, ΠΌΠΎΠ³ Π±Ρ‹Ρ‚ΡŒ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π² шапкС сайта, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ описываСт Π±Ρ€Π΅Π½Π΄, Π° Π·Π° Π½ΠΈΠΌ слСдуСт Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Π΄Π°Π΅Ρ‚ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Ρƒ содСрТимого. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС Π½Π°ΠΌ Π±Ρ‹ ΠΏΡ€ΠΈΡˆΠ»ΠΎΡΡŒ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΡ‡Π½Ρ‹ΠΉ запрос.

ΠšΠ»Π°ΡΡΡ‹ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ±Ρ‰ΠΈΠ΅, Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ всСгда ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ Π²ΠΎ всСм Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π΅, ΠΈ Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ элСмСнта Π² 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.

Π‘Ρ‚ΠΎΠΈΡ‚ΡŒ ΠΎΡ‚ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ Π² JavaScript Π΅ΡΡ‚ΡŒ стрСлочныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΠ΄Π½Π°ΠΊΠΎ Ссли Π²Ρ‹ Π½Π΅Π·Π½Π°ΠΊΠΎΠΌΡ‹ с особСнностями языка, это ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π·Π°ΠΌΠ΅ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²ΠΎ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΡƒΡ‚Π°Π½ΠΈΡ†Ρ‹ с Ρ‚Π΅ΠΌ, ΠΊΡƒΠ΄Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ this, я использовал ΠΎΠ±Ρ‹Ρ‡Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π³Π΄Π΅ this Π² Ρ‚Π΅Π»Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° саму ΠΊΠ½ΠΎΠΏΠΊΡƒ.

Как ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ элСмСнта ΠΈΠ»ΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°?

БущСствуСт нСсколько способов Π² DOM API ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ элСмСнта, Π½ΠΎ Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ свои особСнности ΠΈ назначСния. Допустим ΠΌΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ нашСго названия title.

НапримСр, ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ свойств:

  • textContent
  • innerText

title.innerText ΠΈ title.textContent Π² Π΄Π°Π½Π½ΠΎΠΌ случаС Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ ΠΎΠ΄Π½ΠΈ ΠΈ Ρ‚Π΅ ΠΆΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹. Однако ΠΎΠ½ΠΈ вСсьма ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‚ΡΡ. textContent ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π½Π°ΠΌ Π΄Π°ΠΆΠ΅ тСкстовоС содСрТимоС Π±Π»ΠΎΠΊΠ° <style>.

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ‡Π°Ρ‰Π΅ всСго Π½Π°ΠΌ трСбуСтся ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Ρ‡ΠΈΡ‚Π°Π±Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚, Ρ‚ΠΎ innerText являСтся Π»ΡƒΡ‡ΡˆΠΈΠΌ Π²Ρ‹Π±ΠΎΡ€ΠΎΠΌ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ случаСв, Π½ΠΎ Π΅Π³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ зависит ΠΎΡ‚ стилСй. Если элСмСнт скрыт, Ρ‚ΠΎ ΠΌΡ‹ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ.

Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·Π½ΠΈΡ†Π° Π±Ρ‹Π»Π° явно Π²ΠΈΠ΄Π½Π°, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚Π΅ элСмСнт HTML ΠΈ посмотритС, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Π² этих свойствах.

Для Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ³ΠΎ изучСния смотритС Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° свойства outerText, innerHtml ΠΈ outerHtml.

ΠŸΠΎΡ€ΠΎΠΉ Π½Π°ΠΌ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹Ρ‚Π°Ρ‰ΠΈΡ‚ΡŒ Ρƒ элСмСнта <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)


    
Π’ этот ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ строку, которая прСдставляСт ΠΈΠ· сСбя ΠΊΠΎΠ΄ Π½Π° JavaScript ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. Если ΠΌΡ‹ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ явно, Ρ‚ΠΎ JavaScript runtime Π²Π΅Ρ€Π½Π΅Ρ‚ Π½Π°ΠΌ undefined. Для отслСТивания, ΠΊΠ°ΠΊΠΈΡ… Π»ΠΈΠ±ΠΎ Π±Π»ΠΎΠΊΠΎΠ² ΠΊΠΎΠ΄Π° Π½Π° JavaScript ΡƒΠ΄ΠΎΠ±Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² качСствС Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° true ΠΈΠ»ΠΈ false. Π’ completionHandler пСрСдаСтся Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ исполнСния скрипта ΠΈΠ»ΠΈ ошибка.

Π’ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ сказано, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ² этого ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Ρ€Π°Π²Π½ΠΎΡ†Π΅Π½Π΅Π½ Π²Ρ‹Π·ΠΎΠ²Ρƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°, Π³Π΄Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 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).
Рассмотрим Π΅Π³ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ. Π­Ρ‚ΠΎ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π΄Π°Π΅Ρ‚ Π½Π°ΠΌ Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ ΠΈ обСспСчиваСт ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΌΠ½ΠΎΠ³ΠΈΡ… ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ². ΠœΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для прСдотвращСния ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ² ΠΌΠ΅ΠΆΠ΄Ρƒ скриптами Π½Π° Π²Π΅Π±-страницС. Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ сцСнарии JavaScript Π² собствСнном WKContentWorld Π΄Π°Π΅Ρ‚ Π½Π°ΠΌ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΡƒΡŽ копию ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… срСды для измСнСния.

ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈΠ· шапки ΠΈ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ Π΅Π³ΠΎ Π² нашСм NavigationView. Для этого создадим Ρ„Π°ΠΉΠ» JSUserScripts.swift, Π³Π΄Π΅ напишСм сцСнарии JavaScript, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ страницу ΠΈ Π·Π°Π±ΠΈΡ€Π°Ρ‚ΡŒ ΠΈΠ· Π½Π΅Π΅ Π΄Π°Π½Π½Ρ‹Π΅.

НапишСм Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для получСния ΠΈ скрытия Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Π½Π° Π²Π΅Π±-страницС:

JSUserScripts.swift
        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” Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ.

Когда ΠΌΡ‹ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ с исполнСниСм сцСнариСв JavaScript, инициируя Π²Ρ‹Π·ΠΎΠ² ΠΈΠ· Swift, рассмотрим ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½Ρ‹ΠΉ процСсс – ΠΊΠ°ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ Swift ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ JavaScript.

Π’Π°ΠΊΡƒΡŽ ΠΊΠΎΠΌΠΌΡƒΠ½ΠΈΠΊΠ°Ρ†ΠΈΡŽ Π½Π°ΠΌ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» 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!

ΠœΠ•Π ΠžΠŸΠ Π˜Π―Π’Π˜Π―

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

Π’ΠΠšΠΠΠ‘Π˜Π˜

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ вакансию
ΠŸΡ€ΠΎΠ΄ΡƒΠΊΡ‚ΠΎΠ²Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΡ‚ΠΈΠΊ Π² ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ
ΠΏΠΎ ΠΈΡ‚ΠΎΠ³Π°ΠΌ собСсСдования
PHP Developer
ΠΎΡ‚ 200000 RUB Π΄ΠΎ 270000 RUB

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•