Пользователь
0,0
рейтинг
26 октября 2012 в 01:16

Разработка → Элементарные социальные share-кнопки tutorial

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

HTML
<a onclick="Share.vkontakte('URL','TITLE','IMG_PATH','DESC')"> {шарь меня полностью}</a>
<a onclick="Share.facebook('URL','TITLE','IMG_PATH','DESC')"> {шарь меня полностью}</a>
<a onclick="Share.mailru('URL','TITLE','IMG_PATH','DESC')"> {шарь меня полностью}</a>
<a onclick="Share.odnoklassniki('URL','DESC')"> {шарь меня полностью}</a>
<a onclick="Share.twitter('URL','TITLE')"> {шарь меня полностью}</a>

JS
Share = {
	vkontakte: function(purl, ptitle, pimg, text) {
		url  = 'http://vkontakte.ru/share.php?';
		url += 'url='          + encodeURIComponent(purl);
		url += '&title='       + encodeURIComponent(ptitle);
		url += '&description=' + encodeURIComponent(text);
		url += '&image='       + encodeURIComponent(pimg);
		url += '&noparse=true';
		Share.popup(url);
	},
	odnoklassniki: function(purl, text) {
		url  = 'http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1';
		url += '&st.comments=' + encodeURIComponent(text);
		url += '&st._surl='    + encodeURIComponent(purl);
		Share.popup(url);
	},
	facebook: function(purl, ptitle, pimg, text) {
		url  = 'http://www.facebook.com/sharer.php?s=100';
		url += '&p[title]='     + encodeURIComponent(ptitle);
		url += '&p[summary]='   + encodeURIComponent(text);
		url += '&p[url]='       + encodeURIComponent(purl);
		url += '&p[images][0]=' + encodeURIComponent(pimg);
		Share.popup(url);
	},
	twitter: function(purl, ptitle) {
		url  = 'http://twitter.com/share?';
		url += 'text='      + encodeURIComponent(ptitle);
		url += '&url='      + encodeURIComponent(purl);
		url += '&counturl=' + encodeURIComponent(purl);
		Share.popup(url);
	},
	mailru: function(purl, ptitle, pimg, text) {
		url  = 'http://connect.mail.ru/share?';
		url += 'url='          + encodeURIComponent(purl);
		url += '&title='       + encodeURIComponent(ptitle);
		url += '&description=' + encodeURIComponent(text);
		url += '&imageurl='    + encodeURIComponent(pimg);
		Share.popup(url)
	},

	popup: function(url) {
		window.open(url,'','toolbar=0,status=0,width=626,height=436');
	}
};

Счетчик шаринга

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

Но у меня стояла другая задача, надо было отследить статистику нажатий именно на кнопку шаринга размещенную непосредственно на расшариваемой странице. Далеко не уходя от способа шаринга представленного выше, эта задача была решена табличкой в БД, еще одним параметром функции и простым ajax'ом:
	popup: function(url,soc) {
              window.open(url,'','toolbar=0,status=0,width=626,height=436');
              $.post('/social/share', {social:soc, page:url}, function (data){});
	}

В моем случае принимающий скрипт достает с URL айдишник записи, заносит в табличку запись и/или увеличивает счетчик на 1 для конкретной социальной сети.

