Leaderboard


Popular Content

Showing content with the highest reputation since 03/14/2011 in all areas

  1. 11 points
  2. 9 points
    Сразу оговорюсь, что всё, что будет здесь описано, будет описано максимально упрощённо и многие вещи лично у меня настроены иначе (разбивка диска, nginx на фронте...), но главное донести суть, а там уже тонкости. Для начала нам понадобится домашний интернет с выделенным «белым» IP. Да, есть аозможность сделать и без этого, но я считаю этот вариант плохим и недостойным рассмотрения. Теперь нам нужен сервер. Понятно, что всё зависит от предполагаемой нагрузки, но я не вижу смысла держать дома нагруженные (а, значит, важные) проекты — для этого лучше подойдёт хороший ЦОД. Я выбрал себе девайс под названием DNS Porto — это такой типа неттоп российской сборки http://ekaterinburg.dns-shop.ru/catalog/176/128891/ Скоро, вероятно, такие продавать перестанут, так как пошла новая линейка, но советую тоже брать что-то типа того. Тот который у меня отличается от того, который по ссылке, тем, что у моего 1 гиг памяти, а не два, процессор вроде бы на 1,66 ГГц, а не 1,8 и диск на 160 гигов, а не 250 — моей модели, видимо, уже нет в продаже. Выбрал я этот девайс потому что он маленький, тихий и электричества потребляет мало. Далее надо сделать так, чтобы кроме сервера, вашим домашним интернетом могли пользоваться и другие компьютеры в вашем доме. Самый простой путь — купить маршрутизатор. Хватит самого простого D-Link DIR-300, например. Если вай-фай не нужен, то можно такой же только без вай-фая — не помню как модель называется, но найдёте. Как настраивать маршрутизатор я рассказывать не буду — у д-линков там всё проще простого и вообще есть мануалы. Единственное, что нам надо будет — перебросить на наш сервер порты 21 (FTP), 22 (SSH) и 80 (HTTP). Можно добавить 3306 (MySQL), 443 (HTTPS) и вообще какие угодно, но это уже исходя из потребностей, мне не нужно, например. Теперь система. Мне по нраву Ubuntu Linux, так как устанавливается легко, ПО достаточно свежее и работать с ней приятно. Итак, идём на страницу загрузки http://www.ubuntu.com/download/server/download и грузим себе образ. Предпочесть стоит, думаю, последний LTS — сегодня это 10.04. У меня в сервере нет CD-привода и потому я делал себе загрузочную USB-флэшку — в десктопной убунте для этого есть специальная приблуда, как это делать в других системах я не знаю, но, думаю, на сайте это описано. В конце концов, можно постпрашивать на форумах, если что-то не будет получаться. Итак, подключаем к компьютеру монитор, клавиатуру и загружаемся с диска/флэшки. Для начала мы увидим экран выбора языка. Я считаю, что нужно всё ставить на английском, чтобы не было непоняток в случае косяков локализации. Выбираем «Install Ubuntu Server». То есть начнём устанавливать. Выберем язык для системы. Опять же я советую английский. Выберем наше местоположение. Other -> Europe -> Russian Federation. Понятно, что надо выбирать своё местоположение. Я в России, потому и выбрал её. Определить раскладку клавиатуры? Я думаю, что не стоит. Вручную укажем. Russia -> Russia -> Alt+Shift. Можно и другой комбинацией, но, по сути, это нам даже и не нужно. Далее пойдут какие-то загрузки, операции, будут какие-то прогрессбары — система будет готовиться к установке. Тут система спросит как её назвать. Я назвал, как видно на картинке, testserver. Можете сами выдумать что захотите — это непринципиально. Почему-то система решила, что я в Красноярске. А я не там. Выбираю «No» и далее «Yekaterinburg», поскольку я в Екатеринбурге. Если система правильно всё определила, то жмите «Yes», если нет, то выберите ваш часовой пояс. Формируем файловую систему. По-хорошему, надо в отдельные разделы выносить /home, /tmp, можно отказаться от свопа, но у нас не «настройка и кстановка линукса», а «как хоститься дома», так что доверимся всемогущему усановщику и выберем «Guided — use entire disk». Выберем на какой хард ставить систему. Как видно из картинки, у меня диск всего один и это виртуальный диск виртуальной машины. Вы выберите свой, если будет из чего выбирать. Если диск один, то, понятное дело, жмём Enter без лишних раздумий Предупреждение, что ВСЕ ДАННЫЕ БУДУТ УДАЛЕНЫ. Оно верное — действительно всё, что было на диске будет удалено. Соглашаемся. Начинается форматирование диска и установка системы. Это самый долгий процесс. Создаём пользователя. Он получит доступ к sudo и именно «под ним» мы будем всё делать. Введём и повторим пароль. Зашифровать домашнюю директорию? Я выбрал «нет». Далее снова идут некоторые настройки. Вы подключены через прокси? Нет. Оставляем поле пустым. Нужны автоматические обновления? Нет, не нужны. Какое ПО будем ставить? Выбираем только OpenSSH для удалённого управления сервером. Остальное поставим вручную. Поставить загрузчик GRUB? Да, поставить. Всё готово. Компьютер будет перезагружен. Надо будет после перезагрузки достать диск или флэшку, с которой всё ставилось Итак, система установлена. Можно отцепить от сервера монитор и клаву и поставить его подальше, чтобы не мешал. Подключаемся к серверу через SSH. Через консоль, если она у вас есть в системе, или через Putty, если у вас винда. Теперь обновим систему. Для начала получим список доступных для загрузки пакетов. sudo apt-get update обновим ПО sudo apt-get upgrade обновим систему sudo apt-get dist-upgrade Перезагрузим сервер. Теперь можно поставить полезные какие-нибудь утилиты. Мне полезен файломенеджер midnight commander, чтобы рулить файлами и системный монитор htop, который показывает как у нас в данный момент с нагрузкой дела обстоят. sudo apt-get install mc htop Теперь создадим папку, в которой будут храниться наши сайты. sudo mkdir /webs Создадим специального пользователя из-под которого всё будет испольняться при работе с сайтами sudo groupadd webs sudo useradd -g webs -s /bin/bash -d /webs webs поставим пользователю пароль passwd webs И поставим владельцем папки созданного нами пользователя sudo chown webs /webs sudo chgrp webs /webs Установим apache sudo apt-get install apache2 apache2-doc apache2-mpm-prefork apache2-utils libexpat1 ssl-cert Установим PHP sudo apt-get install php5-common php5 libapache2-mod-php5 php5-cli php5-cgi php5-mysql php5-curl php5-dev php5-gd php5-idn php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-mhash php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl libapache2-mod-fcgid libapache2-mod-fastcgi Установим MySQL sudo apt-get install mysql-client mysql-server libmysqlclient15-dev в процессе установки у нас будет спрошен пароль для рутового пользователя mysql, который надо будет придумать и ввести. Установим Phpmyadmin sudo apt-get install phpmyadmin Выберем в качестве веб-сервера установленный у нас apache. Далее нажмём «Да» на вопрос системы «сконфигурировать ли phpmyadmin», введём недавно придуманный нами рутовый пароль mysql, а так же придумаем и введём два раза пароль юзера phpmyadmin. Включим модуль rewrite в апаче sudo a2enmod rewrite Перезапустим апач sudo /etc/init.d/apache2 restart Теперь, если зайти на ваш сервер через http по IP-адресу, то увидим сообщение «It works!», которая нам скажет, что всё установилось удачно. http://ваш_ip/phpmyadmin — тут мы увидим phpmyadmin. Теперь привяжем к нашему серверу доменное имя. Зарегистрируем имя для начала. Допустим зарегистрировали example.com Я делаю это на сайте 2domains.ru — там дёшево и нормально. Ещё там можно использовать DNS-серверы reg.ru — они-то нам и нужны. Итак, зарегистрировали имя, нажали галочку «использовать DNS-серверы регистратора», потом в редакторе зон DNS добавляем A-запись: «пустое поле» IN A ваш_ip Через какое-то время ваш сервер будет доступен по доменному имени. Теперь создадим сайт на этом домене. для начала в файле /etc/apache2/envvars заменим строки export APACHE_RUN_USER=www-data export APACHE_RUN_GROUP=www-data следующими export APACHE_RUN_USER=webs export APACHE_RUN_GROUP=webs и сделаем sudo chown -R webs /var/lib/apache2 перезапустим апач. Создадим папки, в которых будут жить файлы, связанные с этим сайтом mkdir /webs/example.com mkdir /webs/example.com/www mkdir /webs/example.com/logs echo "Hello world!" > /webs/example.com/www/index.html Создадим файл /etc/apache2/sites-available/example.com следующего содержания <VirtualHost *> ServerName example.com ServerAdmin admin@example.com DocumentRoot /webs/example.com/www <Directory /> Options FollowSymLinks AllowOverride All </Directory> <Directory /webs/example.com/www/> Options FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> ErrorLog /webs/example.com/logs/error.log. LogLevel warn CustomLog /webs/example.com/logs/access.log combined </VirtualHost> Добавим его sudo a2ensite example.com перезагрузим конфиг апача sudo /etc/init.d/apache2 reload Готово! Теперь (если DNS уже успели распостраниться) по адресу example.com будет доступен ваш сайт, который приветствует мир. Можно как на обычном хостинге создавать php-скрипты, которые будут нормально работать. Чтобы работала функция mail() в PHP, нам нужен почтовый сервер. sudo apt-get install postfix Добавим к этому FTP. sudo apt-get install proftpd Теперь отредактируем файл конфига /etc/proftpd/proftpd.conf — отредактируем там некоторые строки ListOptions "-la" DefaultRoot ~ перезапустим FTP-сервер /etc/init.d/proftpd restart Всё, теперь можно логиниться под юзером webs на ваш сервер через FTP. Вот и всё. Ещё раз повторюсь, что это только некоторые основы — сервер будет работать, но надо будет ещё озаботиться его безопасностью. Ещё можно будет оптимизировать серверное ПО, чтобы ресурсы нормально распределялись... Если ещё выберу время, то напишу что для этого надо и как это делается. Если кто-то заметил какие-то ошибки или есть какие-то вопросы — задавайте.
  3. 8 points
    Вертикальное выравнивание. Часть 1. - для тех кто не в курсе. Только что пришла в голову еще одна идея, которая, на мой взгляд проще в реализации и опять же кроссбраузерна. <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> html, body { margin: 0; padding: 0; height: 100%; } .text { display: table; height: 100%; width: 100%; background: pink; } .inner { display: table-cell; text-align: center; vertical-align: middle; } </style> <!--[if lte IE 7]> <style type="text/css"> .text { writing-mode: tb-rl; text-align: center; } .inner { display: inline-block; width: 100%; writing-mode: lr-tb; } </style> <![endif]--> </head> <body> <div class="text"> <span class="inner">Я по центру</span> </div> </body> </html> Проверял в: ИЕ 9 ИЕ 9 (режим ИЕ 8) ИЕ 9 (режим ИЕ 7) Opera 11.11 Firefox 5 Chrome (последний) Safari 5.0.5
  4. 8 points
    По-моему, форумчан снова хотят провести…
  5. 8 points
    brendmaster, нельзя брать деньги с заказчика и предлагать услуги того, чего в принципе не умеешь делать, а потом выискивать тех, кто сделает за тебя эту работу, еще и, по возможности, бесплатно. Должно же у компании быть какое-то лицо Я готова один-два раза сделать за гроши или "за спасибо", но только либо для повышения профессиональных навыков при наличии интересного некоммерческого проекта, либо при наличии свободного времени и желании кому-то помочь (но это мое личное право). И не путайте раба с фрилансером. Если Вы берете деньги за проект (как указано в прайсе, например, индивидуальная верстка страницы сайта 4000р/1 стр.), то извольте достойно оплатить и труд исполнителя, тогда люди к Вам сами за добавкой потянутся. Профессионал не хочет и не будет работать за копейки. С каждым выполненным проектом материальная ценность исполнителя повышается, а у Вас выходит, один и тот же фрилансер за одни и те же копейки каждый раз должен выполнять проекты, и с каждым разом все сложнее и разнообразнее. Ничего удивительного в том, что люди стали от Вас бежать после нескольких, как Вы выразились, "успешно сданных" проектов. Вы с помощью данного ресурса реализовали себе бесплатную верстку сайта компании, занимающейся созданием сайтов, получили бесплатную верстку еще нескольких проектов, и потом утверждаете, что нет доверия фрилансерам. Начните с себя, потому что к Вам, лично у меня, доверия еще меньше, как и к студии BRENDmaster, расположенной в Дзержинске. И скажите спасибо администрации данного форума, которая позволяла Вам раз за разом давать объявления и получать услуги без копейки денег с Вашей стороны. Карма показывает общий настрой среднестатистического потенциального исполнителя по отношению к Вам, а не "злые закомплексованные дяди и тети минуса наставили". Вы себя показали не с лучшей стороны, и я даже не представляю, как можно исправить ситуацию. Но если ничего не делать, то рано или поздно та же ситуация повторится с Вами и на других ресурсах, и будете раз за разом создавать новую студию, новый ник, пока не надоест придумывать логотипы и названия.
  6. 7 points
    За дураков-то не держите: http://clip2net.com/s/1RmaB , http://clip2net.com/s/1Rma9 http://ipgeobase.ru/?address=109.184.194.7 Некрасиво так делать.
  7. 7 points
    Я отвечу на понятном языке.
  8. 7 points
    http://pmsrv.ru/ Вот я сделал новую пробную версию сайта для компании, в которой я работаю. Что вы об этом думаете? Чего ещё не хватает?
  9. 6 points
    Делаю аудит вашей работы: указываю на ошибки, даю практический рекомендации и делюсь решениями проверенные опытом. Обращаю Ваше внимание на неочевидные потенциальные проблемы, делюсь своим многолетним опытом, раскладываю по полочкам как работает вёрстка и как её грамотно писать. Как добавить вёрстку для оценки? Для того что бы иметь возможность оценить проделанную Вами работы, мне понадобится: Исходный код, выложенный на github, butbucket или любой другой вариант (если выкладываете в архиве то используйте zip) Предоставьте доступ к итоговому результату. Для этого идеально подойдёт pages.github.com или любой общедоступный сайт. Отпишитесь в комментарии к данной статьи и предоставьте вышеуказанные данные Что будет в итоге? Вы получите анализ по следующим критериям: вёрстка: какие ошибки допущены, каким блокам не достаточно универсальности, какие проблемы могут возникнуть в будущем, как оптимизировать структуру и поднять гибкость разметки стили: буду обращать внимание на пользование пре-процессорами, предлагать решения которые помогут поддерживать код годами структура проекта: дам рекомендации по организации файловой системы и кода в целом, буду обращать внимание на пользование современными инструментами разработчика В итоге Вы получите анализ по своей работы с точки зрения построения долгосрочных проектов, которые поддерживаются годами, поделюсь своим видением какие изменения требуется изменить что бы код не превратился в боль разработчика. ℹ️ Советую заглянуть в блог Руководство верстальщика и прочитать тему Типичные ошибки начинающего верстальщика перед публикацией работы. Решения для большинства ошибок уже изложены. Когда и где будет обзор? Обзоры выкладываться на YouTube-канале HTMLforum_io, каждый вторник. Хронометраж — ~15 минут. Стоимость участия Плановый аудит работ проводится бесплатно. Раз в неделю я выбираю интересную работу и делаю по ней обзор. Индивидуальный аудит Вы можете заказать индивидуальный аудит работы. В таком случае Вы получите полный обзор работы без ограничения по хронометражу. Я пошагово расскажу допущенные ошибки, причины их возникновения и объясню как их решить. Дам рекомендации по усовершенствованию кода и повышению его качества. Аудит будет доступен на YouTube-канале HTMLforum_io. Стоимость зависит от объёма работ. Рейт: $30/час. В стоимость входит: изучение работы и её аудит видео-запись и монтаж индивидуальная онлайн консультация со мной в формате "Вопрос. Ответ." продолжительностью 1 час. Минимальная стоимость: $60. Срок выполнения: 7 дней. Возврат средств. Если Вам не понравиться моя работа — я верну 50% стоимости аудита (в моей практике недовольных не было). Частная консультация У Вас есть возможность задать вопросы по работе и получить рекомендации, наставления, пути развития для квалифицированного роста и достижения успеха. Онлайн консультация в формате тет-а-тет. Вместе с Вами анализируем код, обсуждаем качество его исполнения, выявляем ошибки, обсуждаем пути их возникновения/решения/предупреждения. Обсудим повышения сложности работ, решение сверх-задач, создание кода для огромных проектов. Порядок действий: я предварительно изучаю Ваш код и говорю ориентировочную длительность консультации, стоимость которой оплачивается предварительно. В случае если консультация заняла меньше времени — возврат части средств. Если больше — обсуждаем индивидуально. Стоимость зависит от длительности консультации. Рейт: $50/час. Минимальная длительность: 1 час. Партнёрство Предложение отрыто для всех. Если Вы считаете себя достаточно опытным что бы уметь анализировать работу других разработчиков и давать рекомендации, — напишите мне в личку. Знаний, успехов и позитива Вам. С уважением, @klierik
  10. 6 points
    Мне давно было интересно как устроен всеми любимый jQuery и вот я решил засесть за него (благо что исходники у него открытые). И вот, по просьбе камрада mishka2 я рассказываю, что я выяснил, как работает этот фреймворк и как написать свой такой же. Прежде всего пара фишек яваскрипта, про которые не все начинающие знают: 1) Имена функций: В яваскрипте валидными считаются любые имена функций, которые начинаются с буквы, со знака доллара ($) и со знака подчеркивания (_). Так что когда вы используете ваш любимый jQuery, вызывая к примеру $(document), знайте, что вы вызываете функцию у которой имя $ и передаете ей в качестве аргумента document. 2) Вызов функций: Обычно все пишут какую-нибудь функцию, к примеру: function myFunc() { alert(1); } // или так var myFunc = function() { alert(1); } а потом вызывают ее, но многие не знают, что в яваскрипте можно вызвать функцию сразу при создании вот таким методом: (function() { // создаем функцию alert(1); })(); // и тут же вызываем ее 3) Переменные и функции: Яваскрипт - это объектно ориентированный язык программирования. В нем все является либо объектами, либо свойствами объектов. Даже если вы используете процедурный подход к программированию (создаете отдельные функции и оперируете ими), вы все равно создаете объекты, т.к. в яваскипте любая функция - это объект. Т.е. вы можете вызвать ее через оператор new и рабоать с ней как с объектом. Когда вы создаете переменную в глобальной области видимости, то она записывается как свойство глобального объекта window. Т.е.var a = 1; и window.a = 1 эквивалентны. Ну вот теперь многие вещи в jQuery станут понятны. Самое интересное в jQuery то, что как только вы поздключили его на страницу он у вас сразу инициализирован. Давайте посмотрим как это сделано. 1) Для начала давайте создадим наш объект, назовем его Helper, у него будет пока единственный метод init(), который должен будет инициализировать его. А делать наш объект будет всего одну вещь - находить по ID элемент на странице или получать уже найденный элемент как ноду и возвращать его: var Helper = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; } } Фишка в том, что нам надо будет обязательно инициализировать наш объект, для того чтобы он заработал, т.е. нам нужно будет где-либо на странице вызвать метод init(): alert(Helper.init('id_элемента')); Но нам то нужно получить что-то вроде такого: alert(Helper('id_элемента')); Тут то нам и приходит на помощь вызов функции сразу при создании, единственное, что нам потребуется это анонимная функция (т.е. функция без имени), которая будет вызываться сразу же после создания и вспомогательная функция, которая будет инициализировать наш объект и возвращать его: (function() { // анонимная функция var Helper = function(elem) { // вспомогательная функция return new Helper.foo.init(elem); // которая возвращает нам уже проинициализированный объект } Helper.foo = { // наш основной объект init: function(elem) { // метод, где происходит инициализация elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; // метод возвращает нам ссылку на ноду } } })(); // сразу же вызываем анонимную функцию У внимательного читателя должен возникнуть вопрос: "Откуда взялся Helper.foo? И почему именно так?". Все дело в наследовании прототипов. Вообще, прототипы в яваскрипте это довольно сложная для понимания штука. В конце я дам ссылки на ресурсы где про это можно почитать. Признаюсь, сам перечитывал раз 10, но все равно не понял до конца как они работают. Скажу лишь, что когда мы пишем new Helper.foo.init(elem);, то не создаем новый объект с именем Helper.foo как вы могли подумать, а создаем новый объект с именем Helper.foo.init (т.к. init() - тоже функция), у которого нет ни одного метода. И чтобы использовать все методы которые мы будем добавлять в Helper.foo в дальнейшем на понадобится переопределить прототип Helper.foo.init. Пока все это звучит очень запутанно, но я надеюсь, что когда вы увидите дальнейший код, то все поймете. Итак, теперь у нас есть проинициализированный объект и казалось бы мы можем его начать вызывать, но (как вы должны знать) переменная Helper у нас получилась не глобальной, т.к. она находится внутри анонимной функции. Чтобы начать использовать наш Helper нам надо передать его в глобальную область видимости, вот так это сделано в jQuery: (function() { // анонимная функция var Helper = function(elem) { // вспомогательная функция return new Helper.foo.init(elem); // которая возвращает нам уже проинициализированный объект } Helper.foo = { // наш основной объект init: function(elem) { // метод, где происходит инициализация elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; // метод возвращает нам ссылку на ноду } } // передаем переменную Helper в глобальную область видимости window.Helper = Helper; })(); // сразу же вызываем анонимную функцию Все, теперь вы можете использовать проинициализированный объект: <body> <div id="test"></div> <script type="text/javascript"> alert(Helper('test')); </script> </body> Но позвольте, откуда же в jQuery берется доллар? Все очень просто - пусть у нас будет два доллара: (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; return elem; } } // создаем два доллара window.Helper = window.$$ = Helper; })(); И вызываем: <body> <div id="test"></div> <script type="text/javascript"> alert($$('test')); </script> </body> Однако, если в jQuery вызвать $('#test'), то он вернет не ссылку на ноду а сам себя, т.е. объект jQuery и чтобы получить ссылку на ноду в jQuery нам придется сделать что-то вроде этого: <body> <!-- Используем jQuery --> <div id="test"></div> <script type="text/javascript"> alert($('#test')); // выведет [object Object] (сам себя) alert($('#test')[0]); // выведет [object HTMLDivElement] </script> </body> Все это потому, что все найденные элементы jQuery цепляет к себе. Ничто не мешает нам сделать так же: (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; this[0] = elem // цепляем элемент к объекту return this; // возвращаем не элемент, а наш объект } } window.Helper = window.$$ = Helper; })(); Вот у нас и получится тоже самое: <body> <!-- Используем наш фреймворк --> <div id="test"></div> <script type="text/javascript"> alert($$('test')); // выведет [object Object] (сам себя) alert($$('test')[0]); // выведет [object HTMLDivElement] </script> </body> Теперь давайте добавим в наш фреймворк какой-нибудь метод, например пусть у него будет имя getNodeName(), а возвращать он будет имя ноды: (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; this[0] = elem return this; }, getNodeName: function() { // наш новый метод // возвращает имя ноды найденного объекта в верхнем регистре return this[0].nodeName.toUpperCase(); } } window.Helper = window.$$ = Helper; })(); Давайте попробуем при помощи нашего нового метода узнать имя ноды: <body> <div id="test"></div> <script type="text/javascript"> alert($$('test').getNodeName()); // Ошибка !!! </script> </body> Почему же это не работает? Как я уже говорил выше, вспомогательная функция Helper создает новый объект с именем Helper.foo.init, а внутри нашего метода init() нет никаких других методов. Поэтому нам надо переопределить прототип для Helper.foo.init, т.е. указать скрипту явно, что шаблоном нашего объекта является не Helper.foo.init, а Helper.foo. Причем наш объект foo должен храниться обязательно как свойство объекта Helper иначе (если я правильно понял, прочитав кучу статей про прототипы) переопределить прототип не получится. (function() { var Helper = function(elem) { return new Helper.foo.init(elem); } Helper.foo = { init: function(elem) { elem = typeof elem == 'string' ? document.getElementById(elem) : elem; this[0] = elem return this; }, getNodeName: function() { return this[0].nodeName.toUpperCase(); } } Helper.foo.init.prototype = Helper.foo; window.Helper = window.$$ = Helper; })(); Вот теперь все заработает: <body> <div id="test"></div> <script type="text/javascript"> alert($$('test').getNodeName()); // выведет DIV </script> </body> Ну вот и все, теперь вы можете расширять свой фреймворк, добавляя туда новые методы и использовать его так же как и jQuery. Теперь вы представляете как устроен этот фреймворк. Конечно то что я тут описал - это очень сильно упрощенная версия jQuery. Она умеет находить ноду только по ID и в ней нет кучи полезных фишек jQuery. Но я не волшебник, я только учусь. Многое еще остается в jQuery для меня не ясным, но надеюсь со временем я его таки доковыряю P.S. Что я читал: http://javascript.ru/ecma/part8#_Prototype_ http://javascript.ru/tutorial/object/inher...type-i-prototip http://code.jquery.com/jquery-1.4.2.js http://dklab.ru/chicken/nablas/40.html
  11. 6 points
  12. 6 points
    А вот мой набросок :
  13. 6 points
    "Меня гложут смутные сомнения - у Шпака магнитофон, у посла медальон..." Можно раздел во флейме создать, "тайные истории с Брендмастером", валютные махинации, стрелки 90-ых, Триада) да да я знаю сообщение не по разделу. но елы-палы, я не могу xD
  14. 6 points
    После Caps Lock и кучи восклицательных и вопросительных знаков все вопросы отпали сам собой. Что и требовалось доказать. Договор не значит в этом бизнесе ничего, фрилансер бесправен. К тому же, заключив договор, вы будете обязаны оплатить налог с суммы сделки. Если не 100%, то 50/50. Дизайнер показывает вам немного уменьшеный (60-70% от оригинала) макет в формате jpg, если заказчик принимает, то высылает исходники и получает остальные 50%. Причем рекомендую исполнителям не вестись на договоры (о чем я написал выше), а требовать расписку с указанием полной суммы сделки, сумму половины которую вам выдадут за макет и оставшуюся сумму. Причем расписка пишется от частного лица частному лицу, как обязательство. В суде за неисполнение долга могут не просто обязать выплатить долг, но и мошенничество пришить. Обязательно переслать самому себе на мыло исходники и ни в коем случае не читать это письмо. В суде это одно из решающих доказательств и всегда учитывается судьей. Все это проверено на личном опыте. А договором можете подтереться, ООО отвечает только своим уставным капиталом в 10.000 рублей, тогда как частное лицо или ИП всем своим имуществом. Еще вопросы есть?
  15. 6 points
    Я долго вынашивал коварные планы по реализации на яваскрипте кастомного селекта, который можно было бы легко стилизовать. И вот наконец я на все плюнул, сел и написал его в виде плагина для jQuery. Прошу потестить его на баги (хотя я уверен, что отловил их все). http://berezkin-r.narod.ru/select/ Что умеет: все, что должен уметь обычный <select>, за исключением того что его можно очень легко стилизовать Что не умеет: нет мультиселекта (мне по работе он не нужен, поэтому делать было влом), он вообще сильно нужен? Работоспособность проверена в: Google Chrome (последний) Apple Safari (последний) Mozilla Firefox 4 Opera 11.11 (редкое дерьмо, а не браузер) IE 9 IE 9 (в режиме IE8) IE 9 (в режиме IE7) IE 6 (виртуальная машина с XP SP1) В IE 6 имеется ровно один глюк, о котором я знаю и исправлять его не собираюсь, кто найдет его может взять с полки пирожок
  16. 6 points
    Одного желания и наличия команды недостаточно. Если проводить аналогии, то вы должны быть дирижёром, перед которым лежит партитура музыкального произведения. Только дирижёр знает и понимает, как должно звучать музыкальное произведение и лишь отдаёт команды исполнителям в какой момент им вступать, в какой останавливаться, где нужен акцент, где крещендо. Также можно сравнить эту работу с режиссёром, который вначале визуально представляет картину в мыслях, а затем воплощает её в виде видеоряда. Но режиссёру также нужны художники, операторы, костюмеры, гримёры, которые не знают ничего о замысле режиссёра, и он должен простыми словами донести до них свою задумку, установить чёткие сроки, следить за выполнением работы, утверждать её, давать комментарии, хвалить людей, поддерживать в них мотивацию и следить за тем, чтобы к указанной дате всё было воплощено в жизнь. Вы хотите сделать проект, но в реальности у вас сейчас нет ни концепции, ни грамотного описания что вы хотите получить. Без этого ничего у вас не получится. Никто к вам не пойдёт, потому что нет стимула, нет понимания, что получится нечто действительно стоящее. К тому же вам постоянно придётся работать с разношёрстной командой специалистов. Хватит ли у вас сил координировать их работу, давать им правильные задания, контролировать сроки выполнения?
  17. 6 points
  18. 6 points
    Вступление Что мы будем делать: бесконечную карусель картинок (infinite image carousel - это для тех, кто хочет погуглить на тему). Используем для этого небезызвестный фреймворк jQuery. Но мы не будем писать просто код, а напишем полноценный легко настраиваемый плагин. Вообще говоря, на сайте http://www.jquery.com/ есть туториал как писать плагины для jQuery, но для тех кто не знает английского, я опишу важные моменты. Т.к. у меня нет хостинга, то я не могу показать вам что получится у нас в итоге, но примерный результат вы можете посмотреть на этой странице http://jqueryfordesigners.com/demo/infinite-carousel.html. Конечно же мы не будем полностью клонировать эту карусель, а напишем свою, которая будет во многом лучше и удобней для конкретного применения. Итак, приступим... Базовая верстка Наша каруселька будет состоять из нескольких элементов, вложенных друг в друга. Обычно (если кто гуглил, то заметил) это <div>, в который вложен неупорядоченный список (<ul>). Но я не хочу привязываться к определенному HTML, поэтому остановимся на таком обязательном условии: на странице должен быть блок-контейнер, в него должен быть вложен блок-карусель, в который могут быть вложены любые элементы с display: block; или display: inline-block; Но для простоты будем работать с версткой как у всех (хотя это не важно): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="ru"> <head> <title>jQuery Карусель</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <style type="text/css"> .container { border: red 1px solid; } .carousel { margin: 0; padding: 0; list-style: none; } .carousel li { float: left; width: 88px; height: 88px; padding: 5px; background: lightblue; border: blue 1px solid; } </style> <!-- Тут подключаем фреймворк jQuery. Лучше конечно скачать его себе в проект, а не использовать ссылку на сторонний ресурс (как у меня). --> <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script> <!-- Подключаем наш плагин, который будет расположен по адресу js/myCarousel.js (ну или куда вы там его положите) --> <script type="text/javascript" src="js/myCarousel.js"></script> <script type="text/javascript"> $(document).ready(function() { // ...тут будет вызываться наш плагин }); </script> </head> <body> <div class="container"> <!-- Вместо <ul> может быть любой блочный элемент, в который могут быть вложены любые блочные элементы --> <ul class="carousel"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> </ul> </div> <!-- Кнопки навигации могут располагаться где угодно на странице --> <button class="prev"><</button> <button class="next">></button> </body> </html> Вот и вся тестовая страничка, над которой мы будем экспериментировать. Больше к HTML мы возвращаться не будем, начнем писать скрипт... Как пишутся плагины для jQuery Прежде всего, рекомендую вам пройти по этой ссылке - http://docs.jquery.com/Plugins/Authoring где написан подробный туториал по созданию плагинов для jQuery. Я не буду полностью переводить его, а остановлюсь лишь на моментах, которые важны для нашего проекта. Приступая Итак, чтобы написать плагин для jQuery нужно добавить новый метод к объекту jQuery.fn: // создаем новый метод объекта jQuery.fn jQuery.fn.myCarousel = function() { // Тут пишем код нашего плагина }; "Но где же знак доллара ($)?", спросите вы. Не волнуйтесь, он все еще тут. Однако, чтобы удостовериться, что наш плагин не пересекается с другими библиотеками, которые тоже используют знак доллара, лучше всего передать объект jQuery в самовыполняющуюся функцию (замыкание), которая свяжет его со знаком доллара так, что его нельзя будет переназначить: // создаем функцию-замыкание... (function($){ // создаем новый метод объекта jQuery.fn $.fn.myCarousel = function() { // Тут пишем код нашего плагина }; })(jQuery); // ...которую тут же вызываем, передавая ей в качестве аргумента объект jQuery Таким образом мы сможем использовать знак доллара внутри нашего плагина, не боясь, что он (доллар) может быть переназначен другим скриптом. Контекст Для тех кто не знает что такое контекст (<b>this</b>) рекомендую почитать эту статью. В области видимости (scope) плагина ключевое слово this ссылается на сам объект jQuery, по этому его нет необходимости оборачивать таким образом - $(this);, что является распростаненной ошибкой среди начинающих разработчиков плагинов. Смотрим код: (function($){ $.fn.myCarousel = function() { // нет необходимости писать $(this) т.к. // "this" уже ссылается на объект jQuery // запись $(this) будет означать то же самое, что и $($('#element')); this.fadeIn('normal', function() { // здесь же this будет ссылаться на конкретный DOM-элемент }); }; })(jQuery); Цепь вызовов Почти каждый метод фреймворка jQuery возвращает собственно сам объект jQuery. Это сделано для того, чтобы обеспечить возможность цепочки вызовов. Давайте рассмотрим такой код: $('div').children().css('background', 'red'); Методы .children() и .css() оба являются методами объекта jQuery, но в коде они вызываются последовательно (по цепочке), это возможно благодаря тому, что каждый метод возвращает нам объект jQuery. Это и называется цепь вызовов. Чтобы наш плагин обеспечивал эту возможность, нам нужно из ближайшей области видимости (immediate scope) вернуть ссылку на объект-конструктор, т.е на jQuery. Так же. чтобы наш плагин работал со всеми найденными элементами нам надо использовать метод .each(): (function($){ // создаем новый метод объекта jQuery.fn $.fn.myCarousel = function() { // возвращаем ссылку на объект jQuery return this.each(function() { // сохраняем контекст ($this будет ссылаться на объект jQuery) var $this = $(this); // ...далее идет код плагина }); }; })(jQuery); Опции и значения по умолчанию Для того чтобы плагин можно было легко настраивать можно сделать настройки по умолчанию, которые можно изменять или расширять при помощи метода .extend(). Таким образом нам не придется задавать кучу параметров для нашего плагина, вмето этого можно передать всего один, который будет объектным литералом (JSON): (function($){ /* * создаем новый метод объекта jQuery.fn, * в который передаем параметр options */ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { a: 1, b: 'text' }; // возвращаем ссылку на объект jQuery return this.each(function() { if (options) { // если в функцию передали опции /* * метод .extend() сливает два объекта, * заменяя совпадающие свойства, * которые есть в объекте settings * новыми свойствами из объекта options * и возвращает измененный settings */ $.extend(settings, options); } // сохраняем контекст ($this будет ссылаться на объект jQuery) var $this = $(this); alert(settings.a); alert(settings.; }); }; })(jQuery); // пример вызова плагина $(document).ready(function() { $('div').myCarousel({ a: 42, b: 'новый текст' }); }); В принципе это все что понадобится нам для создания нашего плагина, поэтому я не буду описывать остальные параграфы из туториала. Кому интересно прочитает о них самостоятельно. Начинаем писать плагин Итак, приступаем к написанию собственно нашего плагина-карусели. Для начала давайте определимся, что нам надо от нашей карусели: 1) она должна быть бесконечной, т.е. когда мы домотаем до последнего элемента все начнется по кругу; 2) кнопки управления могут находится в любом месте на странице (чтобы мы могли подстраивать её под любой дизайн); 3) мы должны сами выбирать по сколько элементов за раз будет проматываться; 4) мы болжны сами выбирать с какой скоростью будут перематываться элементы; 5) мы должны сами выбирать сколько элементов будет отображаться в обласи видимости, а сколько будет "за кадром"; 6) должна быть возможность автоматической перемотки если юзер не нажал на стрелки сам. Вооружившись знаниями о написании плагинов, приступим к реализации задуманного: (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, // видимых элементов - 3 rotateBy: 1, // мотать по одному элементу speed: 500, // скорость перемотки (в миллисекундах) btnNext: null, // кнопка перемотки к следующему элементу btnPrev: null, // кнопка перемотки к предыдущему элементу auto: null, // время задержки (в миллисекундах) при автоматической перемотке backSlide: false // будет ли карусель крутиться в обратную сторону при автоматической перемотке }; return this.each(function() { if (options) { $.extend(settings, options); } var $this = $(this); // сохраняем контекст }); }; })(jQuery); Тут надеюсь все понятно. Теперь нам необходимо определить, так сказать, "глобальные" переменные (конечно они не глобальные во всем документе, а "глобальные" для нашего плагина): (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } // определяем "глобальные" переменные var $this = $(this); // сохраняем контекст var $carousel = $this.children(':first'); // находим первого потомка в нашем контейнере (.container), т.е. <ul> var itemWidth = $carousel.children().outerWidth(); // находим ширину одного элемента внутри нашего контейнера var itemsTotal = $carousel.children().length; // определяем сколько всего элементов у нашей карусели var running = false; // флаг, который хранит информацию о том проигрывается ли анимация на данный момент var intID = null; // ID интервала (нужен для сброса интервала) }); }; })(jQuery); Обратите внимание на то что я специально взял слово "глобальные" в кавычки, чтобы у вас не возникло путаницы. Эти переменные не являются глобальными на самом деле, т.е. они не видны за пределами функции. Возможно лучше было бы обозвать их "статическими", но мне больше понравился первый вариант. Далее нам необходимо присвоить такие стили для нашей карусели без которых она не будет работать. Юзер может забыть их присвоить, поэтому нам необходимо задавать эти стили скриптом: (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } // определяем "глобальные" переменные var $this = $(this); var $carousel = $this.children(':first'); var itemWidth = $carousel.children().outerWidth(); var itemsTotal = $carousel.children().length; var running = false; var intID = null; // присваиваем необходимые стили для элементов карусели // сначала для контейнера $this.css({ 'position': 'relative', // необходимо для нормального отображения в ИЕ6(7) 'overflow': 'hidden', // прячем все, что не влезает в контейнер 'width': settings.visible * itemWidth + 'px' // ширину контейнера ставим равной ширине всех видимых элементов }); // потом для внутреннего элемента (в нашем случае <ul>) $carousel.css({ 'position': 'relative', // относительное позиционирование нужно для того, чтобы можно было использовать сдвиг влево 'width': 9999 + 'px', // ставим ширину побольше, чтобы точно влезли все элементы 'left': 0 // устанавливаем нулевой девый сдвиг }); }); }; })(jQuery); Теперь, после всех приготовлений, пришло время заняться написанием нашей главной функции - функции "скольжения", которая будет прокручивать карусель. Я не буду расписывать на словах как она работает, а лучше покажу схему, из которой вам будет больше понятен принцип работы бесконечной карусели: На картинке описана прокрутка к предыдущему элементу. Такая же последовательность действий у нас будет при прокрутке к следующему элементу. Остальное, надеюсь, будет понятно из кода: (function($){ $.fn.myCarousel = function(options) { // дефолтные настройки var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } // определяем "глобальные" переменные var $this = $(this); var $carousel = $this.children(':first'); var itemWidth = $carousel.children().outerWidth(); var itemsTotal = $carousel.children().length; var running = false; var intID = null; // присваиваем необходимые стили для элементов карусели // сначала для контейнера $this.css({ 'position': 'relative', // необходимо для нормального отображения в ИЕ6(7) 'overflow': 'hidden', // прячем все, что не влезает в контейнер 'width': settings.visible * itemWidth + 'px' // ширину контейнера ставим равной ширине всех видимых элементов }); // потом для внутреннего элемента (в нашем случае <ul>) $carousel.css({ 'position': 'relative', // относительное позиционирование нужно для того, чтобы можно было использовать сдвиг влево 'width': 9999 + 'px', // ставим ширину побольше, чтобы точно влезли все элементы 'left': 0 // устанавливаем нулевой девый сдвиг }); // параметр dir(boolean) - false(сдедующий), true(предыдущий) function slide(dir) { var direction = !dir ? -1 : 1; // выбираем направление в зависимости от переданного параметра (влево или вправо) var leftIndent = 0; // левое смещение (для <ul>) if (!running) { // если анимация завершена (или еще не запущена) running = true; // ставим флажок, что анимация в процессе if (intID) { // если запущен интервал window.clearInterval(intID); // очищаем интервал } if (!dir) { // если мы мотаем к следующему элементу (так по умолчанию) /* * вставляем после последнего элемента карусели * клоны стольких элементов, сколько задано * в параметре rotateBy (по умолчанию задан один элемент) */ $carousel.children(':last').after($carousel.children().slice(0, settings.rotateBy).clone(true)); } else { // если мотаем к предыдущему элементу /* * вставляем перед первым элементом карусели * клоны стольких элементов, сколько задано * в параметре rotateBy (по умолчанию задан один элемент) */ $carousel.children(':first').before($carousel.children().slice(itemsTotal - settings.rotateBy, itemsTotal).clone(true)); /* * сдвигаем карусель (<ul>) влево на ширину элемента, * умноженную на количество элементов, заданных * в параметре rotateBy (по умолчанию задан один элемент) */ $carousel.css('left', -itemWidth * settings.rotateBy + 'px'); } /* * расчитываем левое смещение * текущее значение left + ширина одного элемента * количество проматываемых элементов * на направление перемещения (1 или -1) */ leftIndent = parseInt($carousel.css('left')) + (itemWidth * settings.rotateBy * direction); // запускаем анимацию $carousel.animate({'left': leftIndent}, {queue: false, duration: settings.speed, complete: function() { // когда анимация закончена if (!dir) { // если мы мотаем к следующему элементу (так по умолчанию) // удаляем столько первых элементов, сколько задано в rotateBy $carousel.children().slice(0, settings.rotateBy).remove(); // устанавливаем сдвиг в ноль $carousel.css('left', 0); } else { // если мотаем к предыдущему элементу // удаляем столько последних элементов, сколько задано в rotateBy $carousel.children().slice(itemsTotal, itemsTotal + settings.rotateBy).remove(); } if (settings.auto) { // если карусель должна проматываться автоматически // запускаем вызов функции через интервал времени (auto) intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } running = false; // отмечаем, что анимация завершена }}); } return false; // возвращаем false для того, чтобы не было перехода по ссылке } // назначаем обработчик на событие click для кнопки next $(settings.btnNext).click(function() { return slide(false); }); // назначаем обработчик на событие click для кнопки previous $(settings.btnPrev).click(function() { return slide(true); }); if (settings.auto) { // если карусель должна проматываться автоматически // запускаем вызов функции через временной интервал intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } }); }; })(jQuery); Вот и готов наш плагин Сохраните его в файле my_carousel.js, подключите на страницу, а затем, между тегами <head></head> напишите такой вызов: <script type="text/javascript"> $(document).ready(function() { $('.container').myCarousel({ btnNext: '.next', btnPrev: '.prev', visible: 4, rotateBy: 2 }); }); </script> Итак, опишем настройки для нашей карусели: btnNext - строка, выражение в формате jQuery (по умолчанию null) btnPrev - строка, выражение в формате jQuery visible - целое число, количество видимых элементов (по умолчанию 1) rotateBy - целое число, по сколько элементов мотать за раз (по умолчанию 1) speed - целое число, скорость прокрутки элементов в миллисекундах (чем больше тем медленней, по умолчанию 500 миллисекунд) auto - целое число, задержка автоматической прокрутки элементов в миллисекундах (если назначена, по умолчанию null) backSlide - булево значение true/false, направление прокрутки: false - к следующему элементу, true - к предыдущему элементу (по умолчанию false) И на последок полный код нашего плагина без комментариев. my_carousel.js (function($){ $.fn.myCarousel = function(options) { var settings = { visible: 3, rotateBy: 1, speed: 500, btnNext: null, btnPrev: null, auto: null, backSlide: false }; return this.each(function() { if (options) { $.extend(settings, options); } var $this = $(this); var $carousel = $this.children(':first'); var itemWidth = $carousel.children().outerWidth(); var itemsTotal = $carousel.children().length; var running = false; var intID = null; $this.css({ 'position': 'relative', 'overflow': 'hidden', 'width': settings.visible * itemWidth + 'px' }); $carousel.css({ 'position': 'relative', 'width': 9999 + 'px', 'left': 0 }); function slide(dir) { var direction = !dir ? -1 : 1; var leftIndent = 0; if (!running) { running = true; if (intID) { window.clearInterval(intID); } if (!dir) { $carousel.children(':last').after($carousel.children().slice(0, settings.rotateBy).clone(true)); } else { $carousel.children(':first').before($carousel.children().slice(itemsTotal - settings.rotateBy, itemsTotal).clone(true)); $carousel.css('left', -itemWidth * settings.rotateBy + 'px'); } leftIndent = parseInt($carousel.css('left')) + (itemWidth * settings.rotateBy * direction); $carousel.animate({'left': leftIndent}, {queue: false, duration: settings.speed, complete: function() { if (!dir) { $carousel.children().slice(0, settings.rotateBy).remove(); $carousel.css('left', 0); } else { $carousel.children().slice(itemsTotal, itemsTotal + settings.rotateBy).remove(); } if (settings.auto) { intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } running = false; }}); } return false; } $(settings.btnNext).click(function() { return slide(false); }); $(settings.btnPrev).click(function() { return slide(true); }); if (settings.auto) { intID = window.setInterval(function() { slide(settings.backslide); }, settings.auto); } }); }; })(jQuery); Предложения, критику и прочее в приват. Всем спасибо за внимание.
  19. 5 points
    Долго у меня напрашивался этот цикл статей и вот наконец изливаюсь. А цикл этот вот о чём. Вёрстка и верстальщик. Основы профессии если хотите и логика действий при вёрстке. Решил разделить пока на две статьи. И предлагаю ознакомится с первой. Верстальщик кто-он? И так поехали. Не хотелось бы скатиться до популизма и повторения много раз описанных истин, поэтому постараюсь писать как можно понятнее и всё-таки передать мысль закладываемую в текст. В сети множество примеров статей и вообще материала о принципах вёрстки, инструментах, методиках написания кода, семантике и т.?д. Но я ещё ни-разу не встречал статьи рассказывающей о том с какого бока подойти к этому процессу, с чего лучше начать и по какому пути двигаться. Наблюдая год от года молодых верстальщиков и вебпрограммистов, совершающих одни и те же ошибки, такая статья просто проситься к написанию. Поэтому в следующем наборе букв постараюсь описать принципы и так сказать мыслительные процессы которые надо вырабатывать в себе для того чтобы начать двигаться с мёртвой точки новичка до специалиста в своём деле. Я не претендую на то, что описанные мною алгоритмы мышления и действий являются истиной в первой инстанции и только так и надо делать. Нет ни в коем случае! Для каждого верстальщика или же веб программиста существует своя истина и свои принципы. Всё-таки все мы люди и все ходим по своим дорогам. Но основные алгоритмы у нас всех одинаковые и отличаются только методом изложения и внедрения. Хотелось бы донести одну не тривиальную мысль к пониманию которой приходишь только с опытом и количеством реальной работы в каждом из этапов проекта. Верстальщика нельзя назвать чем-то самостоятельным в команде, единицей мнением которой можно пренебречь или как говориться сработать в слепую, отдал макет, получил страницу (К сожалению-это самый частый случай на ниве фриланса). Как правило из такой работы ничего хорошего не получается. Потому-что верстальщик работает не зная под что и не понимая идеи проекта, а это ведёт к тому что программист получает сложности с внедрением вёрстки в код, копирайтер обнаруживает нехватку или избыток стилей и элементов усложняющих ему жизнь. Сеошник сталкивается с грязью в коде или же не возможностью выстроить необходимое семантичное ядро на странице. В результате всем участникам проекта приходится либо чем-то жертвовать, либо переделывать кучу не профильной работы. Что в свою очередь ведёт к удорожанию проекта или к увеличению сроков проекта. На верстальщика возлагается очень большая ответственность которой нет ни у дизайнера, ни у программиста. Верстальщик своего рода «серый кардинал» проекта, перехватывающий «эстафетную палочку» у менеджера проекта, на стадии от-рисованного макета и параллельно его работе координирует техническую составляющую. По неволе верстальщику приходиться касаться почти каждого этапа проекта и учитывать получаемые рекомендации в своей работе. Как однажды сказал один мой друг. Верстальщик это руки которые складывают бутерброд, от них зависит в каком порядке будут размещены ингредиенты!© Поэтому не бойтесь брать на себя эту ответственность и в теневом режиме координировать исполнение проекта. Не бойтесь думать и отстаивать своё мнение, не бойтесь вносить хотя-бы мелкие поправки в проекты которые вам приходиться делать. В этом ваше предназначение как верстальщика и если вы решаете сделать это увлечение делом вашей жизни, то несите эту ответственность с честью. Поэтому думайте, думайте и ещё раз думайте, в этом залог роста. Прежде чем начать что-то делать потратьте хотя-бы пару минут на то чтобы продумать, как это сделать, затем ещё пару минут на то чтобы продумать, как это сделать лучше, чем сделали бы другие и даже после того когда вроде бы вы уже всё придумали и нарисовали себе в голове идеальную разметку, потратьте ещё с десяток минут на то чтобы ясно себе представить процесс и его реализацию. Прогоните через мозг каждый не очевидный и очевидный элемент макета, каждую строчку кон-тента и каждый блок на странице. Выведите общую формулу проекта распределив по своим группам повторяющиеся элементы и части которые эксклюзивные для страницы. Не надо этого делать на бумаге, приучите себя делать это в голове. Оценивать макет и проект в целом с одного лишь взгляда. Приучите себя понимать то, что вам предстоит сделать, подмечая какие подводные камни встретятся на пути, какими техниками вам придётся воспользоваться и что займёт больше всего времени. Вот с этого пожалуй и должна начинаться любая вёрстка, любого макета. С продумывания и оценки своей будущей работы. Простой ли он, или много-колоночный, резиновый, статичный, под какой тип устройств, на какой платформе и какие браузеры будут его рендерить. Прикиньте вес каждой страницы в отдельности и подведите его под критический порог. Соотнесите на сколько удастся соблюсти стандарты и придётся-ли использовать сторонние технологии для реализации интерфейса. Возьмите на заметку под какую CMS необходима вёрстка и какие её особенности надо учесть. Определите основное семантическое видение страницы. Если есть ТЗ, то вооружившись им, составьте карту страницы с описанием главных и второстепенных блоков, основных заголовков и их подзаголовков. Определите, где, какой тип кон-тента расположен и выстроен ли он в логичном с точки зрения семантики порядке. Какие варианты изменения в содержимом должны выдержать контентные блоки, на сколько макет восприимчив к эволюции содержимого, которое может появиться со-временем на страницах, существование каких элементов надо предусмотреть на будущее. Не бойтесь если в процессе оценки макета вы поймёте что многих вещей дизайнер банально не продумал или не предусмотрел. Как правило, при коллективной работе, дизайнер при от-рисовке макета плотно советуется с верстальщиком, также как верстальщик консультируется у программиста, создавая тем самым естественную цепочку производства. Поэтому обоснованные поправки к макету должны быть учтены дизайнером. На своём веку я много повидал дизайнеров и мало кто отказался от внесения поправок в макет, естественно что они были аргументированы и внесены до предоставления макета заказчику. Хотя случается и такое что работа ведётся разрозненно, тогда аргументы необходимо высказать заказчику напрямую, пояснив с какими трудностями, в будущем, он столкнётся при сборке проекта программистом и продвижении или поддержке проекта. Старайтесь упрощать жизнь себе и тем, кто будет работать над проектом в дальнейшем. Думаю я немного отклонился от темы и ушёл-таки в популизм. Но об этом нельзя было не сказать. Наблюдая как многие молодые верстальщики словно во тьме роются в тегах, забывая про идею и саму суть своей профессии. В следующей части постараюсь более подробно описать логику действий и принцип принятия решений на конкретном примере, будем верстать проект публично)))
  20. 5 points
    Это вольный перевод замечательной статьи молодого американского дизайнера Кендры Гейнс, в которой кроме общих понятий о том, что такое минимализм, приведен список примеров сайтов с отличными комментариями к ним. Возможно статья поможет начинающим дизайнерам и просто веб-мастерам, которые вынуждены делать сайты под ключ в одиночку (их на этом форуме большинство) ощутить эту тонкую грань между красивым минимализмом и просто унылым пустым нечто. Существует много разговоров о том, что техника дизайна, которую большинство называют "Минимализм", умирает или уже умерла. Я вынуждена не согласиться с ними. Минимализм не умер. Так говорят в основном потому, что люди не совсем понимают, что это такое. К сожалению, кажется, люди считают его каким-нибудь определенным стилем или направлением. Хотя я считаю минимализм скорее техникой или, в меньшей степени, общими правилами. Техника может соответствовать различным ситуациям - если мы говорим о веб-дизайне, вы можете использовать минимализм и в портфолио, и в веб-магазинах, и вообще во всем, что вы разрабатываете. Что такое Минимализм? Что такое Дизайн? Книжное определение "минимализма" звучит как "дизайн или стиль, в котором минимально простыми элементами достигается максимальный эффект". А понятие "минималистичное искусство " (minimal art) - "абстрактная живопись или скульптура, в которой выразительность и иллюзия сведены к минимуму за счет использования простых геометрических форм и объектов, а так же ровных, плоских цветов". Последнее определение больше подходит для описания специфики этого направления в искусстве, но если мы говорим о дизайне, который является больше наукой, нежели искусством, то оба эти определения на самом деле идут рука об руку. Дизайн - это то, что вы используете для упорядочения информации таким образом, чтобы это было эстетически приятно. Лучшие дизайны - это дизайны без излишеств и банальностей. Вот что такое минимализм. Если вы дизайните "для того, чтобы было красиво", то вы не разрабатываете дизайн, вы просто декорируете. Одной из самых крутых вещей, которую я слышала о типографике (которая тесно связана с графическим дизайном), является фраза: "Если вы не можете прочитать это - значит вы не поняли сути". А о графическом дизайне - "Когда дизайн готов, не задавайтесь вопросом чего не хватает, задайтесь вопросом - что можно убрать?" Примеры минимализма Люди должны понять, что есть различные уровни минимализма. Есть, конечно, люди, которые стараются придерживаться "голого" дизайна насколько это возможно - только текст и несколько картинок. В то время как другие просто хотят быть уверены в том, что они делают действительно чистый дизайн. В любом случае минимализм должен быть использован (и будет) в качестве основы для дизайна. Если у вас есть сайт, посвященный вашим мыслям, вашей работе или вашему продукту - минимализм будет работать и там. Ниже приведены несколько различных сайтов, которые используют минималистичный подход. 8faces.com Как видите, господа, здесь много внимания уделяется типографике чтобы убедиться, что текст легко читаем. Картинки не разбросаны повсюду, а находятся в аккуратно созданных для них пространствах. bestawards.co.nz Этот сайт использует ровный, плоский цвет с вкраплениями фиолетового и хороший макет для того, чтобы привлекать ваше внимание к наиболее значимым частям веб-сайта. Я бы сказала, что это сайт, который не уходит слишком далеко от корней минимализма, и в то же время добавляет некоторые более красивые дизайнерские элементы. collectedhere.com Вы наверное заметите, что в большинстве минималистичных сайтов используется сетка(grid). В этой сетке нет расстояний между элементами, что заставляет их заполнять собой все пространство. Тем не менее - это прекрасный, чистый сайт. createdm.com Это пример другого, очень чистого и очень сфокусированного сайта. Здесь не может быть даже малейшего непонимания того, чем эта компания занимается. eighthourday.com Этот сайт немножко сложнее. Здесь намного больше картинок и дизайнерских приемов, но они все-равно не отклоняются от принципа фокусирования и отсутствия лишних деталей. hatbox.co Без использования плоских цветов этот сайт является действительно чистым и сфокусированным. Создается ощущение, как будто дизайнер наибольшее внимание уделял точному расположению каждого элемента дизайна, а не сайту целиком. inmotionmassage.co.uk Этот сайт подошел довольно близко к основным ценностям минимализма, хотя в нем и используется больше цветов, чем в традиционных минималистичных сайтах. Разметка работает очень хорошо и опять же, ничего лишнего. kin-design.com Я бы сказала, этот веб-сайт действительно напоминает идею "минималистичное искусство". Хотя здесь и есть сетка, но сайт абстрактен и очень геометричен. Такое чувство, как будто этот дизайнер смешал идею минимализма в дизайне с такой же идеей в изобразительном искусстве. kristaduran.com Этот сайт сосредотачивается больше на дизайне и на красоте вещей, но так же можно сказать, что это не единственная цель дизайна сайта. А еще здесь превосходная компоновка. lamoulade.com La Moulade является одним из тех супер аккуратных одно страничных сайтов. Он использует много различных трюков и артистизма на вершине минимализма. Невозможно не знать, что здесь находится в центре внимания. learncss.tutsplus.com У многих брендов популярным становится создание мини-сайтов, которые продвигают один товар или услугу. Этот сайт мог бы быть очень грязным из-за обилии информации, которую он дает. Однако здесь дизайнеры проделали огромную работу по созданию сайта без излишков, что позволяет ему предоставлять всю информацию эстетически красиво. luanfreirekondo.com Еще один веб-сайт, который имитирует свойства минимализма как искусства. Плоские цвета, абстрактные интерпретации и геометрические формы. Это очень простое и правильное портфолио. mensdept.com Этот сайт использует минимализм больше, чем просто тенденцию. Если вы скролите вниз, то видите хорошую сетку с чрезвычайно богатым содержанием. Однако, я думаю, это очень хороший пример того, что минимализм бывает разным. modulab.co.uk Modulab имеют очень чистый и супер минималистичный веб-сайт. Здесь нету кучи цветов (только когда это необходимо) и абсолютно никаких излишеств. Отличная работа. pigbimpin.com Еще один сайт, в котором смешение обоих идей минимализма (искусства и техники) доведено до совершенства. Есть утверждение, что минималистичные сайты не могут иметь дополнительные функции типа социальных медиа, но здесь они определенно нашли хороший чистый способ сделать это. pillowcompany.com Когда речь идет о e-commerce сайтах, там действительно очень чего происходит и там расположено множество вещей, что порождает куча излишеств. На этом сайте много контента, но дизайнер постарался сделать дизайн чистым и сосредоточить внимание на вещах, которые действительно являются важными. sheltonfleming.co.uk Вот еще один сайт, где нет перебора с цветами. Здесь много интерактивности и он представлен в манере, которая интуитивно понятна для пользователя. thrivesolo.com А вот еще один очень простой сайт. Но его красота кроется в форме сложных элементов дизайна. Везде просматривается одна основная тема оформления, поэтому все вместе это работает эффективно и осмысленно. weltunit.com Этот сайт не сразу говорит сам за себя, его дизайн становится более ясным после некоторых поисков того, чем компания занимается. Использование серого и расположение элементов делают очень многое для этого минималистичного дизайна. wk.com Что мне нравится в этом сайте, так это использование графики и картинок таким образом, каким типичные минималисты не использовали бы никогда. Это определенно приятно для глаза, всего как-будто бы много, но разметка и дизайн расставляют все на свои места. yoshiharuota.com Этот веб-дизайн, наверное, представляет собой то, о чем народ говорит, обсуждая минимализм. Это "голый" дизайн, у которого нет абсолютно ничего лишнего. p.s. к сожалению форум не разрешает мне прикрепить все требуемые картинки, поэтому часть ссылок будет без превьюшек.
  21. 5 points
    В этой теме Максим попросил помощи по дизайну своего блога - http://forum.htmlbook.ru/index.php?showtopic=32217 Мы много с ним "воевали", но человек он хороший, как и профессионал очень высокого уровня. Решил помочь. Это пока набросок, но исходил из того, что никаких рюшечек как, собственно и обилия графики там быть почти не должно. Все строго, лаконично, любимый оранжевый также используется http://freeway-design.ru/files/css-live/main.png Прошу понять, что макет сделан очень быстро и, повторяю, является черновиком. Update (контрастный вариант): Update - http://freeway-design.ru/files/css-live/main2.png
  22. 5 points
    У меня знакомый в свои 14 лет написал адекватный движок (подобие фриланса, но там другие цели), знакомый дизайнер в свои 16 рисует неплохие макеты. Так что в 25 они к двадцати пяти годам будут гуру. Они ведь не просят сделать всё за них, а сами садятся и делают. Да, поначалу что-то непонятно, но Яндекс всегда открыт для ищущих ответов. Вот уже идёт второй (или третий) день существования этого топика. Сколько за это время вы сверстали страниц? Сколько нарисовали макетов? Сколько написали скриптов? Да, разумеется, нисколько. Ведь вы даже не пытались, вы лентяй, который не будет учиться и который хочет, чтобы всё сделали за него. При этом вы не сможете грамотно руководить проектом. Да что там проектом руководить, вы техническое задание адекватно написать не в силах, а всё потому что не понимаете даже основ. Люди становятся директорами не из-за того что они такие лентяи, а потому что знаний у них много. Не суть, что они полные, но как минимум во всех областях должно быть понимание. А про оплату в 3 доллара это капец? Хороший дизайнер получает от 1600 рублей за одну страничку. Хороший верстальщик получает от 1400 за страницу. Про программистов не скажу, но цены там не меньше. И эти деньги получаются за одну работу, а не за месяц. Месячная зарплата профессионалов заходит за 25-30 тысяч. 3 доллара в месяц не привлекут никого. На это не купить еды, не посидеть в баре, да даже адекватный хостинг не оплатить (базовый пакет в юкозе - говно). Что скажу насчёт серьёзных проектов в юкозе? Это невозможно. Я отлично знаю этот движок, прекрасно разбираюсь в плюсах и минусах. Работаю с ним с 2006 года. Да, этот движок удобен для создания небольших сайтиков-визиток, например. Можно позадрачиваться, чтобы поднатаскать свои уменя и сделать что-то более-менее привлекательное (но не стоящее). Стоящих сайтов в юкозе нет и сделать их там невозможно. Только мелкое. К чему это я? Да к тому что, если уж вы решили создавать свой интересный, оригинальный проект, то вам нужен свой движок, но никак не юкоз.
  23. 5 points
    О селекторе :nth-child уже написано немало, но я решил перевести свежую статью Криса Коера , где все самые популярные методы использования этого селектора объединили и разложили по полочкам. У меня просто голова кружится, когда я сталкиваюсь с такими идеальными для использования селекторами как :nth-child или :nth-of-type! Чем лучше их понимаешь, тем больше css нердгазмов (от слова nerd - ботан, заучка и т.д) получаешь! В этих примерах я буду использовать простой набор элементов списка и случайно выбранные числа. Вам должно быть ясно, как менять их, чтобы получить подобную выборку. Выбираем только Пятый элемент: li:nth-child(5) { color: green; } Чтобы выбрать первый элемент, вы можете использовать :first-child. Ну или вы уже сами догадаетесь как для этой задачи изменить пример, который я показал выше. Выбрать все, кроме первых пяти: li:nth-child(n+6) { color: green; } Если бы здесь было больше 10 элементов, такой селектор выбрал бы всех их, начиная с 6-го. Выбрать первыe пять элементов: li:nth-child(-n+5) { color: green; } Выбрать каждый четвертый, начиная с первого: li:nth-child(4n-7) { /* или 4n+1 */ color: green; } Выбрать только четные или нечетные: li:nth-child(odd) { color: green; } li:nth-child(even) { color: green; } Выбрать последний элемент: li:last-child { color: green; } Выбирает 10-ый, потому-что у нас есть 10 элементов. Было бы 8 - выбрал бы 8-ой элемент, 1290 - 1290-ый элемент и т.д Выбрать второй с конца: li:nth-last-child(2) { color: green; } Выбирает 9-тый элемент потому что у нас их 10. Было бы 30 - выбирал бы 29-тый элемент. Кроссбраузерность: Кроме ИЕ существует не так много браузеров, о поддержке этих селекторов в которых следует беспокоиться. Для ИЕ используйте Selectivizr.
  24. 5 points
    Как меня всегда умиляют «HR-специалисты» и тексты вакансий, которые они составляют. Во-первых, знание HTML+CSS === опыт вёрстки для веб, избыточность данных в тексте налицо. «...пунктуальность, исполнительность, инициативность ... приветствуются усидчивость, внимание к мелочам» — это вообще жесть. Неужели бывают такие вакансии (на сообтветствующих должностях), где этого бы не требовалось. Я вот ни разу не видел. Странными так же кажутся два момента. Первое — это «курсы по HTML, CSS-верстке» — большинство из них на редкость паршивые, сколько знаю веб-верстальщиков, все так или иначе самоучки. Второе это «высшее образование». Или надо писать «ВО по таким-то специальностям», или вообще ничего не писать — не понимаю зачем требовать любое высшее образование — вам шашечки или ехать? И, да, в данном контексте слово «ваши» надо писать с маленькой буквы, иначе это неграмотно — это не личное письмо. А насчёт того, что с каждым ЗП обсуждается индивидуально, то тут тоже промах — надо хотя бы указывать границы. Например, меня не интересует работа с зарплатой меньше 100 тысяч рублей в месяц, а вы не можете выделить на верстальщика больше 50. Зачем мне тратить своё и ваше время, чтобы узнать что мы друг другу не подходим? Прошу прощения за флуд, но я думаю, что так не стоит составлять тексты вакансий.
  25. 5 points
    Да, с такой структурой будет сложно добиться результата без скрипта. Куча абсолютно позиционированных dd-шек без координат будут накладываться друг на дружку в уголке, соседним селектором легко можно выбрать только одну, для остальных придется городить длинные цепочки. И в итоге получится что-то типа такого: body{ font-family: Georgia, Times, 'Times New Roman', serif; } #nav, #nav dl{ margin:0; padding:0; border: 1px solid #000; background: #515151; float: left; width:auto; } #nav dt{ float:left; position:relative; background: #515151; } #nav dd{ display:none; position:absolute; padding:8px 0; width:138px; background: #515151; } #nav a{ color:#fff; text-decoration:none; display:block; width:120px; padding:4px 10px; } #nav a:hover{ color:#000; background:#ccc; } #nav dt:hover{ background:#333; } /* заставим отображаться до 5 dd-шек подряд после наведенной dt-шки */ #nav dt:hover + dd, #nav dt:hover + dd + dd, #nav dt:hover + dd + dd + dd, #nav dt:hover + dd + dd + dd + dd, #nav dt:hover + dd + dd + dd + dd + dd { display:block; } /* зададим каждой dd-шке y-координату в зависимости от номера */ #nav dt:hover + dd { top: 36px; } #nav dt:hover + dd + dd { top: 80px; } #nav dt:hover + dd + dd + dd { top: 124px; } #nav dt:hover + dd + dd + dd + dd { top: 168px; } #nav dt:hover + dd + dd + dd + dd + dd { top: 212px; } /* а теперь еще каждой группе dd-шек нужно задать x-координату... */ /* для первой можно не задавать, пусть будет 0 по умолчанию */ /* для второй еще относительно просто... */ #nav dd + dt:hover + dd, #nav dd + dt:hover + dd + dd, #nav dd + dt:hover + dd + dd + dd, #nav dd + dt:hover + dd + dd + dd + dd, #nav dd + dt:hover + dd + dd + dd + dd + dd { left: 140px; } /* а вот начиная с третьей начинается ужас... */ #nav dd + dt + dd + dd + dd + dd + dd + dt:hover + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt:hover + dd + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt:hover + dd + dd + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt:hover + dd + dd + dd + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt:hover + dd + dd + dd + dd + dd { left: 280px; } /* для пятой надо еще учесть, что четвертая была пустой... кстати, по смыслу dl получается, что Download 1 - определение, подходящее не только к Downloads, но и к Help, это действительно так? */ #nav dd + dt + dd + dd + dd + dd + dd + dt + dd + dd + dd + dt + dt:hover + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt + dd + dd + dd + dt + dt:hover + dd + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt + dd + dd + dd + dt + dt:hover + dd + dd + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt + dd + dd + dd + dt + dt:hover + dd + dd + dd + dd, #nav dd + dt + dd + dd + dd + dd + dd + dt + dd + dd + dd + dt + dt:hover + dd + dd + dd + dd + dd { left: 560px; } /* к счастью, в CSS3 есть способ слегка облегчить наши мучения, но это не будет работать в IE7-8 */ #nav dt:nth-of-type(6):hover + dd, #nav dt:nth-of-type(6):hover + dd + dd, #nav dt:nth-of-type(6):hover + dd + dd + dd, #nav dt:nth-of-type(6):hover + dd + dd + dd + dd, #nav dt:nth-of-type(6):hover + dd + dd + dd + dd + dd { left: 700px; } #nav dt:nth-of-type(7):hover + dd, #nav dt:nth-of-type(7):hover + dd + dd, #nav dt:nth-of-type(7):hover + dd + dd + dd, #nav dt:nth-of-type(7):hover + dd + dd + dd + dd, #nav dt:nth-of-type(7):hover + dd + dd + dd + dd + dd { left: 840px; } И самое обидное: при уводе с dt, все эти dd-шки будут тут же прятаться, потому что соответствующий им dt перестанет быть :hover. Т.е. всё равно получится не меню, а в лучшем случае всплывающая подсказка. Надеюсь, теперь вам понятнее, почему вас с самого начала отговаривали от этой затеи?
