Nickolay.info. JavaScript. Пишем информер средствами HTML и JavaScript |
Написание информера - не только развлечение и дополнительный сервис для Ваших пользователей. Он еще и повышает ссылочную популярность сайта, потому что все, размещающие его у себя, вольно или невольно ставят лишнюю ссылку на Ваш сайт.
Самая естественная и правильная технология - использование PHP или другого серверного языка, выполняющего всю работу на стороне Вашего сервера. Но эта статья размещена в разделе JavaScript, и потому предназначена для тех, кто пока не постиг тайны серверного программирования или пользуется хостингом без поддержки серверных скриптов, таким как narod.ru.
Применяя только HTML и JavaScript, информер можно написать по следующему шаблону:
http://www.mysite.com/index.html?par1&par2
передает "главному файлу" index.html сайта www.mysite.com 2 неименованных параметра со значениями par1 и par2, а строка
http://www.mysite.com/index.html?name=Vasya&age=18&group=111
содержит параметры с именами name, age и group, имеющие значения Vasya, 18 и 111 соответственно. Прочитать эти параметры сможет программа на JavaScript.
К сожалению, возможности классического JavaScript довольно ограничены, так что информеров, получающих данные из базы или с других серверов мы сделать не сможем. Но ведь мы и хотели обойтись, пока что, простейшими средствами.
По сути дела, JavaScript может формировать содержимое страницы в зависимости всего от нескольких факторов:
Давайте сделаем информер в виде идущих часов с датой и обеспечим подключение к нему любой нужной картинки и оформления. Все подключаемые картинки должны располагаться где-то в сети, то есть, уже иметь URL-адреса, которые и будут передаваться информеру параметрами.
Пока мы ничего не будем вводить в формы, значит, при написании кода информера необязательно передавать данные в виде имя=значение, достаточно после знака "?" в URL-адресе перечислить значения параметров, разделяя их обычным разделителем "&".
Придумаем несложный блок информера, скажем, вот такой:
Из-за изменений в адресах картинок у Яндекса, конкретно этот код информера уже не работает, но способ, описанный в статье, остаётся работающим!
Основная часть информера будет ссылкой на выбранный пользователем ресурс (у нас - Яндекс), открываемой в новом окне (параметр 1).
URL-адрес картинки, которая является ссылкой - это параметр 2. У нас это картинка Яндекса.
Параметры 3 и 4 передают ширину и высоту картинки в пикселах. Для простоты не будем пытаться узнать ее из скрипта, к тому же, у кого-то может возникнуть желание масштабировать картинку своего информера.
Внешняя таблица будет иметь настраиваемый цвет рамки - параметр 5.
При желании можно задать фоновый рисунок под датой и временем - его URL передается 6 параметром.
Вот уже и ясно, как вызывать будущий информер. Тот его вид, что показан выше, получен следующим тегом:
<iframe src="http://nickolay.info/myclock.html?http://www.ya.ru&http://ya.ru/logo.png&100&44&red&http://img.yandex.net/i/www/iconx.png"
scrolling="no" width=102 height=74 frameborder=0 marginwidth=0 marginheight=0
hspace=0 vspace=0></iframe>
Все атрибуты тега, расположенные после src, призваны обеспечить вид окна фрейма без полос прокрутки и лишних отступов. Ширина и высота окна iframe, думаю, может быть вычислена, исходя из ширины и высоты картинки - ведь строки отображения даты и времени занимают всегда одно и то же пространство.
Дело за малым - написать файл myclock.html, отображающий блок информера, и расположить его по адресу http://nickolay.info/myclock.html.
Прежде всего, разберемся с чтением параметров 1-6. Дадим им имена и расположим в теге <script> вместе со значениями по умолчанию:
<script type="text/javascript">
var url='http://nickolay.info';
var picture='http://nickolay.info/img/pers.gif';
var width=88;
var height=31;
var bgcolor='#009900';
var bgimage='http://nickolay.info/img/bg.gif';
//...
Метод JavaScript с именем location.search позволяет прочитать всю часть URL, включающую список параметров. Эта часть всегда начинается со знака "?" и метод возвращает ее вместе со знаком, поэтому первый символ сразу же исключим:
var count=location.search.substring(1);
Так как параметры не именованы, не будем создавать никаких дополнительных массивов, а просто разберем строку count по частям, каждый раз выделяя часть до очередного разделителя параметров "&":
if (count!='') {
ind=count.indexOf('&');
if (ind>-1) {
url=count.substring(0,ind);
count=count.substring(ind+1,count.length);
ind=count.indexOf('&');
if (ind>-1) {
picture=count.substring(0,ind);
count=count.substring(ind+1,count.length);
ind=count.indexOf('&');
if (ind>-1) {
str=count.substring(0,ind);
var w=parseInt (str);
if ((!isNaN(w)) && (w>0)) { width=w; }
count=count.substring(ind+1,count.length);
ind=count.indexOf('&');
if (ind>-1) {
str=count.substring(0,ind);
var h=parseInt (str);
if ((!isNaN(h)) && (h>0)) { height=h; }
count=count.substring(ind+1,count.length);
ind=count.indexOf('&');
if (ind>-1) {
bgcolor=count.substring(0,ind);
count=count.substring(ind+1,count.length);
if (ind>-1) {
bgimage=count;
}
}
}
}
}
}
}
Теперь все параметры получили значения, либо оставили себе значения по умолчанию, если что-то передано неверно.
Оставшаяся часть скрипта будет формировать на основе параметров вывод:
write1(); //шапка внешней таблицы с рамкой и фоновым рисунком
write2(); //шапка внутренней таблицы + картинка-ссылка
writedate(); //вывод текущей даты
document.writeln ('<br class=clock>'); //и, через перевод строки,
writeclock(); //вывод времени
document.writeln ('</td></tr></table></td></tr></table>');
//закрыть обе таблицы
</script>
Теперь наполним все функции содержимым. Сначала блок для работы с датой и временем:
var clockid=new Array();
var dateid=new Array();
var i_clock=-1,d_clock=-1,thistime,thisdate;
function initTime () { //получить и сформировать время в виде ЧЧ:ММ:СС
thistime= new Date();
hours=thistime.getHours();
minutes=thistime.getMinutes();
seconds=thistime.getSeconds();
if (eval(hours) <10) {hours="0"+hours;}
if (eval(minutes) < 10) {minutes="0"+minutes;}
if (eval(seconds) < 10) {seconds="0"+seconds;}
return (hours+":"+minutes+":"+seconds);
}
function initDate () { //получить и сформировать дату в виде ДД.ММ.ГГГГ
thisdate = new Date();
Day = thisdate.getDate();
if (Day<10) Day = '0'+ Day;
Month = thisdate.getMonth()+1;
if (Month<10) Month = '0'+ Month;
Year = thisdate.getFullYear();
return (Day + "." + Month + "." + Year);
}
function writeclock() { //Вывести часы в элемент HTML с id=i_clock стилем class=clock
i_clock++;
if (document.all || document.getElementById || document.layers) {
clockid[i_clock]="clock"+i_clock;
document.write("<span class=clock id='"+
clockid[i_clock]+"'>"+thistime+"</span>");
}
}
function writedate() { //Вывести дату в элемент HTML с id=d_clock тем же стилем CSS
d_clock++;
if (document.all || document.getElementById || document.layers) {
dateid[d_clock]="date"+d_clock;
document.write("<span class=clock id='"+
dateid[d_clock]+"'>"+thisdate+"</span>");
}
}
function clockon() { //функция, вызываемая каждую секунду для обновления даты и времени
thistime = initTime();
thisdate = initDate();
if (document.getElementById) {
for (i=0;i<clockid.length;i++) {
document.getElementById(clockid[i]).innerHTML=thistime;
}
for (i=0;i<dateid.length;i++) {
document.getElementById(dateid[i]).innerHTML=thisdate;
}
}
var timer=setTimeout("clockon()",1000);
}
Затем добавим функции для вывода шапок обеих таблиц.
function write1 () {
document.writeln ('<table cellspacing=0 cellpadding=0 class="table" style="border-color: '+bgcolor+'; background-image: url('+bgimage+');"><tr><td align=center valign=center>');
}
function write2() {
document.writeln ('<table border=0 cellspacing=0 cellpadding=0 width="'+width+'" height="'+height+'"><tr><td align=center valign=center>');
document.writeln ('<a href="'+url+'" target=_blank><img src="'+picture+'" border=0></a></td></tr><tr><td align=center valign=center>');
}
Остается инициализировать текущие дату и время.
thistime = initTime ();
thisdate = initDate ();
Добавляем стилевые классы clock и table, определяющие как будут выглядеть строки даты-времени и внешняя таблица, соединяем все в один файл и получаем этот документ (новое окно). Правда, вызванный этой ссылкой без параметров, он всегда будет показывать только мой баннер - помните же, какие значения по умолчанию мы дали?
Так что теперь напишем еще один скрипт, чтоб пользователи могли создавать информеры сами себе. Заодно используем еще одно полезное свойство JavaScript - умение проверять на правильность данные форм.
Все параметры кода информера введем через форму, подготовленную специально для этой цели. Для простоты имена полей формы совпадают с показанными выше - url, picture и т. д. Текстовую область, в которую будет выводиться сгенерированный код, назовем html. Вот полный код формы:
<form name="f1">
<table width=100% cellpadding=4 cellspacing=0 border=0>
<tr>
<td width="50%">1. Введите URL, по которому будет выполняться переход с информера</td>
<td width="50%"><input type=text name=url size=40 maxlength=80 class=mainoption></td>
</tr>
<tr>
<td>2. Введите URL рисунка, отображаемого на информере</td>
<td><input type=text name=picture size=40 maxlength=80 class=mainoption></td>
</tr>
<tr>
<td>3. Введите нужную ширину рисунка в пикселах</td>
<td><input type=text name=width size=3 maxlength=3 class=mainoption></td>
</tr>
<tr>
<td>4. Введите нужную высоту рисунка в пикселах</td>
<td><input type=text name=height size=3 maxlength=3 class=mainoption></td>
</tr>
<tr>
<td>5. Введите имя или код цвета рамки информера (необязательно)</td>
<td><input type=text name=bgcolor size=20 maxlength=20 class=mainoption></td>
</tr>
<tr>
<td>6. Введите URL фонового рисунка информера (необязательно)</td>
<td><input type=text name=bgimage size=40 maxlength=80 class=mainoption></td>
</tr>
<tr>
<td><input type="button" class=mainoption value="Получить код" onclick="javascript:getcode()"></td>
<td><input type="button" class=mainoption value="Очистить все" onclick="javascript:clearall()"></td>
</tr>
<tr>
<td colspan=2 align=center><textarea name=html rows=10 cols=80 class=mainoption></textarea></td>
</tr>
</table>
</form>
Кнопки button вызывают всего две функции. Начнём с более простой clearall(), очищающей все поля формы:
<script type="text/javascript">
function clearall () {
document.f1.url.value='';
document.f1.picture.value='';
document.f1.width.value='';
document.f1.height.value='';
document.f1.bgcolor.value='';
document.f1.bgimage.value='';
document.f1.html.value='';
}
//...
Так как мы вводим несколько URL-адресов, нам понадобятся функции для проверки корректности адреса (correctURL) и отсечения лишних пробелов перед тем, как проверять (trim). Коды цветов принято вводить в шестнадцатеричном представлении, значит, как минимум, нужна функция, проверяющая, является ли символ шестнадцатеричной цифрой (is_hex).
Вот листинг со всеми этими служебными функциями.
function correctURL (url) {
var template = /^(?:(?:https?|http|ftp):\/\/(?:[a-z0-9_-]{1,32}(?::[a-z0-9_-]{1,32})?@)?)?(?:(?:[a-z0-9-]{1,128}\.)+(?:com|net|org|mil|edu|arpa|ru|gov|biz|info|aero|inc|name|[a-z]{2})|(?!0)(?:(?!0[^.]|255)[0-9]{1,3}\.){3}(?!0|255)[0-9]{1,3})(?:\/[a-z0-9.,_@%&?+=\~\/-]*)?(?:#[^ \'\"&<>]*)?$/i;
var regex = new RegExp (template);
return (regex.test(url) ? true : false);
}
function trim(string) {
return string.replace (/(^\s+)|(\s+$)/g, "");
}
function is_hex(c) {
var symbols="0123456789abcdefABCDEF";
return (symbols.indexOf(c)==-1 ? false : true);
}
Функция getcode(), выполняющая проверку введенных в форму данных, сознательно сделана максимально простой - она проверяет по очереди все 6 полей ввода и генерирует сообщение об ошибке, как только находит незаполненное или неверно заполненное поле. С URL-адресами обойтись проще всего - достаточно проверить их на корректность регулярным выражением, содержащимся в функции correctURL(). Кстати, я не уверен, что это моё старое выражение - лучшее из возможных. Поищите в Сети - и наверняка найдёте что-то ещё. Ширина и высота картинки - целые числа, поэтому getcode() пытается преобразовать содержимое полей width и height в такие числа, заодно контролируя их на соответствие произвольно установленным нижним границам размера картинки. Контроль верхних границ обеспечивается атрибутом maxlength=3. Вряд ли кому-то понадобится информер с размером картинки больше, чем 999 пикселов. Наконец, цвета можно задавать и именами, которые поддерживаются всеми популярными браузерами (в листинге ниже Вы увидите, что строчка определения массива colors получилось длинноватой, не так ли?), и 16-ричными кодами вида #RRGGBB или RRGGBB (если не знаете, что такое коды RGB, то Вы вообще зря начинали читать статью).
Если каким-то чудом все введённые пользователем данные прошли проверки корректности, функция генерирует содержимое поля html оператором
document.f1.html.value=...;
Пользователю остаётся вставить код информера в удобное место страницы. Привожу текст функции getcode():
function getcode () {
if (correctURL(trim(document.f1.url.value))==true) {
url=document.f1.url.value;
}
else {
window.alert ('Не введен корректный адрес URL в поле 1');
return false;
}
if (correctURL(trim(document.f1.picture.value))==true) {
picture=document.f1.picture.value;
}
else {
window.alert ('Не введен корректный адрес URL в поле 2');
return false;
}
var w=parseInt (trim(document.f1.width.value));
if ((isNaN(w)==true) || (w<60)) {
window.alert ('Не введено корректное значение в поле 3 (целое, от 60 пикселов)');
return false;
}
else { width=w; }
var h=parseInt (trim(document.f1.height.value));
if ((isNaN(h)==true) || (h<20)) {
window.alert ('Не введено корректное значение в поле 4 (целое, от 20 пикселов)');
return false;
}
else { height=h; }
var colors = new Array (
"Aliceblue","Antiquewhite","Aqua","Aquamarine","Azure","Beige","Bisque","Black","Blanchedalmond","Blue","Blueviolet","Brown","Burlywood","Cadetblue","Chartreuse","Chocolate","Coral","Cornflowerblue","Cornsilk","Crimson","Cyan","Darkblue","Darkcyan","Darkgoldenrod","Darkgray","Darkgreen","Darkkhaki","Darkmagenta","Darkolivegreen","Darkorange","Darkorchid","Darkred","Darksalmon","Darkseagreen","Darkslateblue","Darkslategray","Darkturquoise","Darkviolet","Deeppink","Deepskyblue","Dimgray","Dodgerblue","Firebrick","Floralwhite","Forestgreen","Fuchsia","Gainsboro","Ghostwhite","Gold","Goldenrod","Gray","Green","Greenyellow","Honeydew","Hotpink","Indianred","Indigo","Ivory","Khaki","Lavender","Lavenderblush","Lawngreen","Lemonchiffon","Lightblue","Lightcoral","Lightcyan","Lightgoldenrod","Lightgoldenrodyellow","Lightgray","Lightgreen","Lightpink","Lightsalmon","Lightseagreen","Lightskyblue","Lightslateblue","Lightslategray","Lightsteelblue","Lightyellow","Lime","Limegreen","Linen","Magenta","Maroon","Mediumaquamarine","Mediumblue","Mediumorchid","Mediumpurple","Mediumseagreen","Mediumslateblue","Mediumspringgreen","Mediumturquoise","Mediumvioletred","Midnightblue","Mintcream","Mistyrose","Moccasin","Navajowhite","Navy","Navyblue","Oldlace","Olive","Olivedrab","Orange","Orangered","Orchid","Palegoldenrod","Palegreen","Paleturquoise","Palevioletred","Papayawhip","Peachpuff","Peru","Pink","Plum","Powderblue","Purple","Red","Rosybrown","Royalblue","Saddlebrown","Salmon","Sandybrown","Seagreen","Seashell","Sienna","Silver","Skyblue","Slateblue","Slategray","Snow","Springgreen","Steelblue","Tan","Teal","Thistle","Tomato","Turquoise","Violet","Violetred","Wheat","White","Whitesmoke","Yellow","Yellowgreen"
);
var c= trim(document.f1.bgcolor.value).toLowerCase();
if (c!='') {
var l=colors.length;
var code=false;
for (var i=0; i<l; i++) {
if (colors[i].toLowerCase() == c) {
code=true;
break;
}
}
if (code==false) {
l=c.length;
if (l==7) {
if (c.substring(0,1)=='#') { c=c.substring(1,7); l=6; }
}
if (l==6) {
var k=0;
for (i=0; i<6; i++) {
if (is_hex(c.substring(i,i+1))==true) k++;
}
if (k==6) { code=true; }
}
}
if (code==false) {
window.alert ('Не введены корректный код или наименование цвета в поле 5');
return false;
}
else { bgcolor=c; }
}
bgstr=trim(document.f1.bgimage.value);
if (bgstr!='') {
if (correctURL(bgstr)==true) {
bgimage=document.f1.bgimage.value;
}
else {
window.alert ('Не введен корректный адрес URL в поле 6');
return false;
}
}
var w2=width+2;
var h2=height+27;
document.f1.html.value='<iframe src="http://nickolay.info/myclock.html?'+
url+'&'+picture+'&'+width+'&'+height+'&'+bgcolor+'&'+bgimage+'" scrolling="no" '+
'width='+w2+' height='+h2+' frameborder=0 marginwidth=0 '+
'marginheight=0 hspace=0 vspace=0></iframe>';
}
и пример тега информера, сгенерированного с данными по умолчанию:
<iframe src="http://nickolay.info/myclock.html?http://nickolay.info&http://nickolay.info/img/pers.gif&88&31&009900&http://nickolay.info/img/bg.gif" scrolling="no" width=90 height=58 frameborder=0 marginwidth=0 marginheight=0 hspace=0 vspace=0></iframe>
Атрибуты ширины и высоты тега <iframe>, как можно видеть из текста функции
getcode(), приняты следующими:
w2=ширина рисунка + 2 (ширина окна тега)
h2=высота рисунка + 27 (высота окна тега)
Если я с этими размерами ошибся, их нетрудно поправить. Проверено в последних Internet Explorer и Opera, работает.
Готовый скрипт формирования тега для нашего информера, конечно же, существует: вот он (новое окно). Его код отличается от разобранного лишь тем, что к названиям полей приписаны примеры ввода. Там же показан еще один информер, наугад сделанный для сайта Mail.Ru. Остаётся только дождаться, когда они его у себя установят :)
гостевая; E-mail |