ÐÑиÑм пÑогÑаммиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Â«Ð¼Ð¾Ð´ÑлÑ» Ð¸Ð¼ÐµÐµÑ Ð³Ñомадное колиÑеÑÑво ваÑиаÑий. Ðн немного Ð¿Ð¾Ñ Ð¾Ð¶ на ÑÑÑÑÑик, коÑоÑÑй Ð¼Ñ ÑаÑÑмаÑÑивали Ñанее, иÑполÑзÑÐµÑ Ð°Ð½Ð°Ð»Ð¾Ð³Ð¸ÑнÑй пÑиÑм, но на ÑÑовне вÑÑе.
Ðго ÑÐµÐ»Ñ â ÑкÑÑÑÑ Ð²Ð½ÑÑÑенние деÑали ÑеализаÑии ÑкÑипÑа. Ð Ñом ÑиÑле: вÑеменнÑе пеÑеменнÑе, конÑÑанÑÑ, вÑпомогаÑелÑнÑе мини-ÑÑнкÑии и Ñ.п.
ÐаÑем нÑжен модÑлÑ?
ÐопÑÑÑим, Ð¼Ñ Ñ Ð¾Ñим ÑазÑабоÑаÑÑ ÑкÑипÑ, коÑоÑÑй Ð´ÐµÐ»Ð°ÐµÑ ÑÑо-Ñо полезное на ÑÑÑаниÑе.
Ð£Ð¼ÐµÑ ÑабоÑаÑÑ Ñо ÑÑÑаниÑей, Ð¼Ñ Ð¼Ð¾Ð³Ð»Ð¸ Ð±Ñ ÑделаÑÑ Ð¼Ð½Ð¾Ð³Ð¾ Ñего, но Ñак как пока ÑÑого не бÑло (ÑкоÑо наÑÑимÑÑ), Ñо пÑÑÑÑ ÑкÑÐ¸Ð¿Ñ Ð¿ÑоÑÑо вÑÐ²Ð¾Ð´Ð¸Ñ ÑообÑение:
Файл hello.js
// глобалÑÐ½Ð°Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð½Ð°Ñего ÑкÑипÑа
var message = "ÐÑивеÑ";
// ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ Ð²Ñвода ÑÑой пеÑеменной
function showMessage() {
alert( message );
}
// вÑводим ÑообÑение
showMessage();
У ÑÑого ÑкÑипÑа еÑÑÑ Ñвои внÑÑÑенние пеÑеменнÑе и ÑÑнкÑии.
Рданном ÑлÑÑае ÑÑо message и showMessage.
ÐÑедположим, ÑÑо Ð¼Ñ Ñ
оÑели Ð±Ñ ÑаÑпÑоÑÑÑанÑÑÑ ÑÑÐ¾Ñ ÑкÑÐ¸Ð¿Ñ Ð² виде библиоÑеки. ÐаждÑй, кÑо Ñ
оÑеÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾ÑеÑиÑелÑм вÑдавалоÑÑ Â«ÐÑивеÑ» â Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоÑÑо подклÑÑиÑÑ ÑÑÐ¾Ñ ÑкÑипÑ. ÐоÑÑаÑоÑно ÑкаÑаÑÑ Ð¸ подклÑÑиÑÑ, напÑимеÑ, как внеÑний Ñайл hello.js â и гоÑово.
ÐÑли подклÑÑиÑÑ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ñй ÑкÑÐ¸Ð¿Ñ Ðº ÑÑÑаниÑе «как еÑÑÑ», Ñо возможен конÑÐ»Ð¸ÐºÑ Ñ Ð¿ÐµÑеменнÑми, коÑоÑÑе она иÑполÑзÑеÑ.
То еÑÑÑ, пÑи подклÑÑении к Ñакой ÑÑÑаниÑе он ÐµÑ Â«ÑломаеÑ»:
<script>
var message = "ÐожалÑйÑÑа, нажмиÑе на кнопкÑ";
</script>
<script src="hello.js"></script>
<button>Ðнопка</button>
<script>
// ожидаеÑÑÑ ÑообÑение из пеÑеменной вÑÑе...
alert( message ); // но на Ñамом деле бÑÐ´ÐµÑ Ð²Ñведено "ÐÑивеÑ"
</script>
ÐвÑÐ¾Ñ ÑÑÑаниÑÑ Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ, ÑÑо библиоÑека "hello.js" пÑоÑÑо оÑÑабоÑаеÑ, без побоÑнÑÑ
ÑÑÑекÑов. Рона вмеÑÑе Ñ ÑÑим пеÑеопÑеделила message в "ÐÑивеÑ".
ÐÑли же ÑбÑаÑÑ ÑкÑÐ¸Ð¿Ñ hello.js, Ñо ÑÑÑаниÑа бÑÐ´ÐµÑ Ð²ÑводиÑÑ Ð¿ÑавилÑное ÑообÑение.
ÐÐ½Ð°Ñ Ð²Ð½ÑÑÑеннее ÑÑÑÑойÑÑво hello.js нам, конеÑно, понÑÑно, ÑÑо пÑоблема возникла поÑомÑ, ÑÑо пеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ message из ÑкÑипÑа hello.js пеÑезапиÑала обÑÑвленнÑÑ Ð½Ð° ÑÑÑаниÑе.
ÐÑиÑм пÑоекÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Â«ÐодÑлÑ»
ЧÑÐ¾Ð±Ñ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð½Ðµ бÑло, вÑего-Ñо нÑжно, ÑÑÐ¾Ð±Ñ Ñ ÑкÑипÑа бÑла ÑÐ²Ð¾Ñ ÑобÑÑÐ²ÐµÐ½Ð½Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑÑ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑи, ÑÑÐ¾Ð±Ñ ÐµÐ³Ð¾ пеÑеменнÑе не попали на ÑÑÑаниÑÑ.
ÐÐ»Ñ ÑÑого Ð¼Ñ Ð·Ð°Ð²ÐµÑнÑм вÑÑ ÐµÐ³Ð¾ ÑодеÑжимое в ÑÑнкÑиÑ, коÑоÑÑÑ ÑÑÑ Ð¶Ðµ запÑÑÑим.
Файл hello.js, оÑоÑмленнÑй как модÑлÑ:
(function() {
// глобалÑÐ½Ð°Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ Ð½Ð°Ñего ÑкÑипÑа
var message = "ÐÑивеÑ";
// ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ Ð²Ñвода ÑÑой пеÑеменной
function showMessage() {
alert( message );
}
// вÑводим ÑообÑение
showMessage();
}());
ÐÑÐ¾Ñ ÑкÑÐ¸Ð¿Ñ Ð¿Ñи подклÑÑении к Ñой же ÑÑÑаниÑе бÑÐ´ÐµÑ ÑабоÑаÑÑ ÐºÐ¾ÑÑекÑно.
ÐÑÐ´ÐµÑ Ð²ÑводиÑÑÑÑ Â«ÐÑивеÑ», а заÑем «ÐожалÑйÑÑа, нажмиÑе на кнопкÑ».
ÐаÑем Ñкобки вокÑÑг ÑÑнкÑии?
РпÑимеÑе вÑÑе обÑÑвление модÑÐ»Ñ Ð²ÑглÑÐ´Ð¸Ñ Ñак:
(function() {
alert( "обÑÑвлÑем локалÑнÑе пеÑеменнÑе, ÑÑнкÑии, ÑабоÑаем" );
// ...
}());
РнаÑале и в конÑе ÑÑоÑÑ Ñкобки, Ñак как инаÑе бÑла Ð±Ñ Ð¾Ñибка.
ÐоÑ, Ð´Ð»Ñ ÑÑавнениÑ, невеÑнÑй ваÑианÑ:
function() {
// бÑÐ´ÐµÑ Ð¾Ñибка
}();
ÐÑибка пÑи его запÑÑке пÑоизойдÑÑ Ð¿Ð¾ÑомÑ, ÑÑо бÑаÑзеÑ, Ð²Ð¸Ð´Ñ ÐºÐ»ÑÑевое Ñлово function в оÑновном поÑоке кода, попÑÑаеÑÑÑ Ð¿ÑоÑиÑаÑÑ Function Declaration, а здеÑÑ Ð¸Ð¼ÐµÐ½Ð¸ неÑ.
ÐпÑоÑем, даже еÑли Ð¸Ð¼Ñ Ð¿Ð¾ÑÑавиÑÑ, Ñо ÑабоÑаÑÑ Ñоже не бÑдеÑ:
function work() {
// ...
}(); // syntax error
Ðело в Ñом, ÑÑо «на меÑÑе» ÑазÑеÑено вÑзÑваÑÑ ÑолÑко Function Expression.
ÐбÑее пÑавило Ñаково:
- ÐÑли бÑаÑÐ·ÐµÑ Ð²Ð¸Ð´Ð¸Ñ
functionв оÑновном поÑоке кода â он ÑÑиÑаеÑ, ÑÑо ÑÑоFunction Declaration. - ÐÑли же
functionидÑÑ Ð² ÑоÑÑаве более Ñложного вÑÑажениÑ, Ñо он ÑÑиÑаеÑ, ÑÑо ÑÑоFunction Expression.
ÐÐ»Ñ ÑÑого и нÑÐ¶Ð½Ñ Ñкобки â показаÑÑ, ÑÑо Ñ Ð½Ð°Ñ Function Expression, коÑоÑÑй по пÑавилам JavaScript можно вÑзваÑÑ Â«Ð½Ð° меÑÑе».
Ðожно показаÑÑ ÑÑо дÑÑгим ÑпоÑобом, напÑÐ¸Ð¼ÐµÑ Ð¿Ð¾ÑÑавив пеÑед ÑÑнкÑией опеÑаÑоÑ:
+function() {
alert('ÐÑзов на меÑÑе');
}();
!function() {
alert('Так Ñоже бÑÐ´ÐµÑ ÑабоÑаÑÑ');
}();
ÐкÑпоÑÑ Ð·Ð½Ð°ÑениÑ
ÐÑиÑм «модÑлÑ» иÑполÑзÑеÑÑÑ Ð¿Ð¾ÑÑи во вÑÐµÑ ÑовÑеменнÑÑ Ð±Ð¸Ð±Ð»Ð¸Ð¾ÑÐµÐºÐ°Ñ .
ÐÐµÐ´Ñ ÑÑо Ñакое библиоÑека? ÐÑо полезнÑе ÑÑнкÑии, Ñади коÑоÑÑÑ ÐµÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑаÑÑ, плÑÑ Ð²ÑеменнÑе пеÑеменнÑе и вÑпомогаÑелÑнÑе ÑÑнкÑии, коÑоÑÑе библиоÑека иÑполÑзÑÐµÑ Ð²Ð½ÑÑÑи ÑебÑ.
ÐоÑмоÑÑим, к пÑимеÑÑ, на библиоÑÐµÐºÑ Lodash, Ñ Ð¾ÑÑ Ð¼Ð¾Ð³Ð»Ð¸ Ð±Ñ Ð¸ jQuery, Ñам поÑÑи Ñо же Ñамое.
ÐÑли ÐµÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑиÑÑ, Ñо поÑвиÑÑÑ ÑпеÑиалÑÐ½Ð°Ñ Ð¿ÐµÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ lodash (коÑоÑкое Ð¸Ð¼Ñ _), коÑоÑÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ ÐºÐ°Ðº ÑÑнкÑиÑ, и кÑоме Ñого в Ð½ÐµÑ Ð·Ð°Ð¿Ð¸ÑÐ°Ð½Ñ ÑазлиÑнÑе полезнÑе ÑвойÑÑва, напÑимеÑ:
_.defaults(src, dst1, dst2...)â копиÑÑÐµÑ Ð² обÑекÑsrcÑе ÑвойÑÑва из обÑекÑовdst1,dst2и дÑÑÐ³Ð¸Ñ , коÑоÑÑÑ Ñам неÑ._.cloneDeep(obj)â Ð´ÐµÐ»Ð°ÐµÑ Ð³Ð»Ñбокое копиÑование обÑекÑаobj, ÑÐ¾Ð·Ð´Ð°Ð²Ð°Ñ Ð¿Ð¾Ð»Ð½Ð¾ÑÑÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸ÑимÑй клон._.size(obj)â возвÑаÑÐ°ÐµÑ ÐºÐ¾Ð»Ð¸ÑеÑÑво ÑвойÑÑв в обÑекÑе, полимоÑÑÐ½Ð°Ñ ÑÑнкÑиÑ: можно пеÑедаÑÑ Ð¼Ð°ÑÑив или даже 1 знаÑение.
ÐÑÑÑ Ð¸ много дÑÑÐ³Ð¸Ñ ÑÑнкÑий, подÑобнее опиÑаннÑÑ Ð² докÑменÑаÑии.
ÐÑÐ¸Ð¼ÐµÑ Ð¸ÑполÑзованиÑ:
<p>ÐодклÑÑим библиоÑекÑ</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js"></script>
<p>ФÑнкÑÐ¸Ñ <code>_.defaults()</code> добавлÑÐµÑ Ð¾ÑÑÑÑÑÑвÑÑÑие ÑвойÑÑва.</p>
<script>
var user = {
name: 'ÐаÑÑ'
};
_.defaults(user, {
name: 'Ðе Ñказано',
employer: 'Ðе Ñказан'
});
alert( user.name ); // ÐаÑÑ
alert( user.employer ); // Ðе Ñказан
alert( _.size(user) ); // 2
</script>
ÐдеÑÑ Ð½Ð°Ð¼ не важно, какие ÑÑнкÑии или меÑÐ¾Ð´Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñеки иÑполÑзÑÑÑÑÑ, Ð½Ð°Ñ Ð¸Ð½ÑеÑеÑÑÐµÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ как опиÑана ÑÑа библиоÑека, как в ней пÑименÑеÑÑÑ Ð¿ÑиÑм «модÑлÑ».
ÐÐ¾Ñ Ð¿ÑимеÑÐ½Ð°Ñ Ð²ÑдеÑжка из иÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ñайла:
;(function() {
// lodash - оÑÐ½Ð¾Ð²Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð´Ð»Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñеки
function lodash(value) {
// ...
}
// вÑпомогаÑелÑÐ½Ð°Ñ Ð¿ÐµÑеменнаÑ
var version = '2.4.1';
// ... дÑÑгие вÑпомогаÑелÑнÑе пеÑеменнÑе и ÑÑнкÑии
// код ÑÑнкÑии size, пока ÑÑо доÑÑÑпен ÑолÑко внÑÑÑи
function size(collection) {
return Object.keys(collection).length;
}
// пÑиÑвоим в lodash size и дÑÑгие ÑÑнкÑии, коÑоÑÑе нÑжно вÑнеÑÑи из модÑлÑ
lodash.size = size
// lodash.defaults = ...
// lodash.cloneDeep = ...
// "ÑкÑпоÑÑиÑоваÑÑ" lodash наÑÑÐ¶Ñ Ð¸Ð· модÑлÑ
window._ = lodash; // в оÑигиналÑном коде здеÑÑ Ñложнее, но ÑмÑÑл ÑÐ¾Ñ Ð¶Ðµ
}());
ÐнÑÑÑи внеÑней ÑÑнкÑии:
- ÐÑоиÑÑ Ð¾Ð´Ð¸Ñ ÑÑо Ñгодно, обÑÑвлÑÑÑÑÑ Ñвои локалÑнÑе пеÑеменнÑе, ÑÑнкÑии.
- Ð
windowвÑноÑиÑÑÑ Ñо, ÑÑо нÑжно ÑнаÑÑжи.
ТеÑ
ниÑеÑки, Ð¼Ñ Ð¼Ð¾Ð³Ð»Ð¸ Ð±Ñ Ð²ÑнеÑÑи в window не ÑолÑко lodash, но и вообÑе вÑе обÑекÑÑ Ð¸ ÑÑнкÑии. Ðа пÑакÑике, как Ñаз наобоÑоÑ, вÑÑ Ð¿ÑÑÑÑÑ Ð²Ð½ÑÑÑи модÑлÑ, глобалÑнÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ð²Ð¾ избежание конÑликÑов Ñ
ÑанÑÑ Ð¼Ð°ÐºÑималÑно ÑиÑÑой.
РнаÑале кода вÑÑе наÑ
одиÑÑÑ ÑоÑка Ñ Ð·Ð°Ð¿ÑÑой ; â ÑÑо не опеÑаÑка, а оÑÐ¾Ð±Ð°Ñ Â«Ð·Ð°ÑиÑа Ð¾Ñ Ð´ÑÑаков».
ÐÑли полÑÑиÑÑÑ, ÑÑо неÑколÑко JS-Ñайлов обÑÐµÐ´Ð¸Ð½ÐµÐ½Ñ Ð² один (и, ÑкоÑее вÑего, ÑжаÑÑ Ð¼Ð¸Ð½Ð¸ÑикаÑоÑом, но ÑÑо не важно), и пÑогÑаммиÑÑ Ð·Ð°Ð±Ñл поÑÑавиÑÑ ÑоÑÐºÑ Ñ Ð·Ð°Ð¿ÑÑой, Ñо бÑÐ´ÐµÑ Ð¾Ñибка.
ÐапÑимеÑ, пеÑвÑй Ñайл a.js:
var a = 5
ÐÑоÑой Ñайл lib.js:
(function() {
// без ÑоÑки Ñ Ð·Ð°Ð¿ÑÑой в наÑале
})()
ÐоÑле обÑÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð² один Ñайл:
var a = 5
// библиоÑека
(function() {
// ...
})();
ÐÑи запÑÑке бÑÐ´ÐµÑ Ð¾Ñибка, поÑÐ¾Ð¼Ñ ÑÑо инÑеÑпÑеÑаÑÐ¾Ñ Ð¿ÐµÑед Ñкобкой Ñам не вÑÑÐ°Ð²Ð¸Ñ ÑоÑÐºÑ Ñ Ð·Ð°Ð¿ÑÑой. Ðн пÑоÑÑо поймÑÑ ÐºÐ¾Ð´ как var a = 5(function ...), Ñо еÑÑÑ Ð¿ÑÑаеÑÑÑ Ð²ÑзваÑÑ ÑиÑло 5 как ÑÑнкÑиÑ.
Ð¢Ð°ÐºÐ¾Ð²Ñ Ð¿Ñавила ÑзÑка, и поÑÑÐ¾Ð¼Ñ ÑекомендÑеÑÑÑ Ñвно ÑÑавиÑÑ ÑоÑÐºÑ Ñ Ð·Ð°Ð¿ÑÑой. Рданном ÑлÑÑае авÑÐ¾Ñ lodash ÑÑÐ°Ð²Ð¸Ñ ; пеÑед ÑÑнкÑией, ÑÑÐ¾Ð±Ñ Ð¿ÑедÑпÑедиÑÑ ÑÑÑ Ð¾ÑибкÑ.
ÐкÑпоÑÑ ÑеÑез return
Ðожно оÑоÑмиÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ Ð¸ ÑÑÑÑ Ð¿Ð¾-дÑÑгомÑ, напÑÐ¸Ð¼ÐµÑ Ð¿ÐµÑедаÑÑ Ð·Ð½Ð°Ñение ÑеÑез return:
var lodash = (function() {
var version;
function assignDefaults() { ... }
return {
defaults: function() { }
}
})();
ÐдеÑÑ, кÑÑаÑи, Ñкобки вокÑÑг внеÑней function() { ... } не обÑзаÑелÑнÑ, Ð²ÐµÐ´Ñ ÑÑнкÑÐ¸Ñ Ð¸ Ñак обÑÑвлена внÑÑÑи вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¿ÑиÑваиваниÑ, а знаÑÐ¸Ñ â ÑвлÑеÑÑÑ Function Expression.
Тем не менее, лÑÑÑе Ð¸Ñ ÑÑавиÑÑ, Ð´Ð»Ñ ÑлÑÑÑÐµÐ½Ð¸Ñ ÑиÑаемоÑÑи кода, ÑÑÐ¾Ð±Ñ Ð±Ñло ÑÑÐ°Ð·Ñ Ð²Ð¸Ð´Ð½Ð¾, ÑÑо ÑÑо не пÑоÑÑое пÑиÑвоение ÑÑнкÑии.
ÐÑого
ÐодÑÐ»Ñ Ð¿Ñи помоÑи замÑканий â ÑÑо обоÑаÑивание пакеÑа ÑÑнкÑионалÑноÑÑи в единÑÑ Ð²Ð½ÐµÑнÑÑ ÑÑнкÑиÑ, коÑоÑÐ°Ñ ÑÑÑ Ð¶Ðµ вÑполнÑеÑÑÑ.
ÐÑе ÑÑнкÑии модÑÐ»Ñ Ð±ÑдÑÑ Ð¸Ð¼ÐµÑÑ Ð´Ð¾ÑÑÑп к дÑÑгим пеÑеменнÑм и внÑÑÑенним ÑÑнкÑиÑм ÑÑого же модÑÐ»Ñ ÑеÑез замÑкание.
ÐапÑимеÑ, defaults из пÑимеÑа вÑÑе Ð¸Ð¼ÐµÐµÑ Ð´Ð¾ÑÑÑп к assignDefaults.
Ðо ÑнаÑÑжи пÑогÑаммиÑÑ, иÑполÑзÑÑÑий модÑлÑ, Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ Ð½Ð°Ð¿ÑÑмÑÑ ÑолÑко к Ñем пеÑеменнÑм и ÑÑнкÑиÑм, коÑоÑÑе ÑкÑпоÑÑиÑованÑ. ÐлагодаÑÑ ÑÑÐ¾Ð¼Ñ Ð±ÑдÑÑ ÑкÑÑÑÑ Ð²Ð½ÑÑÑенние аÑпекÑÑ ÑеализаÑии, коÑоÑÑе нÑÐ¶Ð½Ñ ÑолÑко ÑазÑабоÑÑÐ¸ÐºÑ Ð¼Ð¾Ð´ÑлÑ.
Ðожно пÑидÑмаÑÑ Ð¸ много дÑÑÐ³Ð¸Ñ Ð²Ð°ÑиаÑий Ñакого Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð°. РконÑе конÑов, «модÑлÑ» â ÑÑо вÑего лиÑÑ ÑÑнкÑиÑ-обÑÑÑка Ð´Ð»Ñ ÑкÑÑÑÐ¸Ñ Ð¿ÐµÑеменнÑÑ .
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)