Неразрывный пробел в HTML

Сегодня я расскажу про неразрывные пробелы в HTML. Многие из вас встречали в документации по HTML так называемый неразрывный пробел « », но либо не понимали, что это такое, либо воспринимали его как обычный пробел, что в принципе не правильно.

Неразрывный пробел — это спец-символ, поэтому вы можете ставить несколько таких пробелов подряд и браузер будет отображать каждый этот пробел, а не игнорировать их как элементы форматирования HTML-кода.

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

Вот такую запись удобно использовать в прайс-листах:

10 500 рублей

Таким образом получится запись:
10 500 рублей

И такая запись ни в коем случае не будет перенесена, как:

10
500 рублей

А всегда будет переноситься, как:

10 500
рублей

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

SEO: Методы продвижения сайтов

В этой статье я расскажу о таких методах продвижения сайта как поисковое продвижение по высокочастотным запросам и сбор трафика по низкочастотным запросам поисковых систем — это 2 основные стратегии продвижения сайтов в рунете.

Общая информация

Допустим вы сделали сайт и теперь ваша задача — составление общей аудитории сайта. Как я уже сказал, есть 2 основные стратегии продвижения сайтов: вывод в топ по ВЧ и сбор трафика по НЧ запросам.

Высокочастотные запросы

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

Как выводит в топ?

  • Оптимизировать главную и другие входные страницы под ваши запросы.
  • Закупить ссылки на сайтах, здесь в помощь вам есть сервисы Sape, Trustlink, GoGetLinks и подобные, оплата ссылок ежедневная из расчёта месячной стоимости.
  • Покупать вечные ссылки в статьях и блогах, например, на бирже статей Miralinks. Оплата за статью.
  • И последний способ, самый гениальный — заказать продвижение у профессионалов, тут без комментариев.

Вывод в топ занимает как правило от месяца до трёх, в зависимости от сложности запросов.

Низкочастотные запросы

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

Приведу пример, недавно я написал статью Реализация Comet, в которой рассказывается про реализацию технологии Comet в среде PHP — это не особо популярный топик, но его регулярно ищут в поисковиках. По статистике Яндекса запрос «comet php» показывают 35 раз в месяц, да это мало, лучше когда показов хотя бы 70-80, тем не менее каждый день на эту статью с поиска приходят 1-5 человек, а это уже трафик. Теперь представьте, что таких статей у вас на сайте 10, потом 100, а потом 1000. Чувствуете? Вот так-то! =)

Чтобы метод работал нужно учитывать в заголовке статьи основной низкочастотный запрос, не забывая повторять его в тексте и разбавляя другими словами. Вкусная ссылка по этой теме — SEO-Альманах 2010.

Прозрачные PNG в IE6

Собственно сабж. Делаю проект, без прозрачных png тут что-то делать просто самоубийство — используются фоновые градиенты, закруглённые углы и всё это в резине. Вот так и нашёл фичу.

Раньше всегда выводил прозрачные PNG через фильтры, просто прописывал их в CSS, но технологии не стоят на месте и вот уже есть решение позволяющее выводить png в IE позиционируя его в блоке. Работает всё через behavior — прописывается htc-файл с JS-скриптом обрабатывающим нужный блок.

P.S. Меня эта штука просто спасла. =)

Реализация Comet в среде php+javascript

Ну что ж, сказано — сделано. В этой статье я расскажу, что из себя представляет Comet и рассмотрю реализацию простой схемы с помощью PHP и JavaScript.

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

При инициализации клиент открывает соединение с сервером и повисает в таком состоянии, когда на сервере появляются какие-то новые данные он отправляет их по этому соединению клиенту.

Для того, чтобы реализовать подобную вещь на JavaScript нужно учесть, что работа ведётся, через AJAX по протоколу HTTP. На сервере же предположительно установлен веб-сервер Apache.

В условиях AJAX-запросов, после отправки данных сервер закрывает соединение, клиент обрабатывает данные, открывает соединение заново и ждёт новую порцию данных.

Особенности

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

// javascript class, connection manager
this.connection = function() {
        self.comet = $.ajax({
            type: "GET",
            url:  "backend.php",
            data: {'id':self.last},
            dataType: "text",
            timeout: self.timeout*1000,
            success: self.parseData,
            error: function(){
                // something wrong. but setInterval will set up connection automatically
                setTimeout(self.connection,1000);
            }
        });
    }
this.init = function() {
        //setInterval(self.connection,self.timeout*1000);
        self.connection();
    }
this.init();

В JavaScript все таймауты указываются в миллисекундах, поэтому мы их умножаем на тысячу.

