Как сделать Css Transition только что добавленному элементу

Понадобилось сделать плавный переход от одной картинки к другой, средствами javascript, как он есть. То есть, ни тебе jQuery.animate ни ещё чего-нибудь.

Сразу подумалось: “Есть же css-transition, круто!” Быстренько накидал стиль:

main.css
1
2
3
4
5
6
7
8
.image img {
  opacity: 0;
  transition: opacity .5s;
}

.image img.fade-in {
  opacity: 1;
}

потом, в скрипте

script.js
1
2
3
4
5
6
var $div = document.querySelector('.image');
var $image = document.createElement('img');
$image.src = 'https://placekitten.com/400/300';

$div.appendChild($image);
$image.classList.add('fade-in');

Казалось бы, мы добавили img на страницу, потом добавили класс fade-in, прозрачность должна плавно измениться, правда?

Нет, к сожалению, не правда.

Чтобы прозрачность всё-таки начала изменяться, необходимо (и, вроде бы, достаточно) сделать так:

script-with-timeout.js
1
2
3
4
$div.appendChild($image);
setTimeout(function() {
  $image.classList.add('fade-in');
}, 0);

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

Тестовая страничка на codepen.

Phantomjs и бандлы

В процессе написания библиотеки, которая должна была упрятать в себя проверки свойств различных DOM-узлов html-дерева внутрь простенького DSL (три аббревиатуры на одно предложение, ого..), выяснил, а, вернее, вспомнил, что phantomjs принципиально не поддерживает Object.assign, например.

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

Такой код phantom использовать отказывается — dom-check–wrong.js
1
2
3
4
5
6
7
8
9
var DomChecker = function(/* ... */) {
  // ...
};

Object.assign(DomChecker.prototype, {
  textIsEqual: function(value) {
    // ...
  }
});

не будет выполняться в phantomjs, если втянуть его, например, webpack-ом в какой-нибудь бандл. Более того, с момента, когда мы попытаемся использовать Object.assign() весь дальнейший код выполнен не будет.

Приходится возвращаться к дедовским методам:

А так вполне себе — dom-check–right.js
1
2
3
4
5
6
7
8
9
var DomChecker = function(/* ... */) {
  // ...
};

var cp = DomChecker.prototype;

cp.textIsEqual: function(value) {
  // ...
};

Минусы — чуть больше кода. Плюсы — код (ура!) работает даже в бандле, который будет скормлен phantomjs.

P.S. Или уже создать (или использовать?) phantom-shims?

Привет, Github Pages

Переехал на github.io, стало более дешевле, стало более веселее.

Соответственно, плата вносится только за домен, а дополнительным бонусом – собственный красивый email.

Зависимости внутри пакета в Python

Что за прелесть эти ваши сказочки..

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

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

Небольшая пауза, пока я вычищаю из поста все ругательства, которые накопились за пять дней “знакомства” с языком.

Тем не менее, способ справиться с “кошмарным ужасом” зависимостей есть.

Алиасы для Localhost

Давно хотелось делать для работы в проектах на своем компе алиасы вида project1.local. Казалось бы, уж чего проще, поставил nginx, отредактировал пару файлов и - вперед!

Совершенно согласен, особенно после того, как всё заработало и больше не надо выискивать правильный рецепт. Чтобы больше не искать, что именно надо делать и где, оставлю рецепт здесь.

Перво-наперво, редактируем /etc/hosts:

1
project1.local 127.0.0.1

Во-вторых, предположим, наш проект запущен на порту 9999 и мы бы не хотели набивать порт. Пишем в /etc/nginx/conf.d/project1.conf:

1
2
3
4
5
6
7
8
9
10
server {
  listen 80;

  server_name project1.local;

  location / {
    proxy_pass http://127.0.0.1:9999/;
    proxy_set_header Host $host;
  }
}

Для каждого последующего проекта заменяем project1 и 9999 на имя проекта и номер порта и движемся дальше.