Мой авторесайз IFRAME

    Прочитав статейку Дмитрия Котерова о ресайзе ифрэймов решился поделиться своим решением.

    Этим решением пользуемся на продуктивном сайте.

    Итак, дано:
    1. Нужно показывать в ифрэйме страницы с других доменов без скроллбара
    2. Внутри ифрэйма могут совершаться переходы
    3. Сайты в ифрэйме могут менять высоту без перегрузки (AJAX или просто раскрытие каких-нибудь невидимых элементов)
    4. Во включаемые страницы должно включаться кода по минимуму
    5. Решение не должно портить историю посещение браузера и должно работать в актуальных версиях популярных браузеров
    6. Решение должно работать в обоих случаях master.site и www.master.site

    Решение:

    Нам нужно на основном сайте master.site создать два файлика iframe_height.js и height.html.

    На самой странице создаем ифрэйм с id=«iframe». Во включаемую страницу с домена slave.site в head добавляем ссылку на жаваскрипт http://master.site/iframe_height.js

    iframe_height.js:
    var __hc = {<br>  i: null, // используется для периодической проверки высоты<br>  h: 0, // предыдущая установленная высота<br>  iframes: [null, null], // создаем два ифрэйма<br>  path: 'master.com/height.html#', // путь до height.html<br>  // созание невидимых ифрэймов для установки высоты<br>  setHeight: function(height) {<br>    var ifr,i;<br>    for (i=0;i<2;i++) {<br>      if (this.iframes[i]) this.iframes[i].parentNode.removeChild(this.iframes[i]);<br>      ifr = document.createElement('IFRAME');<br>      ifr.style.display = 'none';<br>      this.iframes[i] = ifr;<br>      document.body.appendChild(this.iframes[i]);<br>      ifr.src = 'http://' + (i ? 'www.' : '') + this.path + height;<br>    }<br>  },<br>  // выполняется после загрузки окна — устанавливаем высоту и запускаем периодическую проверку<br>  onLoad: function(full) {<br>    this.checkHeight();<br>    if (full) {<br>      this.i = window.setInterval(this.bind(this.checkHeight), 100);<br>    }<br>  },<br>  // проверка высоты, если не изменилась с прошлой проверки<br>  checkHeight: function() {<br>    var h = this.getDocHeight();<br>    if (this.h == h) return;<br><br>    this.h = h;<br>    this.setHeight(this.h);<br>  },<br>  // если определена функция для определения высоты используем ее, иначе ползуемся общей реализацией<br>  getDocHeight: function() {<br>    if (window.GetDocumentHeight) return window.GetDocumentHeight();<br>    var D = document;<br>    return Math.max(<br>      D.body.scrollHeight, D.documentElement.scrollHeight,<br>      D.body.offsetHeight, D.documentElement.offsetHeight,<br>      D.body.clientHeight, D.documentElement.clientHeight<br>    );<br>  },<br>  // служебные методы<br>  addEvent: function(o, t, h) {<br>    if (o.addEventListener) o.addEventListener(t, h, false);<br>    else if (o.attachEvent) o.attachEvent('on'+t, h);<br>  },<br>  bind: function (method) {<br>    var context = this, args = arguments;<br>    return function() {<br>      return method.apply(context, Array.prototype.slice.call(args, 1));<br>    };<br>  },<br>  // инициализация<br>  init: function(full) {<br>    this.addEvent(window, 'load', this.bind(this.onLoad, full));<br>  }<br>};<br><br>__hc.init(true);<br><br>* This source code was highlighted with Source Code Highlighter.

    height.html:
    <html><head><br><script type="text/javascript"><br>  // весь location.hash – это высота<br>  var l = location.hash.replace('#', '');<br>  if (l) {<br>    // используем try catch чтобы браузер не матерился<br>    try {<br>      parent.parent.document.getElementById('iframe').style.height = l + 'px';<br>    } catch(e) {}<br>  }<br></script><br></head><br></html><br><br>* This source code was highlighted with Source Code Highlighter.

    Смысл в том, что ифрэйм внутри ифрэйма имеет доступ к главному окну, если он располагается на том же домене.

    Открываю я два ифрэйма, потому как решение с document.domain имеет свои недостатки, которые на моем сайте довольно тяжело устранить.

    При этом решении не портится история браузера, т.к. рабочие ифрэймы каждый раз заново создаются.

    height.html – не достается каждый раз с сервака, а берется из кэша браузера

    Насчет определения высоты документа в ифрэйме, кроссбраузерного решения я не нашел. При уменьшении контента в ифрэйме, сам ифрэйм не уменьшается, потому как, например, в вебкитовких браузерах и document.body, и document.documentElement разворачиваются по высоте ифрэйма. Для этого я проверяю, если определена функция GetDocumentHeight, используем ее. Т.е. Если на каком-то сайте не устраивает подсчет высоты, то можно реализовать свою функцию — для конкретных случаев это намного проще, чем использовать универсальную.

    Вообщем, жду критику.
    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 7

      0
      Спасибо, очень вовремя…

      Комменты чуть попозже, нужно время что бы объездить это решение.
        0
        если от айфрейма нужно чтобы он просто был id=«iframe» то не работает к сожалению.

        bananalassi.ru/index_new.html

        в меню две кнопки, каждая загружает в основной iframe файлы action2.html и news2.html

        Как видно iframe не ресайзится никак
          0
          Все работает.

          По твоей ссылке у ифрэйма id=«mainframe», поэтому и не проходит фокус. Либо id ифрэйма поменяй на «iframe», либо подправь height.html.

          А вообще, если это реальный документ, в котором ты собрался использовать это решение, то это перебор. Если и родительский и дочерний ифрэйм расположены на одном домене, то они имеют прямой доступ друг к другу. Т.е. решение можно очень упростить.
          0
          и правда заработало, спасибо!
          с id просто забыл залить на сервер, но осталась одна проблема — при скрипты работают только когда кликаешь по ссылкам. по умолчанию iframe обрезает контент. можно конечно вручную выставить height, но делать этого не хочется — наверняка есть и другое решение.

          Согласен, что перебор. Но, к сожалению, мои знания не позволяют, самостоятельно написать такой скрипт, а все что нагуглил к тому моменту либо не работало вообще, либо не работало во всех браузерах.
            0
            Дело в том, что ифрэймы это вообще зло, и пользоваться ими нужно только тогда, когда без них не обойтись. В твоем случае они точно лишние. Например щелкни правой кнопкой мыши на пункт меню и выбери «открыть в новом окне». Так же сайт будет выглядеть при переходе с поисковых систем. Конечно и это можно обойти при желании, вообщем, смотри сам.
              0
              А Какая альтернатива? Чем заменить фреймы при условии, что навигация необходима?
                0
                Походи по интернету, посмотри на разметку сайтов. Подавляющее большинство сайтов сделано без ифрэймов. И довольно сложно представить себе сайт без навигации.

          Only users with full accounts can post comments. Log in, please.