На сервере рекомендую поставить max_execution_time в значение равное таймауту клиента. В самом скрипте нужно организовать вечный цикл, с регулярной проверкой данных для отправки.

// simple infinite loop in php
while (time()-$time<$limit) {
    // checking if something new was added to my test table
    $res = mysql_query('SELECT * FROM `comet` WHERE `id`>"'.$last_id.'" ORDER BY `id` ASC');
    if (mysql_num_rows($res)) {
        while ($item=mysql_fetch_array($res)) {
            echo 'self.putMessage("'.$item['id'].'","'.escape($item['name']).'","'.escape($item['text']).'");';
        }
        flush();
        exit;
    }
    sleep(5);
}

Реализация

Я напишу всё с использованием библиотеки jQuery. Итак, javascript:

function Messanger() {
    this.last = 0;
    this.timeout = 360;
    this.comet = 0;
    var self = this;
    this.putMessage = function(id,name,text) {
        // callback, добавляет сообщения на страницу, вызывается из полученных с сервера данных
        self.last = id;
        var b = document.createElement('div');
        b.innerHTML = '<span style="color: red;">'+name+'</span> '+text;
        $('#messages').append(b);
    }
    this.parseData = function(message) {
        // простая обработка данных полученных с сервера, разбиваем строки и выполняет функции
        var items = message.split(';');
        if (items.length<1) return false;
        for (var i=0;i<items.length;i++) {
            eval(items[i]);
        }
        setTimeout(self.connection,1000);
    }
    this.connection = function() {
        // здесь открывается соединение с сервером
        self.comet = $.ajax({
                type: "GET",
                url:  "backend.php",
                data: {'id':self.last},
                dataType: "text",
                timeout: self.timeout*1000,
                success: self.parseData,
                error: function(){
                    // something wrong. but setInterval will set up connection automatically
                    setTimeout(self.connection,1000);
               }
            });
    }
    this.init = function() {
        //setInterval(self.connection,self.timeout*1000);
        self.connection();
    }
    this.init();
}
function sendMessage() {
    // callback формы, для отправки сообщений на сервер
    if ($('#name').val()&&$('#text').val()) {
        var data = {
                name: $('#name').val(),
                text: $('#text').val()
            }
        $.post('add_new.php',data);
    } else {
        alert('Please fill the fields');
    }
}
$(document).ready(function(){
    // инициализация
    var msg = new Messanger();
});

И PHP скрипт, отправляющий данные:

<?
// number of second the script allowed to run. setting to 6 minutes
$limit = 360;
$time = time();

// getting last loaded value
$last_id = (int)$_GET['id'];

// just to be sure that script will be killed
set_time_limit($limit+5);

mysql_connect('localhost','user','password');
mysql_select_db('database');

function escape($str) {
    return str_replace('"','\"',$str);
}

// цикл, проверяющий новые сообщения каждые 5 секунд
while (time()-$time<$limit) {
    // checking if something new was added to my test table
    $res = mysql_query('SELECT * FROM `comet` WHERE `id`>"'.$last_id.'" ORDER BY `id` ASC');
    if (mysql_num_rows($res)) {
        while ($item=mysql_fetch_array($res)) {
            // пишем js-скрипт, который выполнится у клиента
            echo 'self.putMessage("'.$item['id'].'","'.escape($item['name']).'","'.escape($item['text']).'");';
        }
        // выбрасываем все данные и выходим, чтобы клиент смог их обработать
        flush();
        exit;
    }
    // если данных нет - ждём 5 секунд
    sleep(5);
}

mysql_close();
?>

Мы получили фронтенд на JavaScript, который отправляет запросы на сервер в ожидании новых данных, сервер каждые 5 секунд проверяет не появились ли данные, когда появляются — он их отправляет клиенту и закрывает соединение. После этого клиент снова открывает соединение и всё повторяется. Если данных не поступило и сработал таймаут — клиент просто открывает соединение заново.

Обратите внимание, что и в классе на JS и в скрипте PHP задан таймаут, это сделано, чтобы избежать создание мёртвых процессов, одинаковые таймауты в теории должны поддерживать нагрузку сервера на минимуме.

Социальные кнопки на сайт

Пост для тех, кто хочет добавить к себе на сайт социальные кнопки, но либо не знает как это сделать, либо не хочет обходить с десяток популярных сервисов в их поисках. Решение есть, его нам предоставляет Яндекс.

На страничке Яндекса вы можете в пару кликов настроить и скопировать к себе код для подключения социальных кнопок, очень удобно, так что пользуюсь и сам. Самое главное — сервисом довольны и мои заказчики, такие кнопки их устраивают, а подключать их одно удовольствие! =)

