Ми можемо використовувати window.location.replace
для уникнення історії та націлювання на якірні сторінки без перезавантаження сторінок, але не в iframe?
Проблема полягає в порушенні CSP (політики безпеки вмісту), яка script-src 'unsafe-inline'
повинна бути включена. За винятком того, що у мене не визначено CSP, і навіть якщо я визначу його та дозволю, script-src 'unsafe-inline'
він все одно дає ту саму помилку порушення. Той самий результат у ie11 / chrome / ff.
Iframe на тому самому домені (у тому самому каталозі).
- Націліть на рамку iframe та використовуйте
window.location.replace('/samepage.html#onpage_anchor')
в консолі. - це працює. Він орієнтований на якір сторінки, не завантажуючи сторінку та без історії.
- Помістіть той самий код в рядку на якірних посиланнях, і він працює.
- Використовуйте той самий код у зовнішньому скрипті, отримайте помилку порушення csp. Це чудово працює, якщо не в iframe.
Я спробував створити ПЕС , щоб дія, але навіть не в більшості дозвільних політик безпеки контенту можливо дозволять його.
Редагувати: тому я зібрав приклади на plunker, який дозволяє кілька файлів, щоб я міг використовувати належні hrefs, які посилаються на батьківські / дочірні сторінки.
Примітки щодо прикладів планку:
Проблема не відтворена в цих прикладах. Сценарій працює чудово, навіть у iframe. Однак той самий код не працює на моєму локальному сервері, або коли я запускаю його наживо на VPS.
Я підозрюю, що порушення CSP не спрацьовує на plunker, оскільки plunker представляє вміст у браузері через якийсь шар абстракції.
Перший раз, коли ви натискаєте посилання на гармошку у батьків, це викликає оновлення. Це тому, що те, що сторінка завантажується спочатку, не посилається на index.html. Подальші кліки працюють, як очікувалося, без перезавантаження сторінок. Не проблема в iframe, оскільки вона спочатку посилається на child.html
Це хороші приклади, щоб показати код, не вимагаючи змін для його роботи (як у необхідності змінити hrefs, щоб вони працювали у фрагментах stackoverflow, згаданих нижче). Це також добре, як показує, що javascript працює як слід. Але це не показує насправді проблеми. Вам все одно потрібно буде завантажити його у свій редактор і запустити його на локальному сервері або в реальному середовищі хостингу, щоб побачити справжню проблему.
Приклади Плункер
Зі сценарієм: Без історії
Без сценарію: З історією
Приклад спрощеного коду
Простий акордеон з одним записом. Достатньо для відтворення питання.
Клацання відкрити / закрити розширить / згорнуть гармошку, не потрібно JS. JS повинен робити саме те ж саме, але без історії. Добре працює, але не в рамці.
Примітки фрагмента коду:
Ви можете запустити фрагмент, щоб отримати уявлення про те, що я описую, але це насправді не демонструє проблеми.
Фрагмент поводиться не так, як це було б у реальному браузері, javascript не працює.
У фрагменті відображається код, але його слід запустити в рамку iframe, щоб побачити проблему. Запустіть його поза рамкою iframe, щоб побачити різницю та як вона має працювати.
- Через те, як посилання працюють з JS (замінюючи весь URL), вони насправді повинні бути подібними до цього,
href="https://stackoverflow.com/thispage.html#ac1"
а не просто так,href="#ac1"
як вони з'являються у фрагменті (не може орієнтуватися на фактичну сторінку HTML у фрагменті). Отже, якщо ви спробуєте це у своєму редакторі (будь ласка), тоді не забудьте змінити посилання на цей формат,this_document.html#anchor
щоб вони все одно були якорями сторінки, але page.html включена у посилання.
Сценарій
$(document).ready(function() {
// anchor links without history
$.acAnch = function(event) {
event.preventDefault();
var anchLnk = $(event.target);
var anchTrgt = anchLnk.attr('href');
window.location.replace(anchTrgt);
}
// listen for anchor clicks
$('.accordion').on('click', 'a', $.acAnch);
});
Це дуже просто:
1. Функція acAnch бере href
атрибут і скидає його window.location.replace()
.
2. Прослухайте клацання якоря в гармошці, щоб запустити функцію acAnch.
Отже, весь сценарій працює window.location.replace('/this_same_page.html#on_page_anchor')
Якщо ви помістите це в консоль, це працює, порушення CSP не буде. Але запустити його із зовнішнього скрипту не працює.
Inline за посиланнями працює добре:
onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"
Якщо встановити, що на відповідних посиланнях працює чудово , але я дійсно вважаю за краще не використовувати вбудований сценарій, як це. Має бути спосіб зробити це за допомогою зовнішнього сценарію.
Я спробував запустити javascript на батьківському, а не в iframe (з модифікаціями, щоб вибрати посилання в дочірніх програмах). Той самий результат помилки CSP.
Чому я це роблю?
Ну сайт набагато складніший за приклад. Якіри в iframes добре працюють, але вони додають історію. Якщо ви запускаєте код вище без JavaScript, (або просто запустіть фрагмент), відкрийте та закрийте акордеон кілька разів та скористайтесь кнопкою "Назад", вона повернеться через відкриті закриті стану.
Я не заперечував би проти історії, але якщо вона знаходиться в кадрі iframe, коли ви залишаєте батьківську сторінку і повертаєтесь до неї, історія в iframe порушена. Повернення вже не повертається через стан гармошок, а натомість просто продовжує перезавантажувати кадр iframe. Спочатку прив’язки не спричиняють перезавантаження iframe, а лише кроки через історію стану гармошок, яка працює добре, поки ви не залишите сторінку та не повернетесь назад. Потім назад вже не проходить через стани гармошки, а просто проходить через купу однакових iframe-перезавантажень. Це дуже недоброзичлива поведінка користувачів.
Мені не потрібно використовувати location.replace, якщо є інший метод, який буде працювати. Хоча я спробував багато інших підходів, і я виявив, що методи, які можуть досягти однакового результату, як правило, призводять до тієї ж помилки.
Мета - просто активувати якірні посилання на сторінці без перезавантаження та без історії, всередині iframe.
Вбудований сценарій працює. Чи можемо ми змусити його працювати у зовнішньому файлі .js?
<a href="#ac0" class="ac-close">Close</a>
має працювати.