JavaScript
Задаем вопросы по JavaScript: оптимизация кода, примеры решений, анимация (питаю к ней неземную любовь), jQuery. Самые интересные вопросы будут добавляться прямо в статью. Большая просьба не задавать вопросов вроде «какую книгу по JavaScript советуете прочитать», «где найти уроки для начинающего кодера», «помогите найти ошибку в коде» и тому подобное — все это останется без ответа, по крайней мере с моей стороны.
Ответы
- Что думаете по поводу производительности популярных фреймворков? Какой лучше использовать? Например, здесь (http://lusever.ru/css-selectors/) prototype уделывает jquery.
-
Тесты производительности фреймворков — такая же маркетинговая спекуляция, как и ACID тест для брузеров: на картинках все круто, а когда начинаешь использовать те же CSS-свойства, но в другой комбинации, появляется куча проблем. Например, в тестовом документе, в котором 1781 элемент, селектор
p:nth-child(n)
на моем ноутбуке отрабатывает за 2 мс в jQuery против 1 мс в Prototype. Это большая разница? Как часто вы имеете дело с такими большими документами?Производительности большинства известных фреймворков достаточно для выполнения типичных задач. И самым узким местом в производительности того или иного фреймворка является сам разработчик, который его использует. Например, один человек пытался доказать мне, что jQuery — очень медленная библиотека и ее нельзя использовать. Когда я начал разбираться, увидел вот такой код:
$('.some-item').mouseover(function(){ $('.some-item').addClass('hover'); })
. Небольшая доработка, и код в его понимании стал «реактивным»:var elem = $('.some-item'); elem.mouseover(function(){ elem.addClass('hover'); })
.Выбор фреймворка должен определяться исключительно собственными предпочтениями, удобством использования и средой, в которой работаете (например, для RubyOnRails удобнее использовать Prototype, хотя, возможно, уже есть нормальная поддержка jQuery). Если мне понадобится исключительная производительность на каких-то задачах, я не буду менять jQuery на фреймворк, в котором селекторы быстрее работают; я сделаю решение задачи с использованием стандартных DOM-методов, которое по скорости выиграет у любого фреймворка.
- Как вы относитесь к эмуляции (приватные свойства и методы, наследование и др.) механизмов и паттернов (командер, наблюдатель и др.), пришедших из классического ООП, в JavaScript? Меня лично сильно раздражает, когда, например, человек, ранее программирующий на PHP или Java, начинает лепить из JavaScript привычную ему среду, выдавая это за правильные стандарты кодирования.
-
В целом, разделяю ваше негодование насчет «правильных стандартов». Паттерны проектирования нужно использовать для решения типовых задач, а не потому, что так делают правильные пацаны. У каждого языка есть свои сильные и слабые стороны, которыми в первую очередь нужно научиться пользоваться. Помню, у меня был коллега, у которого стояла задача сделать простейший ховер на одном элементе (добавлять/удалять класс при наведении курсора), при том, что на проекте использовался jQuery. Так вот, вместо того, чтобы просто написать
$('#myelem').hover(...)
, он сделал целый класс с инициализатором, свойствами и методами (а в этих методах все равно использовал jQuery), вынес его в отдельный файл и создал объект из него в другом файле. В итоге задача, решаемая одной строчкой кода, решалась 20-ю строками. На вопрос «зачем это все?» я услышал что-то невнятное насчет ООП, расширяемости (расширяемость ховера?) и инкапсулирования.Мое мнение: нельзя загонять себя в угол стереотипов. Паттерны — это хорошо, но гораздо важнее научиться их правильно и вовремя применять. Любая книга по программированию — не руководство к действию, а пища для ума. Если говорить о JavaScript, то я сейчас крайне редко создаю прототипные классы — все чаще просто генерирую объект во время вызова функции (задолбался всюду писать
this
); не использую синглтон, потому что есть самовызывающиеся функции и так далее. В итоге код получается простым, компактным и модульным (не засоряется глобальная область видимости) — именно то, что нужно для веба.
Добрый день, Сергей.
Хотелось бы узнать подробнее как растягивать фоновую картинку на все окно браузера (см. metrostroy.com).
Спасибо.
P.S. Извиняюсь если написал не в ту категорию.
Еще интересует знак рубля, а именно есть ли какое-нибудь решение на jQuery?
Дело в том, что при применении опубликованных способов в «Техногрете», если знак 12-14px, то результат получается не очень красивый. При увеличении текста черточка смещается и т.д.
Спасибо.
Про такие решения не знаю. У всех текущих решений есть один большой недостаток: зависимость от гарнитуры и размера шрифта. В связи с бурным развитием современных браузеров можно начинать пользоваться специальной гарнитурой и внедрять ее на сайт через CSS
фоновая картинка — наверное, не самый сложный вопрос для этого сайта 🙂
to iSergey:
Отвечу за автора.
Ваш вопрос относится больше к тематике html/css. Информацию о том как реализованы элементы интерфейса отдельного веб-сайта, удобно смотреть используя расширение для FireFox — Firebug.
#back_under {
height:50%;
left:-50%;
position:absolute;
top:50%;
width:200%;
}
iSergey, вопрос очень хороший и мне его часто задают. Ответил в разделе HTML/CSS
Сергей, как вы относитесь к эмуляции (приватные свойства и методы, наследование и др.) механизмов и паттернов (командер, наблюдатель и др.), пришедших из классического ООП, в JavaScript? Меня лично сильно раздражает, когда, например, человек, ранее программирующий на PHP или Java, начинает лепить из JavaScript привычную ему среду, выдавая это за правильные стандарты кодирования. Интересно узнать ваше мнение 🙂
Добрый день.
Подскажите, как проще решить такую задачу? http://h4mpy.ru/q/hover_q.png
Есть некий скрытый блок, который появляется при наведении на заданную область. Есть некий перекрывающий блок, который частично перекрывает появляющийся блок.
Вопрос такой: как лучше задать область наведения, чтобы она никак не пересекалась с блоками?
На всплывающем блоке есть ссылки, интерактивные элементы, соответственно просто перекрыть неким 3 блоком не получится.
Вопрос скорее касается верстки, но может есть какие-то способы задавать области на javascript, и им уже назначать обработчики событий…hover, click. Наподобие map, area в html.
А перекрывающий блок должен быть именно круглым? Я вижу два варианта. Первый — самый простой, — положить сверху прозрачную картинку и применить ей image map. Можно сделать даже две картинки и расположить их слоями на разных уровнях, чтобы выезжающий блок перекрывал одну из карт. Второй способ довольно сложный. Можно заранее просчитать габариты и позицию блоков, а при движении мышки проверять вхождение курсора в эти области. Что-то подобное я делал на сайте «Мукла» (сейчас сайт почему-то не работает): там есть витрина магазина, гда размещаются коробки под разным углом наклона. Соответственно, где-то они пересекаются, поэтому обычный ховер давал неправильный результат. И там я как раз рассчитывал обрамляющий прямоугольник каждого блока и проверял, попадает ли курсор в него.
> h4mpy
В jQuery есть такой событие как mouseenter и mouseleave http://docs.jquery.com/Events/mouseover
Это никак не может помочь?
Здравствуйте Сергей,
Я делаю сайт на основе Друпала по функционалу похожий на Швабрашвабр.
Мне понравилась фишка с разъезжающимся блоком-подсказкой на главной http://shvabrashvabr.ru/. Скопировал себе js. Все подправил.
Но не работает. Точнее работает, но странно. Текст не выезжает, а появляется резко и поверх остального контента.
Если не затруднит, посмотрите пожалуйста: мне кажется для Вас ответ лежит на поверхности. Вот проблемный сайт: http://gorodkozlov.ru
P.S. На самом Швабре и Друпал.Ру прошли мимо моего вопроса.
Заранее спасибо.
Сделайте так, чтобы сначала сайт загружался, тогда посмотрю
Странно, вроде сайт доступен. (Оба)
Сейчас заметил, что если кликнуть в тот момент, когда страница еще не догрузилась до конца, то блок «разъезжается», как положено. Но после окончания загрузки (не)работает как описано выше…
Попробуйте из файла mainpage.js убрать первые 4 строчки
Большое спасибо. Все заработало. =)
Есть сайт (на одном домене) в котором через iframe вставляется некий сервис (разработанный другими людьми) находящийся на другом домене. В сервисе есть необходимость динамически менять высоту iframe’а в зависимости от ситуации (выбрали checkbox — добавились какие-то поля, например).
Когда эти самые люди тестили все у себя на сервере, все прекрасно работало: у них есть функция, которая измеряет текущую высоту контента и через
parent.window
илиwindow.frames[0]
меняет высоту.Теперь же из-за same origin policy это не прокатывает.
У меня из вариантов выхода из ситуации есть только: 1) передавать в location.hash iframe’а параметр со-значением текущей высоты, а мы бы каким-то образом это значение считывали; 2) переделать все на JSONP
Была еще идея загружать все в невидимый div и измерять его высоту, но на сервере используется немало ajax-запросов, поэтому непонятно, что измерять :))
Можешь что-нибудь посоветовать?
Я бы настаивал на том, чтобы сделать небольшой локальный прокси-скрипт, который будет загружать все данные с другого домена. Сам с такой проблемой недавно сталкивался, пока не нашел решения.
сейчас появилось много браузерных онлайн игр, как простых(типа покера и шашек), так и сложнее(разные ММОРПГ например), и очень многие используют флеш. Вопрос, потянет ли js написание такой игры, как в анимации так и в производительности браузера.
Флэш очень хорошо оптимизирован под различные анимации и рисования, поэтому там, конечно же, все будет работать намного быстрее. С другой стороны, если делать какой-нибудь аркадный платформер со спрайтовой графикой, то и на HTML вполне качественную вещь мнжно сделать. Кстати, я когда-то делал тетрис на JavaScript — все вполне шустро работает.
Сергей, почему на сайтах студии (например на http://federationtower.ru/) не практикуется сборка джс-файлов в один и последующая компрессия?
Тогда еще не было вменяемого процесса сборки файлов, да и сильной необходимости в этом не было. Проект все-таки не высоконагруженный. Согласен, что это снижает потребительские качества проекта. У меня сейчас есть готовый Ant-скрипт, который очень легко может собирать файлы проекта; в моем текущем проекте все файлы обязательно подвергаются конкатенации и компрессии.
Как можно обновлять контент в диве и только в диве чтобы не затрагивалась остальная часть сайта, и чтобы адрессная строка участвовала в блуждании по сайту (для работы кнопок назад и вперед и прочей приевшихся вещей.)?
Грузить данные аяксом, менять hash у адресной строки. За готовым решением можете обратиться на http://fullajax.ru
Сергей, здравствуйте.
Пару дней назад мы в очередной раз решили оживить огонь в логотипе на сайте http://ifun.ru/ первый вариант был выполнен аутсорсером на флеше в виде навороченной программы, там и дым и огонь обсчитывались в лучших традициях российской математической школы. Как следствие ролик тормозил.
Вчера я сделал огонь по проще через JavaScript путём последовательной смены 5-и картинок, каждые 80 мс, получилось достаточно живенько.
Код выглядит примерно так:
var logo_frames = new Array();
function logoburner() {
var i = 0;
var original_url = $(‘logo_fire’).src;
for (; i < 5; i++) {
logo_frames[i] = new Image();
logo_frames[i].src = original_url.replace(/[0-9]-/, (i + 1) + ‘-‘);
}
burn(1);
}
function burn(frame) {
$(‘logo_fire’).src = logo_frames[frame — 1].src;
frame++;
if (6 == frame)
frame = 1;
setTimeout(«burn(«+frame+»)», 80);
}
Вообщем-то классический пример из книжки, функция logoburner пускается по onload страницы.
Таким образом я сам себе вчера сделал DOS атаку, несмотря на то, что веб-сервер(Nginx), который раздаёт ставит хедер Expires на сутки вперёд для кадров с огнём, некоторые клиенты не обращают на это внимания, никаким образом не кэшируют картинку и тупо бомбят несчастный веб-сервер запросами через каждые 80 миллисекунд.
Интересно сталкивались ли вы с похожими проблемами при создании анимации через JavaScript и каким образом они решались?
Мне сходу пришло в голову следующее решение: все 5 кадров разместить внутри одной картинки, картинку сделать бэкграундом к DIV и менять позиционирование бэкграунда внутри DIV, нормальное ли это решение?
Судя по всему, проблема возникла в IE. Это давно известный баг, связанный с тем, что любое изменение свойства
background
инициирует новую загрузку картинки с сервера в IE6. Решается такми скриптом:Ну а в целом стоит загнать все эти картинки в один спрайт и просто менять
background-position
. Подробности можете прочитать в статье про спрайты.Спасибо, так и сделал(спрайты).
Хочется сделать большую надпись с наложенным на неё градиентом (возможно «текущим»). Единственное что приходит в голову — использовать векторные маски поверх картинки. Но ума не приложу как сделать векторную маску на основе текста (чтобы можно было миллион этих надписей сделать без использования заранее сгенерированных файлов), с использованием стандартных шрифтов и любых размеров.
Может вы знаете какое то другое решение?
Посмотрите в сторону библиотеки Raphaël, возможно, она сделает то, что вам нужно. Если градиент у вас вертикальный (то есть цвет меняется строго по вертикали), то можно поступить так: во время загрузки страницы делаете десяток дубликатов блоков с текстом, красите в разные цвета и накладываете их друг на друга. Затем с помощью CSS-свойства
clip
показываете несколько пикселей кадого слоя, так, чтобы в итоге получился градиет. Извращение, конечно, зато сработает везде 🙂Раскройте секрет «Десяти причин» (http://job.euroset.ru/candidates/benefits/). Я сделал фильм с помощью jTweener и вашей лекции «Третий способ борьбы…». Ну как бы получилось. Но если прокрутить кадр и уменьшить ширину браузера, левый угол фильма смещается на величину изменения, показывая кусок другого кадра. Как вам удалось этого избежать?
Я смотрел код сайта, знаю про функцию подсчета смещения. Через setInterval прибавлял смещение фильму, если менялась ширина окошка. Работает, но даже при самом малом интервале, изменения идут скачками, особенно ужасными в Опере. Думаю, что все дело в особенностях библиотеки tween в «Десяти причинах» — у ней загадочные аргументы. В чем секрет?
Особых секретов нет. Перед началом анимации считаем, сколько 100% ширина будет в пикселях, потом с помощью анимации смещаем контейнер на это значение влево, а после завершения анимации выставляем это смещение в проценты. Таким образом, после завершения анимации блок смещается на 100% (200, 300, 400…) влево, тем самым решается проблема с отображением соседних кадров при изменении размера окна.
Сергей, что думаете по поводу производительности популярных фреймворков? Какой лучше использовать?
Например, здесь (http://lusever.ru/css-selectors/) prototype уделывает jquery.
Ответ в теле поста
Добрый день, Сергей.
Проблема в следующем — есть сайт на Joomla, есть компонент для менюшек SwMenu. Не могу заставить вылезать созданное в Swmenu подменю в IE (не работает ни на одной версии с шестой по восьмую), жалуется на строку
TransMenu.initialize();
В файрофоксе все работает без нареканий.
Галка «padding ie6 hack» в Swmenu стоит.
Если сделать меню одноуровневым, без выпадающих подменю, то проблема решается. Но меня это не устраивает.
меню вот: http://www.vezem63.ru — в IE не работает, в FF все в норме
Помогите, плз, решить вопрос!
Если ещё актуально, поставьте этот скрипт в незапакованном виде, я посмотрю, в чём может быть дело.
http://www.mooqla.ru/install.php?profile=default
Студия к этой версии сайта не имеет никакого отношения.
не хорошо как-то получается 8(
Здравствуйте Сергей, прошу минутку вашего внимания, нужна ваша помощь!
Я изучаю XHTML и CSS уже больше полугода, вышел на более менее неплохой уровень, теперь хочу двигаться дальше.
Помогите разобраться, что раньше мне нужно начать изучать, JavaScript(немного изучал, более менее имею представление) или XML(никогда не изучал.)
У меня есть много хорошей литературы по обоим предметам, только вот не знаю от куда начать, так как времени уйдет много и чтоб потом не возвращаться назад и не начинать учить что-то из этих языков заново, понимая, что сначала нужно было уделить время другому, я прошу вашей помощи, помогите пожалуйста начинающему!
спасибо!
Вот вам самый замысловатый вопрос! Как в jQuery при помощи плагина tablesort сделать сортировку по полям таблицы, в которой ячейки объеденены при помощи colspan и rowspan. 🙂
с помощью библиотеки jQuery можно сделать водяной знак (Watermark Input Plugin) , как такую штуку реализовать на JavaScript без подключения всяких библиотек? нужен чистый JS
спасибо
Здравствуйте. Не могу найти решение следующей задачи:
У меня есть первая страница к примеру test_1.htm на которой есть ссылка с классом .uroven1 на вторую страницу test_2.htm.
Необходимо чтобы при загрузке страницы test_2.htm в новом окне (использование фреймов исключено) скрипт выполнит любое действие (к примеру выбросит сообщение «WELLCOME») — только после того как «поймёт или отследит» что открытие этой страницы произошло по событию «клик» на ссылку с классом .uroven1 что на странице test_1.htm.
Да и по боьлшей части важней отследить класс ссылки, по которой перешли на новую страницу.
Сам скрипт вояется в jQuery.
Pastorman, самое простое, что приходит в голову (при условии, что не копаться в window.opener), это при открытии окна добавлять ему в location.hash какой-нибудь флаг, с классом, например
#?from=my-class
.Плюс страницы с одного домена могут смотреть в область глобальных переменных друг-друга, т.е. на test_1 создаем глобальную переменную
var sFromClass = '';
и при клике запихиваем в нее что-то$('a').click(function(){ sFromClass = 'blah';window.open(...) });
Из test_2 должна быть видна window.opener.sFromClass.
Проблема то как раз в том, что в моём случае исключено использование window.open(…)
Работа над скриптом ведётся как раз на том сайте на который ссылается мой ник.
Там открытие окна по ссылке должно проводиться дву способами:
1. Вывод через модальное окно -используется избитая тема jquery.fancybox.js (учитывая что в окно подгружается не просто контент а полноценный код html странницы полностью);
2. Вывод через команду «открыть в новом окне».
Исходя из вышеперечисленного, да идея с присвоением глобальных переменных почти спасает, но пока не приходит в голову как же всё таки их использовать.
Посоветовали следующую схему:
$(window).load(function() {
var ref = document.referrer;
if ref /* ??? */
then …
});
в этом случае как вытащить из referrer — класс ссылки по которой перешли на эту страницу?
или как именно здесь воспользоваться этой глобальной переменной?
Как мне кажется решение моей проблемы подразумевает исключительно работу скрипта только на открывшейся странице test_2.htm
Прошу помощи.
Попробуйте ифрэйму присвоить атрибут name с вашим классом и проверить его через window.name. Ещё можно писать в куку имя класса при клике, а при загрузке проверять и очищать её.
Сергей, я в какой-то момент смотрел на Ваш dataRequest из imobilco и помню, что не понял, зачем там callback зовётся два раза: сразу по приезду ответа от сервера callback не вызывается (потому что b=false), а во второй раз уже вызывается. Почему было сделано именно так?
Это сделано для того, чтобы пользователь успел увидеть прелоудер на кнопке (то есть понял, что что-то произошло). Если у пользователя очень быстрый интернет, то после нажатия на кнопку он может не понять, отреагировал сайт или нет. Поэтому ставится принудительная задержка на скрытие прелоудера. С другой стороны, интернет может быть очень медленным и ответ придёт позже, чем закончится задержка. С этой целью ставится специальная проверка, которая определяет, в какой именно момент нужно убрать прелоудер с кнопки: после принудительной задержки или после получения ответа.
Сергей, здравствуйте! Помогите, пожалуйста, решить задачу.
Есть страница со списком:
Очень важный текст
Задача: подгружать содержимое элемента #important-text.
Я попробовал воспользоваться следующей конструкцией:
$(«#target»).load(«/some_page #important-text»);
Но загружается сам элемент #important-text, а мне нужно загружать только его содержимое. Подскажите, пожалуйста, как это сделать?
Спасибо.
Здравствуйте, мне нужно сделать такой эфект на странице, есть логотип на странице сайта и он должен состоять из 3 разных картинок форматом png и как страница загрузилась нужно чтобы эти 3 части логотипа так сказать разьехались в 3 разные стороны и там оставались и чтобы после этого сбоку под появлялось меню в таблице так сказать с задержкой к примеру как страница загрузилась и после 10 сек появилось меню…
Я нашел пример похожего скрипта вот он
Как сделать движение HTML-объекта на Javascript
html, body { height:100%; overflow:hidden; }
* { font:17px serif; color:black; margin:0; padding:0; overflow:visible; }
h1 { margin-bottom:15px; }
input { padding:3px 10px; cursor:pointer; line-height:80%; float:left; margin-right:10px; }
#rocket { position:absolute; left:50%; top:50%; font-size:100px; margin-top:-12px; line-height:25px; }
#info { float:left; height:30px; line-height:30px; color:gray; width:500px; margin:0 10px; }
window.rocketSpeed = 3;
function rocketLauncher( obj, rocket )
{
rocket = (typeof rocket == ‘object’) ? rocket : document.getElementById( rocket );
rocket.params = {
direction: { ‘x’: 1, ‘y’: 1},
borders: {
‘x’: document.body.clientWidth — rocket.offsetWidth,
‘y’: document.body.clientHeight — rocket.offsetHeight
}
}
obj.flying = !obj.flying ? true : false;
obj.default_value = ! obj.default_value ? obj.value : obj.default_value ;
if( obj.flying )
{
// устанавливаем первоначальные значения позиции объекта
if( !rocket.style.left ) rocket.style.left = rocket.offsetLeft + ‘px’;
if( !rocket.style.top ) rocket.style.top = rocket.offsetTop + ‘px’;
obj.rocket = setInterval(function()
{
// смещение положение объекта
posX = parseInt( rocket.style.left ) + rocketSpeed * rocket.params.direction.x;
posY = parseInt( rocket.style.top ) + rocketSpeed * rocket.params.direction.y;
rocket.style.left = posX + ‘px’;
rocket.style.top = posY + ‘px’;
// изменение направления движения при достижении границ окна браузера
if( posX rocket.params.borders.x ) rocket.params.direction.x *= 1;
if( posY rocket.params.borders.y ) rocket.params.direction.y *= 0;
// информационное окно
document.getElementById(‘info’).innerHTML = ‘Текущая позиция — (X: ‘ + posX +’, Y: ‘+ posY +’), Скорость: ‘ + rocketSpeed;
}, 10);
obj.value = ‘Остановить’;
}
else {
// остановка движения
clearInterval( obj.rocket );
obj.value = obj.default_value;
}
}
Как сделать движение HTML-объекта на Javascript
И мне нужно чтобы 3 картинки такие разлетались в отпределенные места окоординаты на странице и там остовались
ой вот он
Как сделать движение HTML-объекта на Javascript
html, body { height:100%; overflow:hidden; }
* { font:17px serif; color:black; margin:0; padding:0; overflow:visible; }
h1 { margin-bottom:15px; }
input { padding:3px 10px; cursor:pointer; line-height:80%; float:left; margin-right:10px; }
#rocket { position:absolute; left:50%; top:50%; font-size:100px; margin-top:-12px; line-height:25px; }
#info { float:left; height:30px; line-height:30px; color:gray; width:500px; margin:0 10px; }
window.rocketSpeed = 3;
function rocketLauncher( obj, rocket )
{
rocket = (typeof rocket == ‘object’) ? rocket : document.getElementById( rocket );
rocket.params = {
direction: { ‘x’: 1, ‘y’: 1},
borders: {
‘x’: document.body.clientWidth — rocket.offsetWidth,
‘y’: document.body.clientHeight — rocket.offsetHeight
}
}
obj.flying = !obj.flying ? true : false;
obj.default_value = ! obj.default_value ? obj.value : obj.default_value ;
if( obj.flying )
{
// устанавливаем первоначальные значения позиции объекта
if( !rocket.style.left ) rocket.style.left = rocket.offsetLeft + ‘px’;
if( !rocket.style.top ) rocket.style.top = rocket.offsetTop + ‘px’;
obj.rocket = setInterval(function()
{
// смещение положение объекта
posX = parseInt( rocket.style.left ) + rocketSpeed * rocket.params.direction.x;
posY = parseInt( rocket.style.top ) + rocketSpeed * rocket.params.direction.y;
rocket.style.left = posX + ‘px’;
rocket.style.top = posY + ‘px’;
// изменение направления движения при достижении границ окна браузера
if( posX rocket.params.borders.x ) rocket.params.direction.x *= 1;
if( posY rocket.params.borders.y ) rocket.params.direction.y *= 0;
// информационное окно
document.getElementById(‘info’).innerHTML = ‘Текущая позиция — (X: ‘ + posX +’, Y: ‘+ posY +’), Скорость: ‘ + rocketSpeed;
}, 10);
obj.value = ‘Остановить’;
}
else {
// остановка движения
clearInterval( obj.rocket );
obj.value = obj.default_value;
}
}
Как сделать движение HTML-объекта на Javascript
2Владимир
Jquery->animate
Сергей, вам попадался флешовый mp3-плейер, который был бы полностью невидим и полностью рулился бы яваскриптом? Я гуглил полдня, но не нашёл 🙁
Alexander, http://www.schillmania.com/projects/soundmanager2/
Сергей, не подскажите, почему ни в хроме, ни в сафари не работает этот код:
html:
<img src=»img/round.png» width=»50″ height=»50″ id=»round» alt=»Hello» />
<canvas id=»first» width=»150px» height=»150px»>Это канвас</canvas>
js:
var canvas = document.getElementById(’first’),
i = document.getElementById(’round’),
ctx = canvas.getContext(’2d’);
ctx.drawImage(i,0,0,50,50);
Забыл написать, что в Опере и Файерфоксе всё нормально
Владислав Шкодин, проверьте следующее:
<canvas>
атрибутыwidth
иheight
полжны быть числами (не нужен px)Да, спасибо, так всё работает. И ещё один вопрос: скажите, у элемента canvas есть z-index? У меня не получилось поставить его ниже других элементов.
Ой, видимо я где-то ступил. Всё нормально у него с z-index. Можете потереть этот вопрос.
Добрый день Сергей. Я совсем недавно начал осваивать анимацию. Использую jQuery и метод .animate() (над свойствами стилей left и opacity). Анимация шустро и плавно отображается в chrome, opera 10.53, ie 6/7. Но в лисе (версия 3.6.6) проблемы — анимаци тупит и не плавная. Здесь пример: http://host.poskachey.com/ex/anim.
Я также пробовал сделать такую же анимацию на чистом js — и результат тот же. Не подскажите в чем проблема.
http://s002.radikal.ru/i199/1008/d9/527b1d0372b4.jpg
Сергей, скажите, как на канвасе определить координаты синей точки? Мне нужно провести линию из левого верхнего угла квадрата в эту точку.
В смысле определить? Проанализировать изображение или математически высчитать точку пересечения двух линий?
Ну, мне нужно, чтобы конечная точка линии перемещалась в зависимости от положения мыши, но не выходила за пределы квадрата. Т.е. исходя из координат курсора нужно как-то высчитывать координаты пересечения этой линии со стороной квадрата. Видимо наверное математически.
Ну значит надо нагуглить алгоритм поиска пересечения двух линий и всё
Сергей, скажите пожалуйста, в чём разница между window.getComputedStyle() и document.defaultView.getComputedStyle()? Не могу понять почему иногда одно заменяют другим.
Разницы нет, технически
window === document.defaultView
. Но возможна ситуация, чтоdocument
(то есть объект классаHTMLDocument
) принадлежит другому документу, а не тому, с которым работаем. Например, загрузили аяксом внешний XML-файл. В этом случае, если захотите получить CSS-свойства элемента из этого внешнего документа черезwindow.getComputedStyle()
получите ошибку.Ясно. Спасибо. А в случае с айФреймом тоже ошибку получу?
Да
Сергей, поясните пожалуйста как работает эта функция, а именно, почему i всегда увеличивается, а не обнуляется?
function counter() {
var i = 0;
counter = function() {
return i++;
}
return counter();
}
Это называется «замыкание»: http://javascript.ru/basic/closure
Здравствуйте Сергей. Около года назад один человек побывавший на вашей конференции порекомендовал мне глянуть один ваш продукт, который мог скруглять, обрезать (под разными углами) дивы, картинки и прочее. Это не была библиотека Racon, это было что-то другое. Но спустя время найти это совсем не получается. Называлось оно еще очень заковыристо)
Буду очень признателен, если напомните. Заранее спасибо
Меня поправили, что это была РИТ 2008 WebHiTech.
Андрей, библиотека называется ictinus.
Ссылка вверху этой страницы, справа.
Здравствуйте. Делаю меню на jquery. Сергей, подскажите пожалуйста, как сделать чтобы родительские ul скрывались не моментально а через некоторое время и только если на них не наведена мышь? Пробовал использовать setTimeout, не получается.
Код на данный момент:
$.fn.submenu = function() {
$(this).has(«li»).hover(function() {
if(!lihover) {
lihover = true;
$(this).children(«ul»).animate({width:»show»}, «fast», function() {
lihover = false
})
}
}, function() {
if(!lihover) {
$(this).children(«ul»).animate({width:»hide»}, «fast»)
}
}).click(function(){return false});
};
Лучше так: http://skysail.ru/code.js
Баг в Zen Coding. В сафари на маке выделение строки CMD+L выделяет всю строку без последнего символа.
Нужно управлять состоянием меню: после того, как увели мышь выставить какой-нибудь флажок в
true
и запустить таймер. Если во время срабатывания таймера флажок всё ещёtrue
, то запустить анимациюЗдравствуйте, Сергей.
В -е с текстом фоном идет полупрозрачный пнг. При срабатывании функции плавного изменения прозрачности fadeTo, ИЕ(7,8) ухудшает качество фонового изображения, теряются полупрозрачные пиксели, и оно становиться похоже на гиф. И у текста вокруг букв появляются неприятные серые артефакты.
Может вы сталкивались с похожим? Спасибо.
В спане с текстом
Сергей, у меня следующая проблема: есть меню, довольно большое по ширине. Оно должно быть зафиксировано сверху справа на странице. Проблема в том, что если поставить ему position: fixed, то при сжатии окна оно будет заползать на контент. Тогда я попытался сделать вертикальный псевдо-fixed с помощью события scroll, но в этом случае меню начинает дико дрожать при прокрутке. Вопрос: есть ли какой-то хороший способ решить эту проблему, лучше через css, но можно и через js.
Катя, посмотрите тут: http://chikuyonok.ru/2009/02/ie-filters/
Правда, в IE8, скорее всего, не поможет
Владислав, не понял задачу. На какой контент что заползает?
Очень просто: контент слева, меню справа. Меню зафиксированно. Если изменять ширину окна (сжимать), то (т.к. position: fixed) в какой-то момент меню начнет заползать на контент. Т.е. по сути мне нужно чтобы меню было fixed по вертикали. Оставалось на месте при вертикальной прокрутке. Я пробовал два способа: эмулировал вертикальный fixed через событие scroll, но в этом случае меню при прокрутке начинает дрожать, и менял скриптом у меню position: fixed, на position: absolute при достижении минимальной ширины. Но оба способа не устраивают: первый из-за дрожания, второй из-за того, что используется событие resize, которое жрёт ресурсы сильно.
И второе решение опять же не устраивает тем, что при минимальной ширине окна, меню начнет скролиться вместе с контентом.
Ресайз не жрёт ресурсы, просто в некоторых браузерах он отрабатывает не так быстро, как хотелось бы.
Задачу всё равно до конца не понимаю, обычно спрашивающие предоставляют макет, чтобы было ясно, что к чему. Но можно попробовать эмулировать position: fixed http://www.artlebedev.ru/tools/technogrette/html/emulate-fixed/
http://wip.acdstudio.ru/hotshotfilms/ — вот пример. сжимайте окно. меню наползает на контент.
В этом случае необязательно делать глобальный скроллинг, можно перенести его на отдельный элемент, как указано в ссылке выше
Сергей, я вот только не совсем понимаю, как данный способ эмуляции position: fixed позволит мне ограничить передвижение меню по горизонтали таким образом, чтобы оно не залезало на область контента.
Помогите решить задачку… (Написать функцию которая рисует таблицу. Пользователь с клавиатуры вводит количество строк и количество колонок.)
Здравствйте, хотел прикрепить ваш скрипт rocon к скрипту модуля thickbox для друпал. работать его удалось заставить только на опере, что печально. Действовал — добавил после всех append(’див с ид=TB_window ‘) строку rocon.update($(”#TB_window”).get(0)); — что видимо не свовсем верно. можете помочь разобраться в проблеме?
Здравствуйте. Возможно ли как-то остановить стандартное действие браузера (например сброс фокуса с ссылки) на событие onmousedown на другом оъекте в Ie<=8?
есть кто живой?
Здравствуйте Сергей!
В своей статье в Техногрете «Eclipse: редактирование JavaScript в Spket IDE» был приведён файл документации для jquery в формате jsdoc, но только для jquery версии 1.2.3 — не обновляли ли Вы этот файл в соответствии с изменениями jquery? Если да, то не поделитесь?
Спасибо.
Хочу заметить, что лучше использовать префикс $, для обозначении объектов jquery.
var $elem = $(‘.some-item’);
Привет.
Как определить, картинка находится в кэше или ее следует загрузить?
Пытаюсь сделать галерею с загрузкой по клику, алгоритм примерно таков:
1) показываем лоадер
2) ждем загрузки картинки через .load(function())
3) скрываем лоадер
Хотел бы не показывать лоадер для кэшированных картинок. Как это можно реализовать?
Заранее спасибо.
Игорь, я скоро напишу пост про мою обновлённую среду разработки (в частности, про Eclipse JSDT), там будет пара ссылок.
Ruby, получить информацию о налии картинки в кэше вряд ли получится, но я эту проблему решал так: прелоудер показывал не сразу, а через небольшой таймаут. Если картинка в кэше или интернет быстрый, то прелоудера не будет, а если превышен лимит ожидания, то показываю прелоудер как минимум на секунду, чтобы не было неприятных морганий. Пример: http://federationtower.ru/tower/offices/
Сергей,
сталкивались ли вы с необходимостью вращать блоки с изображениями/текстом/слоями/ссылками и если да, то какой способ использовали?
Я смог найти svg, canvas и css3 transform: rotate. Для IE фильтр.
Александр, по-моему этих способов вполне достаточно, чтобы сделать вращение текста во всех браузерах. Самый правильный — CSS Transforms, можно ещё глянуть SVG + foreign object,
Здравствуйте Сергей!
Хочу спросить следующее, про скорость рендеринга страницы используя jQuery селекторы, сначала опишу на примере css, используя селекторы такого плана например ul#menu li a{} которые обрабатываются справа налево.. и можно уменьшить время рендеринга если цеплять классы, на ссылки и css привязывать используя уже классы вместо ul#menu li a{} селектора. Уважаю вашу точку зрения, что если даже элементов около 1000 то особо видимого прироста производительности можно не ждать, даже в ИЕ6.
Но вопрос мой вот в чем. Если использовать такие селекторы в jQuery(«ul#menu li a»), то как в этой ситуации по производительности, по аналогии со случаем CSS. Как это происходит в jQuery селекторах?
Заранее спасибо!
Как правильно реализовать слабое связывание произвольных не DOM объектов? jQuery, как я понял, умеет правильно работать только с DOM элементами, а на остальные bind и trigger по-хорошему привязать не удаётся.
Студийный способ от 2007го года я знаю и пользуюсь им. Но ведь, наверняка, такой функционал должен быть уже реализован в каком-то фреймворке и использовать самописные модули некрасиво.
Спасибо!
Виталий, jQuery работает точно так же, как и браузеры: ищет элементы справа налево. То есть в вашем примере сначала найдутся все элементы
a
, потом отфильтруются те, у которых есть родительli
и т.д. Лучше не писать глубоких селекторов или, как вариант оптимизации, искать вот так:$('#menu').find('li').find('a');
. Это должно быстрее работать в старых браузерах.Антон, для слабого связывания я использую библиотеку js-signals. Может, она не самая производительная, но для моих проектов вполне хватает.
Привет Сергей! Подскажи, чем лучше сделать меню «дерево», jquery плагин какой или еще как?
Сергей! Скажите, как Вы относитесь к проекту JSLint — оцениваете ли свой собственный код через призму его рекомендаций и насколько на Ваш взгляд применение и ориентация команды разработчиков на следование им может поспособствовать повышению качества их кода с т.з. удобства задач разбора кода, переформатирования кода автоматизированными средствами и т.д.? Случалось ли Вам работать в проектах, где жёстким требованием при commit`е кода было бы выставлено его прохождение через JSLint?
Здравствуйте Сергей. У вас есть замечательная статья «Производительность браузеров в зависимости от верстки», в которой вы использовали счетчик FPS, который прекращал работать после окончания анимации. Возможно ли использовать подобный счетчик постоянно? Просто я посчитал, что это неплохой способ анализировать так сказать «оптимальность» верстки. Чтобы можно было узнать насколько каждый эффект (скрипт, картинка, анимация и т.д.) притормаживат браузер. Или просто скажите, как вы решаете такие проблемы. Очень интересует эта тема. Заранее большое спасибо.
Подскажите пожалуйста.
Вопрос связан с библиотекой Raphael
var paper = Raphael(ph, 600, 600);
var shapeA = paper.path(«M 300 10 L 400 10 L 600 500 L 500 500 L 400 300 L 350 300 L 250 500 L 150 500 Z»);
Подскажите пожалуйста, каким способом я погу получить любые 5 координат точек лежащих ВНУТРИ фигуры shapeA ?
Здравствуйте Сергей.
Подскажите пожалуйста, как ПРАВИЛЬНЕЕ реализовать.
Есть земля, в нее попадает снаряд, который разрушает(делает в ней впадину/углубление), все зависит от попавшего в нее снаряда + кроме впадины нужно реализовать осыпание земли.
Я думаю это реализовать следующим способом:
Имеем 2 слоя, один под другим. Верхний слой — картинка земли или гор, второй слой — канвас, который и будет разрушаться. Далее я высчитываю координаты конечной точки снаряда. Сам снаряд имеет радиус поражения, после того, как снаряд достиг конечной точки, я стираю первый слой — тот который канвас — имитирую взрыв(не знаю, как правильнее имитировать, гиф-картинку точно не хочу использовать, скорее всего буду спрайтами делать анимацию) и во время этого взрыва подменяю верхнюю картинку на новую с готовой впадиной.
Физику я уже сделал, больше всего меня интересует реализация впадины в земле. Как правильно это реализовать подскажите пожалуйста?
Сергей, хотелось бы увидеть цветовую схему которой вы пользуетесь в IDE, можно в скринах, это возможно? 🙂
Никита, сейчас я пользуюсь стандартной в JSDT цветовой схемой. Вряд ли смогу найти старую схему раскраски
Сергей, а могли бы вы как-нибудь рассказать про реализацию функционала нестандартных маркеров гуглокарты на bigbuzzy?
Сергей здравствуйте! если у вас есть интересные уроки и различные решения для веб програмирования …то я с огромным удовольствием прочитаю их — если еще нет то попробуйте их разместить на сайте!
Здравствуйте Сергей! Я новичок в JS, помогите пожалуйста, не очень понимаю логику рекурсивных функций в JavaScript.
Вот например, не могли бы вы обьяснить как работает данная функция:
function power(base, exponent) {
if (exponent == 0)
return 1;
else
return base * power(base, exponent — 1);
}
power(5, 3);
Привет. А скажите как вы замеряете скорость выполнения скриптов? Например, что будет быстрее создать на лету два новых элемента, или один создать, а второй клонировать. Как такие штуки замерять?
Например, какой код при использовании jQuery будет менее ресурсоемким?
var $div = $(»);
var $divInner = $(»).appendTo($div);
___________________________________________
var $div = $(»);
var $divInner = $div.clone().appendTo($div);
Для измерения производительности существуют инструменты, встроенные в браузер: http://chikuyonok.ru/2010/11/optimization-story/
В вашем случае нельзя сказать, какой из методов будет быстрее, так как сильно зависит от браузера и от специфики задачи. Обычно клонирование гораздо быстрее, но в данном конкретном случае вы используете реализацию jQuery, которая, помимо всего прочего, может наследовать содержимое
data
и события с элемента-донора. Так что всё зависит от конкретной задачи.где можно посмотреть видео урок