P. S. Я себе на внутренних страницах постов здесь тоже поставил.

До конца света осталось…

Как-то во время общения с другом всплыла идея сделать счётчик дней до «конца света». Ну, или проще – счётчик времени до того момента, когда все ждущие и верящие наконец-то будут окончательно повержены.

Собственно реализация: spectrox.ru/timebeforetheend/

Работает на JavaScript с небольшой погрешностью на загрузку страницы, учитывает разницу между серверным временем и пользовательским.

Ждём!

iFraming on the fly

Давно слышал о проблемах с созданием динамических iframe и заполнении их содержимым, но посмотреть что и как самому всё никак не доходили руки, теперь же, по причинам связанным с не приходящим сном, я эту тему затрону.

Для примера я набросал простую страничку создающую iframe по клику мыши. Изначально я записал всё одной функцией выполняющейся в один поток, но результата никакого небыло, решение было найдено — собственно участок кода, в котором происходит редактирование iframe я записал в функцию setTimeout, тем самым вынес его в отдельный поток выполнения:

setTimeout(function(){
        //редактируем iframe;
    },0);

После чего код начал работать. Буквально пару часов спустя, я показал описанное выше @chaos_8 и он разъяснил, что суть не в вызове setTimeout(), а в том, что после создания iframe нужно дождаться события onload (как и при работе с объектом Image).

Получившийся исходный код:

function start() {
    var fB = document.getElementById('frame_block');
    var frame = document.createElement('iframe');
    frame.setAttribute('width','640');
    frame.setAttribute('height','480');
    frame.onload = function() {
        var doc = frame.contentWindow.document;
        doc.body.innerHTML = 'Test it';
    }
    fB.appendChild(frame);
}

Несколько слов о НДС

Столкнулся я недавно с необходимостью расчёта НДС. При том не только в виде «вычислить 18% от цены», а в виде просчёта НДС для счетов-фактур и других официальных документов, где необходим просчёт по позициям. Смысл статьи в описании 2х основных моментов, которые мной были замечены.

Введение

Существует 2 основные проблемы при расчёте НДС:

  1. Необходимость просчётов в вариантах, когда НДС уже включен в цену товара, и варианта, когда НДС будет просчитан сверху, из цены товара.
  2. Проблемы связанные с погрешностью округления. Эта погрешность может создать различие между НДС расчитанным по позициям товара, и НДС получающийся из общей суммы товара.

Вроде бы всё просто, но давайте разберёмся с этими примерами поподробнее.

Варианты просчёта НДС

В любимой нами всеми программе от существует 2 вариант просчёта НДС:

  1. НДС в сумме. Это когда НДС уже содержится в цене товара и для его просчёта используется формула:

    СуммаНДС = Сумма * 18 / 118

    Формула это выходит из логики начальной школы. Сначала высчитываем сколько будет рублей в 1% (Сумма/118), затем умножаем на 18, и получаем 18% (из расчёта того, что НДС 18%. хотя он не всегда бывает таковым).

  2. НДС сверху. В этом варианте необходимо расчитать сумму НДС исходя из цены товара без НДС, т.е.:

    СуммаНДС = Сумма * 0.18

    или

    СуммаНДС = Сумма * 18 / 100

    Тут думаю всё понятно.

А теперь немного о самой проблеме: «Различия в расчётах между двумя этим видами».

Цена с НДС

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

Цена_за_единицу_товара = Округление( (Сумма_с_НДС — Сумма_НДС) / Количество_товара )

Мы не расчитываем сумму товара, умножением его цены на количество. Это не верный путь, для данного варианта расчёта НДС.

Сумму НДС мы можем расчитать следующим образом:

Сумма_НДС = Округление( Сумма_с_НДС * 18 / 118 )

Затем, мы используем следующую формулу для расчёта суммы товара без НДС:

Сумма_без_НДС = Округление( Сумма_с_НДС — Сумма_НДС )

Таким образом, мы явно видим, что все цены подогнаны под сумму с НДС.

Цена без НДС

Если же счёт-фактура расчитывается исходя из цены без НДС, то все расчёты ведутся по логике действий. Сначала вычисляется сумма без НДС, затем из суммы без НДС, вычисляется сумма НДС и соответственно, в итоговой сумме пишется просто «Сумма_без_НДС + Сумма_НДС».

Если вы захотите заного просчитать счёт-фактуру, изходя из данных полученных после прошлого просчёта (где НДС расчитывался другим способом), вы можете увидеть некоторую разницу в расчётах. В моём случае разница составляла одну копейку. Позже, я постораюсь добавить пример, на котором всё это хорошо видно.