Статьи

Создавайте всплывающие окна без мертвых ссылок

Они являются предметом многих горячих дискуссий в Интернете и любимой игрушкой злодеев, которые хотят нас раздражать рекламой «в лицо» — всплывающими окнами.

Но давайте не будем судить об инструменте по злодею, который его обрабатывает. Действительно, бывают времена и условия, когда всплывающее окно может быть желательным эффектом; эти условия обычно возникают в веб-приложениях, а не на веб-сайтах.

Одним из основных недостатков всплывающих окон является их зависимость от JavaScript. Javascript — отличный инструмент для улучшения разметки, чтобы он стал интерактивным без перезагрузки. Тем не менее, мы должны знать о его проблемах.

Создать всплывающее окно смехотворно легко, и есть много устаревших учебных пособий и генераторов кода, которые могут заманить вас в мысль, что ссылка с javascript:window.open()

Отучиться от того, что вы узнали

Давайте не будем тратить время на обсуждение, почему это неправильно — многие другие статьи, такие как эта статья о evolt , и эта статья в A List Apart уже сделали это. Вместо этого давайте подумаем о проблеме и найдем другой способ добиться хорошего результата.

По какой-то веской причине (например, клиент не будет счастлив без этого, вы не можете обновить главную страницу и т. Д.):

  • Нам нужно всплывающее окно, которое мы можем контролировать (с точки зрения его размера, местоположения, отключения частей браузера Chrome и т. Д.).
  • Мы хотим, чтобы всплывающее окно работало для людей, которые не используют JavaScript. Всплывающий вызов должен просто открыть новое окно браузера (или вкладку).
  • Независимо от того, что мы копируем задачи браузера, нам нужна ссылка «закрыть окно» во всплывающем окне.

Это общие требования, которые мы все должны были выполнять в течение нашего времени, как дизайнеры взаимодействия. Если мы проанализируем их, мы можем сделать вывод:

  • Для управления всплывающим окном и закрывающей ссылкой требуется JavaScript.
  • Открытие ссылки в новом окне может быть достигнуто в разметке через атрибут target (за исключением строгих документов XHTML, но есть обходной путь ).

Теперь нам нужно убедиться, что в нашем развитии соответствующий инструмент делает только то, что ему нужно. Давайте начнем с разметки HTML.

 <p>This will be our demo page that  
<a href="popkid.html" target="_blank">
shows a pop-up window(where possible)</a>
and simply <a href="popkid.html">links to the  
page without a pop-up.</a></p>

Это все, что нам нужно. Нам не нужны встроенные обработчики событий, такие как onclick или onkeypress — это JavaScript, и его следует добавить в код JavaScript.

Используйте силу чистого JavaScript

Давайте начнем с определения атрибутов окна и текстового содержимого ссылки «закрыть окно». Поскольку эта ссылка может работать только с JavaScript, мы добавим ее через DOM позже.

 var closeElementId='closewindow'; 
var closeLinkText='Close window';
var windowAttributes='width=310,height=400,left=0,top=0,scrollbars=no,location=no';
Изменить страницы, которые вызывают всплывающие окна