Данное решение является самым минималистичным из мною встречаемых, с свободной кастомизацией внешнего вида. Оно избавляет от надобности в использовании сторонних сервисов типа pluso.ru и дает возможность вести собственную статистику на своем же сервере.
Дмитрий @WuWu
карма
16,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (57)

  • –40
    А что эти «ссылки» будут означать для пользователя который отключил javascript?
    • +53
      Для пользователя который отключил javascript, надобность в использовании социальных сетей, а тем более надобность шаринга, наверняка отсутствует
      • –39
        Рановато вы за пользователей всё решили, раз уж делаете такие неправильные ссылки вы их хотя бы скрывайте через style=«display: none;»
        • +25
          Раз уж на то пошло, то все остальные кнопки, включая нативные от соцсетей, не работают без js. Вброс не засчитан)
    • –19
      Ух ты сколько минусующих, вы что и вправду считаете что ссылки с onclick без href это нормально?
      • 0
        Нет, не считаю, но и ваш комментарий тоже не в тему.
        Да, эти кнопко-ссылки можно было сделать с target="_blank", о отработку в pop-up сделать на js )
        • –6
          Это и ссылками даже нельзя назвать, ссылка ведёт на конкретный адрес, здесь же у элементов «a» просто добавлено поведение onclick. Соответственно их надо скрывать от юзеров которые отключили у себя javascript. Или думать о пользователях без js тоже «не в тему»?
          • +4
            специально для вас — кошерный вариант, кошерней не бывает)
            jsfiddle.net/rrZBR/1/
            Так подумали о юзерах с js?)
            • 0
              Вот, спасибо, такой вариант не страшно на сайт ставить.
              • 0
                Хм, а вы ждали, что кто-то предложит более правильный вариант?) Могли бы не возмущаться, а предложить решение, которое нравится вам сами)
            • 0
              Мне кажется это стоило бы добавить в топик.
              • 0
                Предложите это топикстартеру)) он тут властелин и хозяин))
          • +2
            Да что Вы прицепились к ссылкам?
            Если Вам не нравится тег a, сделайте через span, h1, p или что-нибудь ещё.
            Я согласен с комментриующим Выше, что человек, который отключает js, вряд ли сидит в соц. сетях.
            Представьте себе сами тот-же ВК, без JS. Ужас, правда?
            • +3
              ВК вообще не пускает юзеров без JS
              • +1
                он тупо не работает без JS, как и 50% всех современных сайтов
                • 0
                  ну тут вы не правы) я стараюсь свои сделать такими, чтобы основной функционал отрабатывал и без js, иначе правда, будет совсем плохо
                  • 0
                    Да, я тоже стараюсь делать именно так.
                    Но как вы сделаете аякс-отправку формы, например, без JS`а?

                    Даже комментарии на хабре — тоже JS :)
                    • 0
                      Почему сразу ajax? Если работает js — делаем аякс, не работает? Идет стандартный post. А как уже разбить логику на стороне приложения — это ваше дело)
                      • 0
                        Это уже урезание функционала приложения :)
                        • 0
                          По-моему мы говорим о разных вещах, но никакого урезания нет и не будет ;-)
                          • 0
                            Чем ниже читаю комментарии, тем дальше они от темы топика. Давайте все же поговорим о кнопках. Они кошерные, не правда ли? xDD
            • +1
              с h1 переборщили
    • +7
      Слишком умные пользователи, которые отключают js, куки, картинки, css могут идти к черту.

      Я к тому, что когда сам отключаю скрипты, вполне ожидаю, что половина функционала сайта вообще работать перестанет.
      • 0
        А я когда отключаю js надеюсь, что оно все-таки заработает. Надежда умирает последней
    • 0
      Каков процент таких людей щас в %? Если отключили js — значит сами себя лишили функционала.
      А что если люди сидят с ie 3.0?
    • +3
      JavaScript отключают только сис админы и прогеры с «параноидальным синдромом безопастности», а большинство обычных пользователей вообще не в курсе что такое JavaScript и что его еще и отключить можно.
      • +10
        Не только…

        image
  • 0
    А как быть с теми пользователями которые нажав на кнопку шаринга, натолкнулись на ввод пароля, который, возможно забыли или просто передумали и решили не шарить контен или удалили после шаринга. Как их пересчитывать?
    • 0
      … надо было отследить статистику нажатий именно на кнопку шаринга...
    • 0
      Не скажу точно за все сервисы, но возможность обратиться по url сервиса, передать свой url и узнать сколько раз расшарили имеется)
      • 0
        Точно так и делаю! По карте сайта делаю запросы каждый час и кэширую результаты… Представленный вариант в топите крайне не точен.
  • +3
    А как вы боретесь с блокировкой всплывающих окон?
    • +1
      Тот же вопрос назрел у меня сразу после прочтения. И проскочила мысль что можно сделать кастомное окошко (div «над» сайтом) где бы через iframe подгружался контент страницы шаринга. Единственное — незнаю, могут ли быть какие то проблемы изза защиты какойнить фреймов и т.д.
      • 0
        Теоретически — возможно. Хотя не пробовал
        • 0
          Попробовал: вставил на место вашего коммента iframe с vk.com/share.php.
          Итог: не работает, «Security Breach».
    • +4
      Называется дело было вечером, делать было нечего :)
      Share = {
      	go: function(a, type, url, title, img, text) {
      		type = type || 'facebook';
      		url  = url  || location.href;
      		title= title|| document.title;
      		img  = img  || '';
      		text = text || '';
      
      		var urlSet = this[type](url, title, img, text);
      		var isOpened = this.popup(urlSet);
      		if (null === isOpened) {
      			a.href = urlSet;
      			return true;
      		}
      		return false;
      	},
      	vkontakte: function(purl, ptitle, pimg, text) {
      		url  = 'http://vkontakte.ru/share.php?';
      		url += 'url='          + encodeURIComponent(purl);
      		url += '&title='       + encodeURIComponent(ptitle);
      		url += '&description=' + encodeURIComponent(text);
      		url += '&image='       + encodeURIComponent(pimg);
      		url += '&noparse=true';
      		return url;
      	},
      	odnoklassniki: function(purl, text) {
      		url  = 'http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1';
      		url += '&st.comments=' + encodeURIComponent(text);
      		url += '&st._surl='    + encodeURIComponent(purl);
      		return url;
      	},
      	facebook: function(purl, ptitle, pimg, text) {
      		url  = 'http://www.facebook.com/sharer.php?s=100';
      		url += '&p[title]='     + encodeURIComponent(ptitle);
      		url += '&p[summary]='   + encodeURIComponent(text);
      		url += '&p[url]='       + encodeURIComponent(purl);
      		url += '&p[images][0]=' + encodeURIComponent(pimg);
      		return url;
      	},
      	twitter: function(purl, ptitle) {
      		url  = 'http://twitter.com/share?';
      		url += 'text='      + encodeURIComponent(ptitle);
      		url += '&url='      + encodeURIComponent(purl);
      		url += '&counturl=' + encodeURIComponent(purl);
      		return url;
      	},
      	mailru: function(purl, ptitle, pimg, text) {
      		url  = 'http://connect.mail.ru/share?';
      		url += 'url='          + encodeURIComponent(purl);
      		url += '&title='       + encodeURIComponent(ptitle);
      		url += '&description=' + encodeURIComponent(text);
      		url += '&imageurl='    + encodeURIComponent(pimg);
      		return url;
      	},
      
      	popup: function(url) {
      		return window.open(url,'','toolbar=0,status=0,width=626,height=436');
      	}
      };
      

      <a href="" onclick="return Share.go(this)">like+</a>
      

      т.е. банально проверяем, вернулся ли объект window, если да, то все нормуль, если нет то прописываем ссылку и переходим на неё.

      P.S.: Сорри что-то не нашел тэг спойлера, был ведь вроде или мне не доступен :(
  • 0
    Улучшенная и дополненная версия на базе jQuery с опциями
    Share = {
        /**
         * Показать пользователю дилог шаринга в сооветствии с опциями
         * Метод для использования в inline-js в ссылках
         * При блокировке всплывающего окна подставит нужный адрес и ползволит браузеру перейти по нему
         *
         * @example <a href="" onclick="return share.go(this)">like+</a>
         *
         * @param Object _element - элемент DOM, для которого
         * @param Object _options - опции, все необязательны
         */
        go: function(_element, _options) {
            var
                self = Share,
                options = $.extend(
                    {
                        type:       'vk',    // тип соцсети
                        url:        location.href,  // какую ссылку шарим
                        count_url:  location.href,  // для какой ссылки крутим счётчик
                        title:      document.title, // заголовок шаринга
                        image:        '',             // картинка шаринга
                        text:       '',             // текст шаринга
                    },
                    $(_element).data(), // Если параметры заданы в data, то читаем их
                    _options            // Параметры из вызова метода имеют наивысший приоритет
                );
    
            if (self.popup(link = self[options.type](options)) === null) {
                // Если не удалось открыть попап
                if ( $(_element).is('a') ) {
                    // Если это <a>, то подставляем адрес и просим браузер продолжить переход по ссылке
                    $(_element).prop('href', link);
                    return true;
                }
                else {
                    // Если это не <a>, то пытаемся перейти по адресу
                    location.href = link;
                    return false;
                }
            }
            else {
                // Попап успешно открыт, просим браузер не продолжать обработку
                return false;
            }
        },
    
        // ВКонтакте
        vk: function(_options) {
            var options = $.extend({
                    url:    location.href,
                    title:  document.title,
                    image:  '',
                    text:   '',
                }, _options);
    
            return 'http://vkontakte.ru/share.php?'
                + 'url='          + encodeURIComponent(options.url)
                + '&title='       + encodeURIComponent(options.title)
                + '&description=' + encodeURIComponent(options.text)
                + '&image='       + encodeURIComponent(options.image)
                + '&noparse=true';
        },
    
        // Одноклассники
        ok: function(_options) {
            var options = $.extend({
                    url:    location.href,
                    text:   '',
                }, _options);
    
            return 'http://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1'
                + '&st.comments=' + encodeURIComponent(options.text)
                + '&st._surl='    + encodeURIComponent(options.url);
        },
    
        // Facebook
        fb: function(_options) {
            var options = $.extend({
                    url:    location.href,
                    title:  document.title,
                    image:  '',
                    text:   '',
                }, _options);
    
            return 'http://www.facebook.com/sharer.php?s=100'
                + '&p[title]='     + encodeURIComponent(options.title)
                + '&p[summary]='   + encodeURIComponent(options.text)
                + '&p[url]='       + encodeURIComponent(options.url)
                + '&p[images][0]=' + encodeURIComponent(options.image);
        },
    
        // Живой Журнал
        lj: function(_options) {
            var options = $.extend({
                    url:    location.href,
                    title:  document.title,
                    text:   '',
                }, _options);
    
            return 'http://livejournal.com/update.bml?'
                + 'subject='        + encodeURIComponent(options.title)
                + '&event='         + encodeURIComponent(options.text + '<br/><a href="' + options.url + '">' + options.title + '</a>')
                + '&transform=1';
        },
    
        // Твиттер
        tw: function(_options) {
            var options = $.extend({
                    url:        location.href,
                    count_url:  location.href,
                    title:      document.title,
                }, _options);
    
            return 'http://twitter.com/share?'
                + 'text='      + encodeURIComponent(options.title)
                + '&url='      + encodeURIComponent(options.url)
                + '&counturl=' + encodeURIComponent(options.count_url);
        },
    
        // Mail.Ru
        mr: function(_options) {
            var options = $.extend({
                    url:    location.href,
                    title:  document.title,
                    image:  '',
                    text:   '',
                }, _options);
    
            return 'http://connect.mail.ru/share?'
                + 'url='          + encodeURIComponent(options.url)
                + '&title='       + encodeURIComponent(options.title)
                + '&description=' + encodeURIComponent(options.text)
                + '&imageurl='    + encodeURIComponent(options.image);
        },
    
        // Открыть окно шаринга
        popup: function(url) {
            return window.open(url,'','toolbar=0,status=0,scrollbars=1,width=626,height=436');
        }
    }
    



    // Все элементы класса .social_share считаем кнопками шаринга
    $(document).on('click', '.social_share', function(){
        Share.go(this);
    });
    


    // Пример кнопок с минимальной настройкой
    <p>Поделиться:
        <button class="social_share" data-type="vk">ВКонтакте</button>
        <button class="social_share" data-type="fb">Facebook</button>
        <button class="social_share" data-type="tw">Twitter</button>
        <button class="social_share" data-type="lj">LiveJournal</button>
        <button class="social_share" data-type="ok">Одноклассники</button>
        <button class="social_share" data-type="mr">Mail.Ru</button>
    </p>
    

    • +1
      Спасибо. вот еще кусочек для Google+

      // Google+
      	gg: function (_options) {
      		var options = $.extend({
      			url: location.href			
      		}, _options);
      
      		return 'https://plus.google.com/share?url='
      			+ encodeURIComponent(options.url);
      	},
      
    • 0
      Спасибо. Добавлю сюда еще кусок для LinkedIn.

      //LinkedIn
      li: function(_options) {
          var options = $.extend({
              url:    location.href,
              title:  document.title,
              text:   ''
          }, _options);
      
          return 'http://www.linkedin.com/shareArticle?mini=true'
              + '&url='       + encodeURIComponent(options.url)
              + '&title='     + encodeURIComponent(options.title)
              + '&summary='   + encodeURIComponent(options.text);
      },
      
    • 0
      Возникла необходимость так же размещать кнопки на странице списка новостей те кнопки должны быть под каждой новостью. Данные каждой страницы для каждой кнопки соответственно должны подставляться в шаблоне движка сайта динамически.

      Разметка должна стать такой, добавляем атрибуты data:
      Facebook

      js пока не трогал, там есть где развернуться или надо все переписывать?
      • 0
        Упс, хабр сьел код

        <button data-type="vk" data-url="" data-title="" data-text="" data-image="">ВКонтакте</button>
        
        • 0
          Или скрипт подразумевает данные в data-*? Не работает.
          • 0
            Все, пардон, нашел баг в своем коде, супер что работает.
    • 0
      добавил загрузку данных из meta-тегов OpenGraph:
      Загрузка из OpenGraph
          go: function(_element, _options) {
              var
                  self = Share,
                  options = $.extend(
                      {
                          type:       'vk',                  // тип соцсети
                          url:        location.href,         // какую ссылку шарим
                          count_url:  location.href,         // для какой ссылки крутим счётчик
                          title:      param('title'),        // заголовок шаринга
                          image:      param('image'),        // картинка шаринга
                          text:       param('description'),  // текст шаринга
                      },
                      $(_element).data(), // Если параметры заданы в data, то читаем их
                      _options            // Параметры из вызова метода имеют наивысший приоритет
                  );
      
              if (self.popup(link = self[options.type](options)) === null) {
                  // Если не удалось открыть попап
                  if ( $(_element).is('a') ) {
                      // Если это <a>, то подставляем адрес и просим браузер продолжить переход по ссылке
                      $(_element).prop('href', link);
                      return true;
                  }
                  else {
                      // Если это не <a>, то пытаемся перейти по адресу
                      location.href = link;
                      return false;
                  }
              }
              else {
                  // Попап успешно открыт, просим браузер не продолжать обработку
                  return false;
              }
              
              function param(name) {
                  return $('meta[property=og\\:' + name + ']').attr('content');
              }
          },
      

  • 0
    Пользуюсь кодом из топика, нажимаю поделиться в одноклассниках, в окне такая надпись «Нет доступа к ресурсу», хотя в соседней вкладке открыты одноклассники. Погуглил, у кучи людей подобная проблема, но решения не нашел.
  • 0
    простите за некропостинг, но я запилил виджет для yii: github.com/wapmorgan/ShareWidget
  • 0
    Полезная ссылка на тему: api.yandex.ru/share/
  • 0
    А что означает параметр noparse в ссылке на ВК?
  • 0
    Столкнулся с проблемой, что при переходе по ссылке на шаринг вконтакте с мобильного устройства — на странице подтверждения диалога шеринга слетает кодировка у title и description полей. Все мои страницы и скрипты в UTF-8 и на десктопных браузерах все нормально, а вот на айфоне, например, кодировка слетает. Кто-нибудь знает как решить эту проблему?
    • 0
      Если кто-то столкнется с такой проблемой, то временно я ее решил детектор мобильных устройств и заменой линка на m.vk.com/share.php тк кодировка ломается во время редиректа с обычного домена на m
  • 0
    Я так понимаю времени много прошло с момент публикации, и facebook чето поменял — имя картинка не подхватывается. Как то случайно он выбирает ее…
    • 0
      сейчас надо использовать разметку Open Graph в head страницы, мне помогло
          <meta property="og:url"           content="https://example.ru" />
          <meta property="og:type"          content="website" />
          <meta property="og:title"         content="тайтл" />
          <meta property="og:description"   content="описание" />
          <meta property="og:image"         content="https://example.ru/123/img.png" />
      
      • 0
        Да, только вот она любит кешироваться…
        • 0
          да, настраивать неудобно и оч запутано, в общем:
          developers.facebook.com/tools/debug
          для юзания нужно быть залогиненым, ввести там в форме урл, потом жмакнуть кнопку Debug, потом Fetch new scrape information
  • –1
    Спасибо!

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