Эффект параллакса в кросс-исходном фрейме с чистым JS? - PullRequest
0 голосов
/ 30 мая 2018

Итак, у меня есть документ, который содержит элемент iframe.

Мой документ и iframe имеют разные источники.

Я хочу сделать содержимое этогоiframe выглядит как параллакс при загрузке в документ.

Например, документ выглядит так:

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>blah</p>
<p>blah</p>
<p>blah</p>
<p>blah</p>
<iframe src="parallax.html" width="200" height="200">
<p>blah</p>
<p>blah</p>
<p>blah</p>
</body>
</html>

А файл parallax.html содержит только изображение, которое подходитдо размера окна.

Я думал, что parallax.html должен иметь скрипт, который определяет положение окна относительно экрана и корректирует положение изображения.Я пробовал что-то, например:

  • добавить прослушиватель события прокрутки в верхнее окно, но так как они междоменные, это ограничено
  • get document.body.scrollTop,но он всегда возвращает 0
  • get getBoundingClientRect() параметров, но top также возвращает 0

Возможно ли это? Я что-то упустил?И да, я должен сделать это с помощью vanilla JS, без jQuery или других библиотек.

1 Ответ

0 голосов
/ 30 мая 2018

Как вы заметили, ограничения по происхождению делают это несколько хитрым.Ваш родительский фрейм не сможет получить доступ к внутренним переменным или установить слушателей в своем дочернем фрейме, и наоборот.Существует очень ограниченный набор свойств, к которым он может получить доступ, для просмотра здесь: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy#Cross-origin_script_API_access

Более того, я считаю, document.body.scrollTop и getBoundingClientRect() внутри iframe относятся к самому фрейму, как если бы фрейм былмини-окно.Вы, вероятно, не сможете получить доступ к нужной информации в iframe, но сможете получить ее из родительского фрейма.

Использование postMessage

Традиционный способ передачи информации междуфреймы перекрестного происхождения должны использовать iframe .contentWindow.postmessage.

В этом случае простая реализация заключается в том, чтобы прикрепить прослушиватель прокрутки к родительскому кадру, который отправляетсообщение вашему детскому фрейму.Это будет выглядеть примерно так:

В родительском документе :

var iframeElement = document.getElementById('my-parallax'); // give your iframe this id
window.addEventListener('scroll', () => {
  var rect = iframeElement.getBoundingClientRect();
  var dataToSend = {
    scrollY: window.scrollY,
    left: rect.left, right: rect.right,
    bottom: rect.bottom, top: rect.top
  };
  var targetOrigin = '*'; // can change this if you know it
  iframeElement.contentWindow.postMessage(dataToSend, targetOrigin);
});

Затем в parallax.html :

window.addEventListener('message', function (e) {
  var data = e.data;
  if (e.source === window.parent) { // check if the sender was the parent
    // use data.scrollY, data.top... etc. here
  }
});

Предостережение в этом подходе (и с postMessage в целом) заключается в том, что нет гарантии, что пользовательский интерфейс iframe будет обновляться синхронно с родительским окном.Разница должна быть незначительной, если только в одном кадре нет значительных вычислений.Насколько я знаю, это неизбежно при работе с междоменными фреймами.

...