Нам нужна функция JavaScript, чтобы превратить HTML-ссылки на наших страницах во всплывающие ссылки. Мы можем легко добиться этого, просматривая все ссылки и проверяя, какие из них имеют целевой атрибут. Это, однако, должно происходить только с документами, которые не содержатся во всплывающем окне; следовательно, мы проверяем, есть ли открывающий документ.

 if(!window.opener) 
{
 var as,i,popfun
 as=document.getElementsByTagName('a');
 for (i=0;i<as.length;i++)
 {
   if(as[i].target=='_blank')
   {
     popfun=function(){
       window.open(this.href,'',windowAttributes);
       return false;
     };
     as[i].onclick=popfun;
     as[i].onkeypress=popfun;
   }
 }

Перебирая все элементы <a>'_blank' Если это так, мы применяем функцию window.open при нажатии на ссылку или при нажатии клавиши, когда ссылка находится в фокусе (доступность, как мы знаем, также означает независимость от мыши). Возвращение false гарантирует, что ссылка не будет открыта в открывающем документе — она ​​открывается только во всплывающем окне. Мы знаем, какой документ открыть во всплывающем окне, читая атрибут href ссылки.

Если мы не хотим зацикливать все ссылки (это может занять некоторое время), мы можем просто зацикливаться на специальных частях страницы. Скажем, например, что мы определили часть контента с помощью <div id="content"> В этом случае все, что нам нужно сделать, это найти следующее:

 as=document.getElementsByTagName('a');

Мы заменили бы это на:

 as=document.getElementById('content').getElementsByTagName('a');
Добавление дополнений к документам во всплывающем окне

Это позаботилось об открытии страниц. Теперь давайте посмотрим на всплывающие окна, в которых есть window.opener:

 } else { 
 var closep,closelink,closetext;
 closelink=document.createElement('a');
 closetext=document.createTextNode(closeLinkText);
 closelink.href='#';
 closelink.appendChild(closetext);
 closelink.onclick=function(){self.close();};
 closelink.onkeypress=function(){self.close();};
 if(document.getElementById(closeElementId))
 {
   document.getElementById(closeElementId).appendChild(closelink);  
 } else {
   closep=document.createElement('p');
   closep.id=closeElementId;
   closep.appendChild(closelink);
   document.body.insertBefore(closep,document.body.firstChild);  
 }
}

Сначала мы создаем новый элемент ссылки и применяем текст, определенный ранее, как текстовое содержимое. Затем, чтобы она появилась в виде ссылки, мы устанавливаем href ссылки на "#" Чтобы ссылка закрывала окно, мы применяем к нему функцию self.close() Это активируется, когда пользователь нажимает на ссылку или когда нажата клавиша, когда ссылка находится в фокусе.

Теперь мы становимся жадными: мы хотим дать возможность разработчикам HTML определить, где должна появляться ссылка.

Если они не хотят определять местоположение, мы просто применяем ссылку в своем собственном абзаце в качестве первого элемента документа. Но, чтобы убедиться, что мы все еще можем применить к нему CSS, мы даем ему идентификатор.

Этот идентификатор тот, который мы определили ранее как closeElementId Теперь, если HTML уже содержит элемент с таким идентификатором, мы просто добавляем нашу ссылку как новый дочерний элемент к этому элементу с помощью appendChild() Если у нас еще нет элемента с таким идентификатором, мы создаем новый элемент абзаца и применяем к нему идентификатор. Мы добавляем ссылку на этот новый абзац и добавляем абзац как новый первый дочерний элемент в тело документа, используя insertBefore

Призыв к действию!

Это все, что нам нужно сделать. Осталось только обернуть все вышеперечисленное в функцию, вызвать ее при загрузке страницы и добавить весь лот в .js

Вызов onload может быть выполнен различными способами. Один метод включает в себя прикрепление события к окну; другое — просто добавить window.onload=functionname; поскольку последняя строка .js

Скотт Эндрю написал удобную функцию, которая присоединяет событие onload к окну. Преимущество этого заключается в том, что он добавляет другие события загрузки, а не перезаписывает их. Одна из проблем заключается в том, что он не работает в Internet Explorer на компьютерах Mac.

Загрузите полный скрипт и демонстрационные страницы HTML здесь .

Другие приложения

Что еще мы можем сделать с этим решением? Хорошей особенностью было бы предоставление пользователям возможности открывать всплывающие окна со стилем или без, как им хотелось бы. Мы могли бы реализовать это, применяя к открывающим страницам форму, содержащую флажок, и применять атрибуты окна только тогда, когда флажок был установлен.

Этот параметр должен быть сохранен в файле cookie или на сервере, поскольку он довольно бесполезен, если пользователь должен переопределить его на каждой странице.

Поскольку мы обычно удаляем панели инструментов браузера из всплывающего окна и не можем предполагать, что всем известны сочетания клавиш для печати страницы, мы также можем добавить ссылку «печать этой страницы», которая будет вызывать window.print()

Другая идея может заключаться в том, чтобы указать пользователю, что эти конкретные ссылки открываются во всплывающих окнах, применяя к ним значок или изменяя их отображение. Но, что бы мы ни делали, давайте удостоверимся, что мы делаем это в JavaScript и не повредим HTML.