Яндекс.Виджет + adjustIFrameHeight + MooTools

image
Многие знают о такой клёвой штуке как Яндекс.Виджет.
Сделать свой функциональный виджет проще простого, достаточно написать серверный виджет и подключить его к Яндекс.Виджет через iframe.

Для управления виджетом Яндекс предоставляет API в виде JS объекта widget, в частности с помощью него можно изменять высоту фрейма под динамический контент (adjustIFrameHeight), это позволяет избавиться от вертикальной полосы прокрутки. Но у этого API есть существенный минус — он написан с использованием jQuery, что лишает разработчиков виджетов на MooTools использовать Widget API.

Ниже я покажу, как довольно просто можно в обход Widget API управлять высотой фрейма, используя MooTools на стороне виджета.


Как известно из содержимого фрейма нельзя получить доступ к объекту самого фрейма, если они находятся на разных доменах. Для обхода этого ограничения Widget API использует проксирующий iframe, через hash (содержимое после # в src фрейма) которого осуществляется обмен командами. В итоге нам необходимо на стороне виджета написать функционал взаимодействия с этим проксирующим iframe.

Сразу приведу весь код виджета, благо он совсем небольшой:

<script type="text/javascript" src="mootools-1.2.js"></script>
  
<script language="JavaScript" type="text/javascript">

var lsWidgetClass = new Class({
  
  Implements: [Options],
  
  options: {
    // Некая добавочная величина для установки автоматической высоты фрейма
    delta: 30
  },
  
  initialize: function(options){
    this.setOptions(options);
    this.adjustIFrameHeight();    
  },
  
  // Передает команду родительскому окну фрейма виджета
  cmdIFrame: function(cmd,value) {
    // Удаляем старый фрейм
    if ($('wd-iframe-cmd')) {
      $('wd-iframe-cmd').destroy();
    }    
    // Вытаскиваем из URL виджета идентификатор wauth, он передается автоматически Яндексом
    var found=location.href.match(/wauth=.+=/ig);
    if(found){      
      // формируем SRC с учетом домена первого уровня(ru,ua,..)
      var url=new URI().getData('.').split('|');
      var src=url[0]+'/xframeproxy.html#'+url[1]+'&wauth=';
      // Формируем проксирующий iframe и добавляем его в HTML
      src=src+found[0].replace("wauth=","").replace("&.=","")+'&name='+cmd+'&value='+value;  
      var iframe=new Element('iframe',{'style':'visibility: hidden; position: absolute; height: 0pt; width: 0pt; left: 0pt; top: 0pt;','src':src,'id':'wd-iframe-cmd'});
      iframe.inject(document.body);
    }
  },
  // Устанавливает заданную высоту фрейма
  setIFrameHeight: function(value) {
    this.cmdIFrame('Widget%3A%3AsetIFrameHeight',value);
  },
  // Устанавливает автоматическую высоту фрема
  adjustIFrameHeight: function() {
    this.setIFrameHeight($('widget-yandex').getSize().y+this.options.delta);
  }
});

window.addEvent('domready', function() {
   new lsWidgetClass();  
});
</script>

<div id="widget-yandex">
Виджет - это информационный блок, который содержит фрагмент сайта. Все виджеты, сделанные с помощью технологии API Яндекс.Виджетов, предназначены для установки на главную страницу Яндекса.<br><br>
В кабинете разработчика вы можете загрузить свой виджет и проверить, как он работает.<br><br>
Вы можете сами распространять свой виджет, используя ссылку для его установки или промокод, которые вы можете получить на странице виджета в кабинете.
</div>


* This source code was highlighted with Source Code Highlighter.


В данном примере сразу после загрузки виджета запускается метод adjustIFrameHeight(), который подгоняет высоту фрема под содержимое виджета.

Надеюсь данный топик поможет начинающим виджето-строителям, которые не ровно дышат в сторону MooTools :)
Рабочий пример MooTools виджета, использующий описанный выше принцип, можно посмотреть здесь (Викторина).

UPD Добавил механизм определения домена первого уровня, т.к. виджет не срабатывал на украинском Яндексе yandex.ua
+17
4 февраля 2010, 12:57
25
ort 91,0

комментарии (15)

+1
noonv #
Отлично! А то я для своего виджета сначала пробывал запустить jQuery в режиме совместимости (из этого почему-то ничего не вышло :( ), а потом решился переписывать весь код с mootools-а на jQuery — да так и бросил :(
Теперь снова попробую :)
+1
kmike #
Лучше не jQuery запускать в режиме совместимости, а mootools, там этот режим реализован лучше — и все работать будет.
0
mezhevikin #
а почему старый логотип яндекса на картинке? просто интересно
0
grafmishurov #
Потому что он офигенен в сравнении с теперешним.
0
mezhevikin #
а мне советский флаг больше нравится, можно я его буду использовать когда буду что-то о России писать?
0
mezhevikin #
это конечно сарказм, мне старый тоже больше нравился, однако логотип это тот же флаг, и надо использовать текущей, а ни некогда бывший.
0
grafmishurov #
Можно конечно)
–3
ferrari #
Попытки оживить загибающийся Mootools, тщетно. А пару лет назад обнаружив в модиксе я по нему тащился, самые красивые плагины были у них, сейчас все остальные содрали/воспроизвели/придумали новых и причин возвращаться к нему уже нет.
+2
kmike #
Хэй, js — это не только финтифлюшки) Mootools — это, прежде всего, библиотека, которая позволяет с большим удобством писать на js, особенно разные сложные штуки.

И она сейчас как раз-таки на подъеме, по сравнению с прошлым годом — появился mootools forge, разработка стала более открытой и активной, она наконец подружилась с jQuery (и всеми остальными, кроме prototype), стал развиваться mootools more.

Но да, без нормального знания js mootools покажется сложным и непонятным. А со знанием js — наоборот, очень простым и удобным фреймворком.
+1
zoxa #
Согласен, особенно он помогает когда плагины с нуля пишешь, а не подгоняешь уже существующий или похожий.
0
ort #
а уходить от него какие причины?
0
kmike #
Можно пару замечаний, скорее по стилю?) Плагины хороо бы оборачивать в анонимную функцию, чтоб они ни при каких условиях не начинали конфликтовать с jQuery тем же. Ну и классы принято называть с большой буквы все-таки.

Да, и еще, API на jQuery ведь спокойно можно использовать при работе с mootools. Если только то, что килобайты лишние грузить. Библиотеки прекрасно дружат, начиная с mootools 1.2.3 что-ли.
+1
tigran #
Закросспостил сюда clubs.ya.ru/widget-api/replies.xml?item_no=1474 с вашего позволения. Спасибо!
0
ort #
там ему самое место :)
0
thorn0 #
Проксирующий ифрейм — костыль для отсталых браузеров. Все новые версии браузеров поддерживают обмен сообщениями между ифреймами без хаков. Интересно, почему Яндекс это проигнорировал? Ведь с дополнительным ифреймом явно больше тормозов.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.