softsprint menu Заказать

ООП в прототипном стиле JavaScript

Январь 25, 2017 в 7:35 | wiki

Как мы знаем, в JavaScript есть два вида наследования:
— ООП в функциональном стиле;
— ООП в прототипном стиле;

Более популярным является прототипный стиль, поскольку имеет главное преимущество — методы в прототипе автоматически доступны везде и всегда. Почему? Методы записываются в объекте, ссылка на который находится в специальном свойстве prototype. Такое свойство есть у каждой функции — оно ссылается на объект с одним единственным свойством constructor:

1
2
3
4
function F() {};
F.prototype = {
  constructor: F
};

Объекты-прототипы есть и у встроенных конструкторов (Object.prototype, Array.prototype и т.д) — в них хранятся служебные методы, например, toString, join, прочие.
Мы также всегда можем добавить свои методы в объект конструктор, например:

1
2
Object.prototype.countSomething = function() {...}
F.prototype.countSomething = function() {...}

И эти методы станут доступны новым объекту, который создаст конструктор F:

1
2
3
4
function F() {};
F.prototype.countSomething = function() {...};
var f = new F();
f.countSomething(); // will work!

Каким образом?
Свойство F.prototype буквально означает, что при запуске конструктора F будет создан новый объект, который получит ссылку f.__proto__ на объект-прототип со всеми его методами:

object proto

Вот и получается, что:

1
2
3
alert(f.__proro__ == F.prototype) // true;
alert(f.countSomething == F.prototype.countSomething); // true
alert(f.__proro__. countSomething == F.prototype.countSomething); // true

Обратите внимание на последние 2 строки: если метод countSomething() не нашёлся в самом объекте f, созданным конструктором F, поиск продолжается в его объекте-прототипе (f.__proro__).

Пойдём дальше и рассмотрим наследование конструкторов один от другого. Пускай, у нас есть 2 конструктора: Second будет наследовать от First:

1
2
3
4
5
function First() {...};
First.prototype = {...}; // здесь общие методы в объекте-прототипе
function Second() {...};
Second.prototype = {...}; // здесь конкретные методы в объекте-прототипе
var obj = new Second();

Алгоритм наследования такой: если нужный метод не найдёт в объекте obj, мы ищем в Second.prototype (объекте-прототипе конструктора, который создал obj); если нужного метода и там нет, ищем в First.prototype:
obj > Second.prototype > First.prototype.

Как мы уже знаем, при создании новый объект obj автоматически получает ссылку на объект-прототип: obj.__proto__ == Second.prototype. А как же заставить Second.prototype наследовать от First.prototype?
Можно, конечно, прописать такую конструкцию: Second.prototype.__proto__ = First.prototype, но на самом деле есть специальный метод:

1
Second.prototype = Object.create(First.prototype);

Он создаёт новый пустой объект с ссылкой на объект-прототип First.prototype. Далее мы смело можем добавлять нужные нам методы в Second.prototype. Итоговая последовательность наследования:

1
2
3
4
5
6
function First() {...}; // объявили общий конструктор 
First.prototype = {...}; // добавили методы в его объект-прототип
function Second() {...}; // объявили конкретный конструктор
Second.prototype = Object.create(First.prototype); // создали пустой объект с ссылкой на прототип First.prototype
Second.prototype = {...}; // добавили методы в его объект-прототип
var obj = new Second(); // запустили конструктор

Что такое this в JavaScript?

Январь 18, 2017 в 1:44 | wiki

Что такое this в JavaScript? Постараемся ответить своими словами:
this — это ссылка на текущий объект, в котором этот самый this и упоминается;
this — это ссылка на объект, указанные перед точкой свойства или метода;
this — это ссылка на этот новый объект, созданный с помощью конструктора (класса).

Давайте рассмотрим пример конструктора, который создаёт новый объект, добавляя в него методы:

