В ходе работы мне приходиться посещать довольно много блогов, и то, что я видел на многих из них, - это "панелька" для скрытия контента. Принцип работы данной панельки достаточно прост. Например, чтобы разблокировать кнопку загрузки файла, или прочесть определенную часть страницы необходимо нажать на одну из кнопок шаринга на данной панели.
Данная панель в GitHub’e называется Social Locker (в дальнейшем так и будем её именовать) и является отличным вариантом для раскрутки Вашего ресурса.
Я сделал больше исследований в чтобы найти подходящий блокировщик контента, но большинство из них - платные плагины или очень простые варианты на Git’e.
Поэтому я решил написать свою собственную версию, основу для которой я взял у данного товарища по цеху:
https://codeshack.io/create-your-own-content-locker-html-javascript/
Она не требует большого количества кода, и вы можете настроить ее так, как хотите, хотя вам понадобится опыт работы в HTML, CSS, и jQuery.
Принцип работы моего варианта Social Locker
Допустим у Вас на странице имеется файл который возможно понадобиться пользователю и он захочет его загрузить.
Блок к которому применен Social Locker выглядит вот так:
Пользователь наводит курсор мышки на данный блок и перед ним благодаря анимации открывается вот такая панелька с кнопками для шаринга страницы:
После того как пользователь сделал клик по выбранной им социальной сети появится окно iframe от AddToAny в котором пользователь и совершит шаринг страницы.
После шаринга страницы появится попап окно c текстом. "Спасибо что поделился"
Выглядит данное окно вот так:
Внимательно изучив файл по пути
/SDStudio_SocialLocker_Plus_AddToAny/script.js
В строке 38, Вы увидите код раскомментировав который (и заменив в нем значения на свои) у Вас появится возможность встраивать свою рекламу от Google в данное попап окно.
После того как попап окно исчезнет Smart Locker будет отключен, и у пользователя появится возможность загрузить файл. Причем достаточно один раз разшарить страницу и смарт локер будет снят со всех "залокированных" ссылок.
Как подключить к себе на сайт
В начале Вам нужно скачать мой смарт локер по ссылке ниже:
Загрузить SDStudio Smart Locker:
И соответственно подключить файлы style.css и script.js из загруженной папки к своему сайту.
Мой скрипт предполагает что на Вашем сайте уже подключены FontAwesome и AddToAny.
При написании поста Вам необходимо поместить ссылку для применения Social Locker в блок:
<div class = "sociallocker" >
<a href = "/file.zip" >
Загрузить файл
</a>
</div>
Содержимое файла style.css:
.sociallocker {
background-color: #EEEEEE;
text-align: center;
position: relative;
max-width: 500px;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
border-radius: 10px;
}
.sociallocker-overlay {
background-color: rgba(0, 0, 0, 0.6);
font-size: 20px;
padding-right: 15px;
padding-left: 15px;
font-weight: bold;
color: #ffffff;
transition: all 0.2s ease;
}
.sociallocker-overlay i {
margin-right: 10px;
margin-left: 25px;
}
.sociallocker:hover .sociallocker-overlay {
top: -100%;
transition: all 0.2s linear;
}
.sociallocker:hover .sociallocker-content {
top: 100%;
transition: all 0.2s linear;
}
.sociallocker-content a {
display: inline-block;
text-decoration: none;
padding: 10px 20px;
background-color: #777777;
color: #f9f9f9;
border-radius: 4px;
font-weight: bold;
}
.sociallocker-overlay,
.sociallocker-content,
.sociallocker-links {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
}
.sociallocker-content {
background-color: #ccc;
transition: all 0.2s ease;
}
.social-1 {
text-decoration: none;
color: #ffffff;
display: inline-block;
width: 60px;
height: 60px;
overflow: hidden;
margin-right: 5px;
}
.social-1 i {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.social-1:hover i {
background-color: rgba(0, 0, 0, 0.1);
transform: scale(1.2);
transition: all 0.2s;
}
.fb {
background-color: #4561A8;
}
.tw {
background-color: #17ADEA;
}
.gp {
background-color: #BF3B28;
}
.in {
background-color: #1679B1;
}
.pi {
background-color: #D9303C;
}
.su {
background-color: #E84930;
}
div# a2apage_thanks_kit {
min - height: 50 px;
}
@media screen and (max-width: 560px) {
.sociallocker-overlay {
font-size: 15px;
}
}
/* Высота кнопок AddToAny */
.a2a_kit a {
min-height: 45px !important;
}
div.sociallocker-content a {
color: white !important;
border: white 2px solid;
background-color: #777777;
}
div.sociallocker-content a:hover {
color: #002467 !important;
border: #002467 2px solid;
background-color: #ffffff;
}
Содержимое файла script.js:
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// ИПОЛЬЗОВАНИЕ :
//
// Помещаем контент для скрытия в контейнер:
// <div class = "sociallocker" >
// <a href = "/file.zip" >
// Загрузить файл
// </a>
// </div>
// Данный скрипт автоматически обернет каждый блок ссылки в свою обвертку.
// И не даст загрузить файл пока пользователь не зашарит Вашу страницу
//
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// =======================================================
// =======================================================
// AddToAny START
// =======================================================
// =======================================================
// AddToAny Подключаем скрипт после загрузки страницы
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "//static.addtoany.com/menu/page.js";
// Use any selector
$("header").append(s);
var a2a_config = a2a_config || {};
// $('div#a2apage_overlay')
a2a_config.thanks = {
postShare: true,
ad: false,
// Указываем свой GoogleAdsence если хотим что бы отображался блок рекламы в окне
// ad: '<ins class=\"adsbygoogle\"\
// style=\"display:inline-block;width:300px;height:250px\"\
// data-ad-client=\"ca-pub-xxxxxxxxxxxxxxxx\"\
// data-ad-slot=\"1234567890\"></ins>\
// <\script>\
// (adsbygoogle = window.adsbygoogle || []).push({});\
// <\/script>'
};
//AddToAny - Меняем локализацию на свой язык
//https://www.addtoany.com/buttons/customize/translation_localization
// var a2a_config = a2a_config || {};
a2a_config.locale = "ru-RU";
// =======================================================
// =======================================================
// AddToAny END
// =======================================================
// =======================================================
jQuery(document).ready(function ($) {
// Оборачиваем каждую кнопку SocialLock
// START
// --------------------------------------------------------------
// Оборачиваем весь контент в нутри div#sociallocker в блок для скрытия в оверлее
$('div.sociallocker').wrapInner("<div class='sociallocker-content'></div>");
// ВСТАВКА КОДА С КНОПКАМИ И ОВЕРЛЕЕМ
// ====================================
// Вставляем блок с кнопками от AddToAny перед обернутым содержимым
$("<div class=\"sociallocker-links\"> <!-- AddToAny BEGIN --> <div class=\"a2a_kit a2a_kit_size_32 a2a_default_style\"> <a class=\"a2a_dd\" href=\"https://www.addtoany.com/share\"> </a> <a class=\"a2a_button_facebook\"></a> <a class=\"a2a_button_twitter\"></a> <a class=\"a2a_button_google_plus\"></a> <a class=\"a2a_button_pinterest\"></a> <a class=\"a2a_button_linkedin\"></a> <a class=\"a2a_button_trello\"></a> </div> </div>").insertBefore(".sociallocker-content");
// Вставляем блок с оверлеем
$("<div class=\"sociallocker-overlay\"><i class=\"fa fa-lock\"></i>Загрузить файл добавив страницу в свою социальную сеть<i class=\"fa fa-share-alt\"></i></div > ").insertAfter('.sociallocker-content');
// --------------------------------------------------------------
// Оборачиваем каждую кнопку SocialLock
// END
// =======================================================================================================
// Едреный скрипт благодаря которому появляется возможность отследить изменения style свойств объекта
// START
// -------------------------------------------------------------------------------------------------------
$(window).bind("load", function () {
// https://github.com/RickStrahl/jquery-watch
/*
jquery-watcher
Version 1.21 - 1/19/2016
© 2014-2016 Rick Strahl, West Wind Technologies
www.west-wind.com
Licensed under MIT License
http://en.wikipedia.org/wiki/MIT_License
*/
(function ($, undefined) {
$.fn.watch = function (options) {
/// <summary>
/// Allows you to monitor changes in a specific
/// CSS property of an element by polling the value.
/// You can also monitor attributes (using attr_ prefix)
/// or property changes (using prop_ prefix).
/// when the value changes a function is called.
/// The callback is fired in the context
/// of the selected element (ie. this)
///
/// Uses the MutationObserver API of the DOM and
/// falls back to setInterval to poll for changes
/// for non-compliant browsers (pre IE 11)
/// </summary>
/// <param name="options" type="Object">
/// Option to set - see comments in code below.
/// </param>
/// <returns type="jQuery" />
var opt = $.extend({
// CSS styles or Attributes to monitor as comma delimited list
// For attributes use a attr_ prefix
// Example: "top,left,opacity,attr_class"
properties: null,
// interval for 'manual polling' (IE 10 and older)
interval: 100,
// a unique id for this watcher instance
id: "_watcher_" + new Date().getTime(),
// flag to determine whether child elements are watched
watchChildren: false,
// Callback function if not passed in callback parameter
callback: null
}, options);
return this.each(function () {
var el = this;
var el$ = $(this);
var fnc = function (mRec, mObs) {
__watcher.call(el, opt.id, mRec, mObs);
};
var data = {
id: opt.id,
props: opt.properties.split(','),
vals: [opt.properties.split(',').length],
func: opt.callback, // user function
fnc: fnc, // __watcher internal
origProps: opt.properties,
interval: opt.interval,
intervalId: null
};
// store initial props and values
$.each(data.props, function (i) {
var propName = data.props[i];
if (data.props[i].startsWith('attr_'))
data.vals[i] = el$.attr(propName.replace('attr_', ''));
else if (propName.startsWith('prop_'))
data.vals[i] = el$.prop(propName.replace('props_', ''));
else
data.vals[i] = el$.css(propName);
});
el$.data(opt.id, data);
hookChange(el$, opt.id, data);
});
function hookChange(element$, id, data) {
element$.each(function () {
var el$ = $(this);
if (window.MutationObserver) {
var observer = el$.data('__watcherObserver' + opt.id);
if (observer == null) {
observer = new MutationObserver(data.fnc);
el$.data('__watcherObserver' + opt.id, observer);
}
observer.observe(this, {
attributes: true,
subtree: opt.watchChildren,
childList: opt.watchChildren,
characterData: true
});
} else
data.intervalId = setInterval(data.fnc, opt.interval);
});
}
function __watcher(id, mRec, mObs) {
var el$ = $(this);
var w = el$.data(id);
if (!w) return;
var el = this;
if (!w.func)
return;
var changed = false;
var i = 0;
for (i; i < w.props.length; i++) {
var key = w.props[i];
var newVal = "";
if (key.startsWith('attr_'))
newVal = el$.attr(key.replace('attr_', ''));
else if (key.startsWith('prop_'))
newVal = el$.prop(key.replace('prop_', ''));
else
newVal = el$.css(key);
if (newVal == undefined)
continue;
if (w.vals[i] != newVal) {
w.vals[i] = newVal;
changed = true;
break;
}
}
if (changed) {
// unbind to avoid recursive events
el$.unwatch(id);
// call the user handler
w.func.call(el, w, i, mRec, mObs);
// rebind the events
hookChange(el$, id, w);
}
}
}
$.fn.unwatch = function (id) {
this.each(function () {
var el = $(this);
var data = el.data(id);
try {
if (window.MutationObserver) {
var observer = el.data("__watcherObserver" + id);
if (observer) {
observer.disconnect();
el.removeData("__watcherObserver" + id);
}
} else
clearInterval(data.intervalId);
}
// ignore if element was already unbound
catch (e) {}
});
return this;
}
String.prototype.startsWith = function (sub) {
if (sub === null || sub === undefined) return false;
return sub == this.substr(0, sub.length);
}
})(jQuery, undefined);
// -0-------------------------
// some element to monitor
var el = $("#a2apage_overlay");
// hook up the watcher
el.watch({
// specify CSS styles or attribute names to monitor
properties: "display,top,left,opacity,attr_class,prop_innerHTML",
// callback function when a change is detected
callback: function (data, i) {
// console.log('style changed!');
// Событие при изменении свойств стилией бекграунда
// START
// -------------------------------------------------------------
// if ($('div#a2apage_modal').attr('aria-label') == "Спасибо, что поделился") {
if ($("div#a2apage_modal").css("display") == "block") {
// console.log('Внимание!!!! Изменение атрибутов начало происходить!!!!');
setTimeout(function () {
//alert('Появился');
//
$("div#a2apage_overlay").css("display", "none");
$("div#a2apage_modal").css("display", "none");
$(".sociallocker-links").each(function () {
$(this).css('display', 'none');
});
$(".sociallocker-overlay").each(function () {
$(this).css('display', 'none');
});
$(".sociallocker-content").each(function () {
$(this).css('top', '0');
});
}, 2500);
};
// -------------------------------------------------------------
// END
var propChanged = data.props[i];
var newValue = data.vals[i];
var el = this;
var el$ = $(this);
// do what you need based on changes
// or do your own checks
}
});
});
// -------------------------------------------------------------------------------------------------------
// Едреный скрипт благодаря которому появляется возможность отследить изменения style свойств объекта
// END
});
Если же у Вас несколько ссылок придется каждую из них помещать в блок:
<div class = "sociallocker" > ссылка </a>
На данный момент я не стал заморачиваться с возможностью вставки нескольких ссылок в один блок (но если будет слишком много желающих в комментариях, уверен я на это выкрою время) так как в очень редких случаях использую несколько ссылок в одном блоке.
Минусы моего Smart Locker
При клике на кнопку локера на мобильных устройствах:
Панель с социальными кнопками не успевает отображаться и сразу происходит переход на iframe социальной сети + срабатывает отображение попап окна и автоматическое открытие ссылок. В ближайшем будущем я постараюсь данный баг исправить. А пока предлагаю просто не подключать социал локер для мобильных устройств. Файлы с мобильного скачивают редко.
Для того что бы подключить социал локер только для ПК воспользуйтесь решением ниже (подключаем скрипт локера только для устройств ширина экрана которых больше 768px):
<script>
jQuery(document).ready(function ($) {
if ( $(window).width() >= 768) {
var s = document.createElement("script");
s.type = "text/javascript";
s.src = "/SDStudio_SocialLocker_Plus_AddToAny/script.js";
// Use any selector
$("header").append(s);
};
});
</script>
Полезности
jquery-watch
Для реализации задуманного мне пришлось весьма потрудиться для правильного запуска скрипта разблокировки контента после того как пользователь "зашарил страницу". Все дело в том что необходимо отслеживать отобразился ли попап после шаринга. Для этого мне пришел на помощь данный скрипт, а точнее библиотека:
https://github.com/RickStrahl/jquery-watch
Пример кода для тестирования плагина. В данном фрагменте кода мы следим за изменением стилей и свойств блока с классами '.modal-wrapper.styled':
jQuery(document).ready(function($){
// watch the content
$(".modal-wrapper.styled").watch({
properties: "top,left,opacity,display,attr_class",
watchChildren: true,
callback: function (data, i) {
console.log("text changed");
}
});
});
Без данного плагина мне бы не удалось отследить атрибут style - display у элемента страницы $("#a2apage_overlay"). От себя отмечу что это единственное решение которое работает как нужно и практически во всех браузерах.
AddToAny
Если У Вас появится желание сделать свой вариант возможно Вам понадобится документация. В данном случае основной акцент будет на скрипт для социальной шары от AddToAny.
По ссылке ниже Вы можете узнать подробнее о функциях и полезных советах при работе с кнопками социальных сетей от сервиса.