Как перехватывать клик по Flash-баннеру

February 9, 2011, revised February 10, 2011 ActionScript b-loader CSS Flash HTML mtasc SWF

Как ни крути, Flash еще надолго останется с нами. Баннеры на Flash являются самой наглядной рекламой, и многие рекламодатели попросту отказываются работать с другими технологиями.

Разместить флешку на сайте - дело несложное. Однако, в 95% случаев ожидается, что флешка будет ссылкой. Думаешь, объект Flash можно просто положить в <a>? Нельзя. Приходится ограничиваться внутренними средствами. Флешка может быть ненажимаемой вообще или вести на неправильный или устаревший адрес. Как показывает опыт, мало кто из дизайнеров догадывается, что ссылку можно передавать во флеш параметром, поэтому придется выкручиваться своими силами. Как же быть?

Очевидный способ - открыть флешку в Flash Professional, перекрыть ее прозрачным прямоугольником и навесить на него событие. Но если Flash Studio у нас нет, да и взять неоткуда? Да и к тому же не хочется, чтоб дергали из-за каждой новой флешки?

Флешка-контейнер

Способ предложил Костя, а сделал эту флешку, как ни странно, тоже днепропетровчанин.

Способ прост, как бревно: вместо флешки-баннера загружается флешка-контейнер b-loader, которая подгружает флешку-баннер внутрь себя и перекрывает её ссылкой.

<object type="application/x-shockwave-flash" data="/PATH/TO/b-loader.swf" width="SWF WIDTH" height="SWF HEIGHT">
  <param name="movie" value="/PATH/TO/b-loader.swf">
  <param name="FlashVars" value="src=SWF URL&href=LINK URL">
</object>

Перекомпиляция флешки

Это решение автоматизируемое, не требует графического режима, работает как из-под Windows, так и из-под Linux.

Пригодится бесплатный компилятор (рекомпилятор, точнее) ActionScript mtasc. Он есть в репозиториях Ubuntu, и, конечно, на официальном сайте.

Что он может? Например, перекрыть флешку прозрачным прямоугольником, навесив на него ссылку! Для этого нужно сохранить следующий код в файл clicker.as.

// Что делает этот код? 
// Создает прямоугольник размером со "сцену", то есть как все содержимое флешки,
// а потом - вешает обработчик на клик по этому элементу.
// Извне нужно передать флешке параметр url
class Clicker {
  static function create():MovieClip {
    var clicker:MovieClip = _root.createEmptyMovieClip('clicker',_root.getNextHighestDepth());
    clicker.lineStyle(1,0x000000, 0);
    clicker.beginFill(0x00000, 0);
    clicker.lineTo(Stage.width, 0);
    clicker.lineTo(Stage.width, Stage.height);
    clicker.lineTo(0, Stage.height);
    clicker.lineTo(0, 0);
    clicker.endFill();
    clicker.onRelease = function(){
      getURL(_root.url, "_blank");
    }
    return clicker;
  }

  static function main() {
    var clicker = Clicker.create();
  }
}

а потом - “вшить” его в нашу флешку несложной командой (которая – осторожно! – затирает исходный файл)

// syntax: bash
mtasc -swf original.swf -main clicker.as

Вот и все! Остается подключить флешку, например, таким кроссбраузерным способом:

<object type="application/x-shockwave-flash" data="SWF URL" width="SWF WIDTH" height="SWF HEIGHT">
  <param name="movie" value="SWF URL">
  <param name="FlashVars" value="url=LINK URL">
</object>

Перекрытие флешки картинкой

Флешка перекрывается прозрачной картинкой, а на картинку вешается ссылка либо любое событие Javascript.

По умолчанию объект Flash отрисовывается вне окна браузера, то есть, отдельным окном, и перекрыть его чем-либо, находящимся в HTML, невозможно. Поэтому есть так называемый режим WMODE, который отрисовывает флеш внутри браузера. Это вызывает некоторые проблемы с производительностью, однако в случае с баннерами они пренебрежимо малы.

Само по себе перекрытие происходит традиционным образом; blank.png - прозрачная картинка размером 1x1, то есть вот такая.

<div style="position:relative">
  <object data='SWF URL' height='SWF HEIGHT' type='application/x-shockwave-flash' width='SWF WIDTH'>
    <param name='movie' value='SWF URL' />
    <param name='wmode' value='opaque' />
  </object>
  <a href='TARGET URL' style='position: absolute; left: 0px; top: 0px'>
    <img height='300' src='blank.png' width='220' />
  </a>
</div>

Можно было бы перекрыть просто ссылкой, сделав ее блочным элементом нужного размера, но это не работает в IE. Можно было бы передавать картинку посредством data URI, но это не работает в IE <8. В общем, как всегда.

Buy Me a Coffee at ko-fi.com