1
2
3
4
5
6
7
8
9
10
11
12
13
"use strict"
function Machine(power) {
	this.power = power;
	this.hi = function () {alert("result for THIS: " + this.power)}; // (1)
	var self = this; 
	function priv() {alert ("result for SELF: " + self.power)}; // (2)
	this.hello = function () {
		priv()
	};   
}; 
var machine = new Machine(10);
machine.hi();
machine.hello();

Machine — это конструктор, который при вызове создаёт объект и записывает ссылку на него в переменную machine. В строке (1) метод hi выводит сообщение со значением свойства power.

Свойство power и метод hi имеют один и тот же this — ссылку на новый объект, который будет создан конструктором Machine.

Здесь всё понятно, поэтому смотрит на cтроку (2): в функции priv() вместо this.power мы указали self.power. Зачем?

Дело в том, что на момент инициализации функции priv() в строке (2) её значение this не определено (для режима «use strict») либо равно window (без «use strict»), т.е также не определено! С этой целью мы умышленно создали переменную self и записали в неё ссылку на текущий объект, который создаст конструктор. Теперь всё ОК — функция priv() отобразит значение свойства power в нужном нам контексте.

Конечно, вместо self мы могли бы использовать методы call/apply/bind для строгой привязки контекста, например priv.call(this). Но описанное решение с self является более простым!

Перевод темы WordPress: _e функция и .mo, .po файлы

Декабрь 5, 2016 в 12:56 | wiki

Эта заметка посвящена переводу тем WordPress без подключения плагинов, например, qTranslate X.

Краткий алгоритм такой:

1) В файлах PHP применяем функцию такого вида (пример для тега h1):

1
<h1><?php _e('title', 'softsprint'); ?></h1>

‘title’ — это текст, который мы будем переводить. Он и будет отображаться в теге h1 нашей темы.
‘softsprint’ — название папки темы, которую подвергаем переводу. В нашем случае папка называется softsprint.
Подробнее о функции _e можете прочитать здесь:
https://codex.wordpress.org/Function_Reference/_e
http://wp-kama.ru/function/_e

2) Вытягиваем значения для перевода из файла PHP с помощью онлайн-сервисов, например, http://www.icanlocalize.com/tools/php_scanner и получаем файл .po

3) Открываем полученный файл .po в софте Poedit и прописываем переводы для каждого значения. Там же определяем локаль (задаём язык): например, ru_RU:
poedit-ru_ru

4) Сохраняем наш .po файл и компилируем его в .mo файл. Скомпилированный .mo файл переименовываем в ru_RU.mo (или иначе, согласно локации нужного нам языка).
Список языков и стран:
http://www.gnu.org/software/gettext/manual/html_chapter/gettext_16.html#Language-Codes
http://www.gnu.org/software/gettext/manual/html_chapter/gettext_16.html#Country-Codes

5) Помещаем файл ru_RU.mo в папку languages, расположенную в папке нашей темы (в нашем случае это — softsprint). Файл .po необязательно помещать в папку, но сохранить его себе нужно для возможных редактирований/добавлений переводов, которые могут понадобиться в будущем

6) В файле functions.php нашей темы прописываем:

1
2
3
4
<?php function my_theme_setup(){
	load_theme_textdomain('softsprint', get_template_directory() . '/languages');
}
add_action('after_setup_theme', 'my_theme_setup');?>

‘softsprint’ — название папки нашей темы;
‘/languages’ — папка, в которой размещён файл ru_RU.mo

Детальнее о функции load_theme_textdomain здесь: http://wp-kama.ru/function/load_theme_textdomain
В результате получаем лаконичный код в файлах PHP без лишних плагинов (например, qTranslate X ) и конструкций такого вида:

1
<li><?php _e('Google Analytics и счётчики'); ?></li>

Кроме того, редактирование перевода становится централизованным (с одного файла .po) и не требует открывать и редактировать каждый файл php отдельно.

CSS3 анимация в Google Web Designer

Октябрь 17, 2016 в 2:28 | wiki