This leaderboard is set to Kiev/GMT+03:00
  • Upcoming Events

    No upcoming events found
  • Blog Entries

  • Сообщения форума

    • Здравствуйте, кажется я делаю что-то не так, но вот что именно никак не пойму.
      Проблема в следующем: подключаю карусель и блок становится неактивен, хотя вроде бы все должно работать как нужно.
      Пробовал подключать карусель и через cdn и через скачанный архив - результат один и тот же.
      Открывал через google, firefox и opera-у - все так же никакого сдвига.
      Подключал по инструкции на официальном сайте.
      Пробовал использовать SlickSlider, но результат тот же.
    • Дорогие Друзья! Рад вам сообщить о выходе новой версии движка Flextype 0.9.5! Исправлено
      - core: исправлена проблема с кешем в Entries API — fetchAll()
      - core: исправлена проблема c генерацией Cache ID для Themes API
      - core: исравлена пролема с emitter twig функцией
      - admin-plugin: исправлены стили для кнопок Менеджера Тем
      - admin-plugin: исправления переводов
      - admin-plugin: исправлена ошибка возникающая если $query['format'] пустой Рефакторинг
      - core: удалена переменная $response из Forms render метода
      - core: добавлена свойство forms в Flextype\EntriesController Скачать
      https://github.com/flextype/flextype/releases/tag/v0.9.5
    • var render = document.querySelector('[data-action="render"]'); var destroy = document.querySelector('[data-action="destroy"]'); var boxes = document.getElementById("boxes"); render.addEventListener("click", getAmount); destroy.addEventListener("click", destroyBoxes); function getAmount() { var amount = +document.querySelector("#controls input").value; createBoxes(amount); } function createBoxes(amount) { var basicSize = 30; var fragment = document.createDocumentFragment(); for (var i = 0; i < amount; i++) { var size = basicSize + i * 10; var div = document.createElement("div"); div.style.cssText = `width: ${size}px; height: ${size}px; background-color: rgba( ${random()} , ${random()} , ${random()} )`; fragment.appendChild(div); } boxes.appendChild(fragment); } function destroyBoxes() { boxes.innerHTML = ""; } function random() { return Math.floor(Math.random() * 256); }  
    • Да! Спасибо!  А почему так не срабатывает?  cardWrap.onclick = function(event) { let target = event.target; while (target != this) { if (target.classList.contains("flip-card")) { if (target.classList.contains("is-flipped")) target.classList.remove("is-flipped"); target.querySelector(".friends-video").classList.remove("is-back"); target.querySelector(".friends-video__back > video").load(); target.querySelector(".friends-video__front > video").load(); else highlight(target); return; } target = target.parentNode; } }; Удалять класс он удаляет, а дальше  target.querySelector(".friends-video").classList.remove("is-back"); target.querySelector(".friends-video__back > video").load(); target.querySelector(".friends-video__front > video").load(); уже нельзя получается? А нет. Добавил скобочки { } и теперь вроде всё как надо, надеюсь. if (target.classList.contains("is-flipped")) { target.classList.remove("is-flipped"); target.querySelector(".friends-video").classList.remove("is-back"); target.querySelector(".friends-video__back > video").load(); target.querySelector(".friends-video__front > video").load(); } else { highlight(target); } return; https://codepen.io/npofopr/pen/zYOmbPv    
    • Пользователь вводит количество элементов в input и нажимает кнопку Создать, после чего рендерится коллекция. При нажатии на кнопку Очистить, коллекция элементов очищается. Создай функцию createBoxes(amount), которая принимает 1 параметр amount - число. Функция создает столько div, сколько указано в amount и добавляет их в div#boxes. Каждый созданный div: Имеет случайный rgb цвет фона Размеры самого первого div - 30px на 30px Каждый следующий div после первого, должен быть шире и выше предыдущего на 10px Создай функцию destroyBoxes(), которая очищает div#boxes. <div id="controls"> <input type="number" min="0" max="100" step="1" /> <button type="button" data-action="render">Создать</button> <button type="button" data-action="destroy">Очистить</button> </div> <div id="boxes"></div>