Я работаю над одностраничным приложением (SPA), где мы моделируем многостраничное приложение с HTML 5 history.pushState
. Он отлично выглядит визуально, но он не корректно работает в iOS Voiceover. (Я предполагаю, что это не сработает ни в одном экране, но Voiceover - это то, что я пытаюсь сделать первым.)
Вот пример поведения, которого я пытаюсь достичь. Вот две обычные веб-страницы:
1.html
<!DOCTYPE html><html>
<body>This is page 1. <a href=2.html>Click here for page 2.</a></body>
</html>
2.html
<!DOCTYPE html><html>
<body>This is page 2. <a href=1.html>Click here for page 1.</a></body>
</html>
Приятный и простой. Voiceover читает это следующим образом:
Загружена веб-страница. Это страница 1.
[проведите пальцем вправо] Нажмите здесь, чтобы перейти на страницу 2. Ссылка.
[двойное нажатие] Загружена веб-страница. Это страница 2.
[проведите пальцем вправо] Нажмите здесь, чтобы перейти на страницу 1. Посетили. Link.
[двойное нажатие] Загружена веб-страница. Это страница 1.
Здесь это снова как одностраничное приложение, использующее манипуляции с историей для имитации фактических загрузок страниц.
spa1.html
<!DOCTYPE html><html>
<body>This is page 1.
<a href='spa2.html'>Click here for page 2.</a></body>
<script src="switchPage.js"></script>
</html>
spa2.html
<!DOCTYPE html><html>
<body>This is page 2.
<a href='spa1.html'>Click here for page 1.</a></body>
<script src="switchPage.js"></script>
</html>
switchPage.js
console.log("load");
attachHandler();
function attachHandler() {
document.querySelector('a').onclick = function(event) {
event.preventDefault();
history.pushState(null, null, this.href);
drawPage();
}
}
function drawPage() {
var page, otherPage;
// in real life, we'd do an AJAX call here or something
if (/spa1.html$/.test(window.location.pathname)) {
page = 1;
otherPage = 2;
} else {
page = 2;
otherPage = 1;
}
document.body.innerHTML = "This is page " + page +
".\n<a href='spa"+otherPage+".html'>Click here for page " +
otherPage + ".</a>";
attachHandler();
}
window.onpopstate = function() {
drawPage();
};
(Обратите внимание, что этот образец не работает из файловой системы, вам нужно загрузить его с веб-сервера.)
Этот пример SPA визуально выглядит точно так же, как простой многостраничный пример, за исключением того, что страница 2 "загружается быстрее" (потому что она совсем не загружается, все это происходит в JS).
Но в Voiceover это не так.
Загружена веб-страница. Это страница 1.
[проведите пальцем вправо] Нажмите здесь, чтобы перейти на страницу 2. Ссылка.
[double tap] Нажмите здесь, чтобы перейти на страницу 1. Посетили. Link.
[Основное внимание уделяется ссылке! проведите пальцем влево] Это страница 2.
[проведите пальцем вправо] Нажмите здесь, чтобы перейти на страницу 1. Посетили. Link.
[двойное нажатие] Загружена веб-страница. Это страница 1.
Основное внимание уделяется ссылке, когда она должна быть в верхней части страницы.
Как сообщить Voiceover, что вся страница только что обновлена, и поэтому читатель должен возобновить чтение в верхней части страницы?