Flash уходит в прошлое, а на замену ему приходит HTML5, точнее новые возможности CSS3. Во многом такой переход обязан отсутствию поддержки flash на устройствах Apple (iPhone, iPad). В этой заметке мы посмотрим, как создавать анимации на CSS3 с помощью бесплатной программы Google Web Designer (версия 1.6.1.0726 на момент написания поста). Понятно, что описывать вручную анимацию CSS3 очень долго, поэтому продукты от Google и Adobe (Adobe Edge Animate CC) и набирают популярности.

В рамках данной заметки рассмотрим только минимально необходимый функционал Google Web Designer. В сети представлено достаточно уроков и материалов для детального изучения — гуглите ))

Итак, размер области анимации задаём здесь:

google web designer area

Добавить изображение в созданную область просто — достаточно перетянуть в неё нужную картинку с папки на Вашем ПК. Для того, чтобы разместить изображение относительно начала координат созданной области (верхний левый угол), указываем 0 (ноль) в следующих полях:

google web-designer position

Логика построения анимации заключается в добавлении кадров с определёнными интервалами времени — keyframes, что соответствует свойствам анимации в CSS (@keyframes). При создании кадра определяются свойства объекта (картинки), например, размеры или положение, прочие эффекты. Совокупность кадров определяет анимацию.

google-web-designer-animation

При нажатии правой кнопки мыши есть возможность указать количество повторов анимации:

google web-designer loop
Более сложными являются события (events), которые Вы можете прописать вручную с помощью JavaScript, но зачем? В Google Web Designer имеется удобный функционал определения событий. Давайте рассмотрим пример. Итак, например, нам нужно при наведении на объект остановить бесконечную анимацию на нём, а при отводе мыши запустить её заново. Правой кнопкой мыши нажимаем на анимированном объекте и выбираем «add event».

google-web-designer-add-event
Далее выбираем тип события, например, движение по целевому объекту «mousemove»:

google-web-designer-mousmove
Выбираем объект, наведение мыши на котором будет срабатывать и добавлять нужный нам CSS-стиль:

google-web-designer-css

google-web-designer-event

Добавили свойство animation-play-state: paused;
Это буквально означает, что нужно поставить анимацию на паузу при наведении мыши на нужный нам объект.

Прочие возможности Google Web Designer Вы можете попробовать самостоятельно, но перечисленного выше вполне хватает, чтобы сделать показанную ниже анимацию. Она работает на всех видах устройств (браузерах), является максимально лёгкой по размеру и хорошо поддаётся настройке (изменение скорости анимации отдельных элементов и их свойств, прочее), поскольку её исходных кодом является валидный CSS. Мы всегда можем это CSS-код отредактировать вручную в любом редакторе. Итак, смотрим:













FOR SALE

SOLD

Форма обратной связи для WordPress с reCaptcha

Август 22, 2016 в 2:57 | wiki

Существует множество форм обратной связи для установки на сайте WordPress: простые самописные решения и продвинутые плагины с конструкторами форм, например, Contact Form 7. Учитывая большую популярность плагина Contact Form 7, остаётся открытым вопрос его безопасности и защищённости… поГуглите, плз!

Итак, когда у нас возникла задача интегрировать форму обратной связи в кастомную тему WordPress, критерии выбора решений были очень просты:

В итоге выбор остановился на «AntiRobot Contact Form» — https://wordpress.org/plugins/antirobot-contact-form/

Мы доработали плагин под нужды клиента:

Согласно инструкции плагин добавляется с помощью шорт-кода

. В нашем случае в созданную тему был имплементирован следующий код:

1
<?php echo do_shortcode('[antirobot_contact_form]'); ?>

Модифицированный плагин можете скачать здесь

contact form

Импорт миниатюр постов при переносе сайта WordPress

Июль 29, 2016 в 1:58 | wiki

Краткая заметка о переносе контента с одного сайта WordPress на другой домен или о переносе сайта WordPress на другой хостинг без изменения домена. Итак, решений есть много, например, сделать дамп базы сайта WordPress и файлов FTP, перенести всё на новый хостинг, прописать настройки в файле wp-config.php, предварительно сделав импорт базы, прочее.

Нас с Вами будет интересовать самый простой способ перенести контент — импорт/экспорт записей (постов), страниц, кастомных элементов wordpress (таксономия) и т.д.

Для экспорта достаточно перейти в раздел: Tools > Export. В результате Вы загрузите файл формата XML.
Для импорта контента понадобится дефолтный плагин «WordPress Importer«, который устанавливается автоматически при выборе пункта меню Tools > Import > WordPress.

Если отметить чекбокс «Import Attachments«, то в папку wp-content/uploads/ будут загружены все изображения, ссылки на которые есть в XML-файле импорта. Эти изображения отобразятся заодно и в разделе: Media > Library админки WordPress и пропишутся в базе.
import wordpress

Всё просто на первый взгляд, но есть проблема: таким способом невозможно импортировать миниатюры постов и страниц (featured images или thumbnails). Для этого нужно сделать «финт ушами»:

Таким образом, проблема с импортом миниатюр решается практически стандартными средствами WordPress.

Скрипт плавного скролла WordPress

Июль 9, 2016 в 6:05 | wiki

Всем привет!

Недавно столкнулся с типичной задачей на сайте WordPress — нужно было сделать плавный скролл к целевому элементу на странице при нажатии на ссылку в меню сайта. Собственно, это — стандартный функционал любого современного лендинга. В нашем случае задача состояла в использовании чистого JavaScript без подключения внешних фреймворков, например, jQuery.
В сети есть не мало плагинов для WordPress для плавного скроллинга, например, https://ru.wordpress.org/plugins/tags/smooth-scroll
Но мы все знаем, что добавление любого плагина в наш сайт снижает его безопасность на взлом. В большинстве случаев сайты на WordPress взламываются именно через плагины — делаем выводы!
Итак, написан следующий код для медленного (плавного) скроллинга по странице:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
document.addEventListener("click", function (event) {
	var target = event.target;
	if (event.target.getAttribute("href")) {
		var targetHref = event.target.getAttribute("href")
	} else return false;
	if (targetHref.indexOf("#") >= 0) {
		var pos = targetHref.indexOf("#") + 1;
		var elemHref = document.getElementById(targetHref.slice(pos));
		moveScroll(elemHref);
		event.preventDefault()
	};
});
function moveScroll(elem) {
	var travel = 40;
	var time = 10;
	if (Math.abs(elem.getBoundingClientRect().top) < 1) return false;
	if (elem.getBoundingClientRect().top < 0) {
		if (Math.abs(elem.getBoundingClientRect().top) < travel) {
			window.scrollBy(0,-1);
			setTimeout(moveScroll,time/5,elem);
			} else {
			window.scrollBy(0,-travel);
			setTimeout(moveScroll,time,elem);
		}
	};
	if (elem.getBoundingClientRect().top > 0) {
		if (Math.abs(elem.getBoundingClientRect().top) < travel) {
			window.scrollBy(0,1);
			setTimeout(moveScroll,time/5,elem);
			} else {
			window.scrollBy(0,travel);
			setTimeout(moveScroll,time,elem);
		}
	}	
};

Функция скроллинга запускается рекурсивно через промежутки времени, равные time = 10 мс.
travel = 40 — это ход вертикального скроллинга при каждом рекурсивном вызове функции.
Представленный скрипт работает для ссылок вида:

1
<a href="http://softsprint.net/en/#about">About us</a>

т.е. скрипт проверяет, есть ли в ссылке обращение к ID элемента, к которому, собственно, и прокрутиться наша страница.

На сегодня всё — спасибо за прочтение заметки!

Иконка домика вместо текста «Домой» в меню WordPress

Июль 13, 2015 в 6:55 | wiki

подробнее >

softsprint adoptive design

Проверка сайта на адаптивность google

Июнь 5, 2015 в 6:40 | wiki

подробнее >

Как установить WooCommerce на свою тему WordPress?

Март 15, 2015 в 6:24 | wiki

подробнее >

Давайте обсудим

softsprint heart

Наши контакты

Львов, Украина
mob: +380 97 551 44 55
skype: softsprint.net

Скажите Привет!