Какой скрипт сдвинет спрайт влево на 10 пикселей
Существует множество JavaScript-свойств, которые позволяют считывать информацию об элементе: ширину, высоту и другие геометрические характеристики. В этой главе мы будем называть их «метрики».
Они часто требуются, когда нам нужно передвигать или позиционировать элементы с помощью JavaScript.
clientTop/Left
Пойдём дальше. Внутри элемента у нас рамки (border).
Для них есть свойства-метрики clientTop и clientLeft .
В нашем примере:
- clientLeft = 25 – ширина левой рамки
- clientTop = 25 – ширина верхней рамки
…Но на самом деле эти свойства – вовсе не ширины рамок, а отступы внутренней части элемента от внешней.
В чём же разница?
Она возникает, когда документ располагается справа налево (операционная система на арабском языке или иврите). Полоса прокрутки в этом случае находится слева, и тогда свойство clientLeft включает в себя ещё и ширину полосы прокрутки.
В этом случае clientLeft будет равно 25 , но с прокруткой – 25 + 16 = 41 .
Вот соответствующий пример на иврите:
scrollLeft/scrollTop
Свойства scrollLeft/scrollTop – ширина/высота невидимой, прокрученной в данный момент, части элемента слева и сверху.
Следующая иллюстрация показывает значения scrollHeight и scrollTop для блока с вертикальной прокруткой.
Другими словами, свойство scrollTop – это «сколько уже прокручено вверх».
В отличие от большинства свойств, которые доступны только для чтения, значения scrollLeft/scrollTop можно изменять, и браузер выполнит прокрутку элемента.
При клике на следующий элемент будет выполняться код elem.scrollTop += 10 . Поэтому он будет прокручиваться на 10px вниз.
Установка значения scrollTop на 0 или Infinity прокрутит элемент в самый верх/низ соответственно.
offsetParent, offsetLeft/Top
Эти свойства редко используются, но так как они являются «самыми внешними» метриками, мы начнём с них.
В свойстве offsetParent находится предок элемента, который используется внутри браузера для вычисления координат при рендеринге.
То есть, ближайший предок, который удовлетворяет следующим условиям:
Свойства offsetLeft/offsetTop содержат координаты x/y относительно верхнего левого угла offsetParent .
В примере ниже внутренний имеет элемент в качестве offsetParent , а свойства offsetLeft/offsetTop являются сдвигами относительно верхнего левого угла ( 180 ):
Существует несколько ситуаций, когда offsetParent равно null :
- Для скрытых элементов (с CSS-свойством display:none или когда его нет в документе).
- Для элементов и .
- Для элементов с position:fixed .
Шаг 4. Сдвинуть спрайт
Сдвиг фона background-position позволяет выбирать, какую именно часть спрайта видно.
В спрайте icons.jpg изображения объединены так, что сдвиг на 16px покажет следующую иконку:
- В спрайт могут объединяться изображения разных размеров, т.е. сдвиг может быть любым.
- Сдвигать можно и по горизонтали и по вертикали.
Координаты
Для сдвига можно использовать координаты:
- top – сдвиг от «обычной» верхней границы
- bottom – сдвиг от нижней границы
- left – сдвиг слева
- right – сдвиг справа
Не будут работать одновременно указанные top и bottom , left и right . Нужно использовать только одну границу из каждой пары.
Возможны отрицательные координаты и координаты, использующие другие единицы измерения. Например, left: 10% сдвинет элемент на 10% его ширины вправо, а left: -10% – влево. При этом часть элемента может оказаться за границей окна:
Свойства left/top не будут работать для position:static . Если их всё же поставить, браузер их проигнорирует. Эти свойства предназначены для работы только с позиционированными элементами.
position: static
Статическое позиционирование производится по умолчанию, в том случае, если свойство position не указано.
Его можно также явно указать через CSS-свойство:
Такая запись встречается редко и используется для переопределения других значений position .
Здесь и далее, для примеров мы будем использовать следующий документ:
В этом документе сейчас все элементы отпозиционированы статически, то есть никак.
Элемент с position: static ещё называют не позиционированным.
position: absolute
Абсолютное позиционирование делает две вещи:
- Элемент исчезает с того места, где он должен быть и позиционируется заново. Остальные элементы, располагаются так, как будто этого элемента никогда не было.
- Координаты top/bottom/left/right для нового местоположения отсчитываются от ближайшего позиционированного родителя, т.е. родителя с позиционированием, отличным от static . Если такого родителя нет – то относительно документа.
- Ширина элемента с position: absolute устанавливается по содержимому. Детали алгоритма вычисления ширины описаны в стандарте.
- Элемент получает display:block , который перекрывает почти все возможные display (см. Relationships between „display“, „position“, and „float“).
Например, отпозиционируем заголовок в правом-верхнем углу документа:
Важное отличие от relative : так как элемент удаляется со своего обычного места, то элементы под ним сдвигаются, занимая освободившееся пространство. Это видно в примере выше: строки идут одна за другой.
Так как при position:absolute размер блока устанавливается по содержимому, то широкий Заголовок «съёжился» до прямоугольника в углу.
Иногда бывает нужно поменять элементу position на absolute , но так, чтобы элементы вокруг не сдвигались. Как правило, это делают, меняя соседей – добавляют margin/padding или вставляют в документ пустой элемент с такими же размерами.
В абсолютно позиционированном элементе можно одновременно задавать противоположные границы.
clientWidth/Height
Эти свойства – размер области внутри рамок элемента.
Они включают в себя ширину области содержимого вместе с внутренними отступами padding , но без прокрутки:
На рисунке выше посмотрим вначале на высоту clientHeight .
Горизонтальной прокрутки нет, так что это в точности то, что внутри рамок: CSS-высота 200px плюс верхние и нижние внутренние отступы ( 2 * 20px ), итого 240px .
Теперь clientWidth – ширина содержимого здесь равна не 300px , а 284px , т.к. 16px отведено для полосы прокрутки. Таким образом: 284px плюс левый и правый отступы – всего 324px .
Если нет внутренних отступов padding , то clientWidth/Height в точности равны размеру области содержимого внутри рамок за вычетом полосы прокрутки (если она есть).
Поэтому в тех случаях, когда мы точно знаем, что отступов нет, можно использовать clientWidth/clientHeight для получения размеров внутренней области содержимого.
Задачи
Шаг 1. Использовать background
Первый шаг к объединению изображений в «спрайт» – показывать их через background ., а не через тег IMG .
В данном случае он уже сделан. Стиль для дерева:
3 ответа 3
Свойство style DOM-объекта элемента, является интерфейсом доступа к его индивидуальным, инлайн-стилям.
То есть, к тем стилям, что изначально прописаны инлайном в атрибуте style в разметке элемента. Например:
Обрати внимание, что в примере style.top содержит "ничего", пустую строку - хотя в общей CSS прописано значение 50px . Это та же "проблема", что и в вопросе. Так происходит как раз потому, что style ссылается на инлайновые стили самого элемента, а не на подходящее ему правило в CSSOM (объектной модели "общих" стилей).
Вариантом решения задачи из вопроса, может быть такое выражение:
Таким образом, если инлайном стилевое свойство не задано - вместо его значения будет подставлено 0 , оператором || (логическое ИЛИ).
А для получения вычисленных (computed) стилей элемента, следует использовать глобальный метод getComputedStyle - он возвращает живой объект (то есть, значения в нем обновляются динамически):
Односложные свойства доступны через точку, как показано в примере. Для чтения из вычисленных стилей тех свойств, которые состоят из нескольких слов через дефис (например, box-shadow ), можно применять нотации compStyles['box-shadow'] , compStyles.boxShadow , или использовать специально предназначенный для этого метод getPropertyValue :
Вычисленные стили доступны только для чтения.
Для неинициализированных явно css-свойств, вычисленное значение будет не пустой строкой, а либо стандартным значением по-умолчанию, либо значением из встроенных стилей браузера (это обязательно следует помнить).
Я хочу сдвинуть изображение на пиксели x , сохранив исходную форму. Я пробовал следующее:
Но проблема с описанным выше подходом заключается в том, что исходная форма изображения теряется. Как я мог сохранить исходную форму при смещении изображения на x пикселя влево.
@zindarod Я проверил это, но не мог понять, как его использовать.
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ.
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это.
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и.
Найти размер прокрутки снизу
Свойство elem.scrollTop содержит размер прокрученной области при отсчёте сверху. А как подсчитать размер прокрутки снизу (назовём его scrollBottom )?
Напишите соответствующее выражение для произвольного элемента elem .
P.S. Проверьте: если прокрутки нет вообще или элемент полностью прокручен – оно должно давать 0 .
Другими словами: (вся высота) минус (часть, прокрученная сверху) минус (видимая часть) – результат в точности соответствует размеру прокрутки снизу.
Пишу страницу HTML. Код страницы, исполняемый js-код и код стилей в трех разных папках:
- site.html
- script/script.js
- res/style.css
В HTML присутствуют два элемента:
С помощью кода js хочу при нажатии кнопки сдвигать данное изображение вправо, увеличивая параметр left родительского элемента div. Непосредственно код:
Данная функция была взята из интернета, разобрана на мельчайшие частицы, но заставить ее работать я не смог. Из того, что я понял, square и square.style являются [object HTMLDivElement] и [object CSSStyleDeclaration] соответственно, однако square.style.left является пустым значением и div не сдвигается.
попробуйте либо aбсолютное позиционирование, либо меняйте у элемента square.style.transform='translate(30px,0);
Метрики
Вот общая картина с геометрическими свойствами:
Значениями свойств являются числа, подразумевается, что они в пикселях.
Давайте начнём исследовать, начиная снаружи элемента.
Итого
У элементов есть следующие геометрические свойства (метрики):
- offsetParent – ближайший CSS-позиционированный родитель или ближайший td , th , table , body .
- offsetLeft/offsetTop – позиция в пикселях верхнего левого угла относительно offsetParent .
- offsetWidth/offsetHeight – «внешняя» ширина/высота элемента, включая рамки.
- clientLeft/clientTop – расстояние от верхнего левого внешнего угла до внутренного. Для операционных систем с ориентацией слева-направо эти свойства равны ширинам левой/верхней рамки. Если язык ОС таков, что ориентация справа налево, так что вертикальная полоса прокрутки находится не справа, а слева, то clientLeft включает в своё значение её ширину.
- clientWidth/clientHeight – ширина/высота содержимого вместе с внутренними отступами padding , но без полосы прокрутки.
- scrollWidth/scrollHeight – ширины/высота содержимого, аналогично clientWidth/Height , но учитывают прокрученную, невидимую область элемента.
- scrollLeft/scrollTop – ширина/высота прокрученной сверху части элемента, считается от верхнего левого угла.
Все свойства доступны только для чтения, кроме scrollLeft/scrollTop , изменение которых заставляет браузер прокручивать элемент.
Шаг 2. Объединить изображения
Составим из нескольких изображений одно icons.jpg , расположив их, например, по вертикали.
Из , и получится одна картинка:
Ответы 1
В обработке изображений эта вещь называется переводом изображения.
Но мы хотим что-то вроде этого:
Перевод в основном означает, что мы смещаем изображение, добавляя/вычитая координаты X и Y. Для этого нам нужно создать матрицу преобразования, как показано ниже:
Здесь значения tx и ty являются значениями перемещения по осям X и Y, то есть изображение будет перемещено на X единиц вправо и на Y единиц вниз.
Итак, как только мы создадим подобную матрицу, мы можем применить функцию warpAffine к нашему изображению.
Третий аргумент в warpAffine относится к количеству строк и столбцов в результирующем изображении. Поскольку количество строк и столбцов такое же, как у исходного изображения, результирующее изображение будет обрезано. Причина этого в том, что у нас не хватило места в выводе, когда мы применили матрицу перевода. Чтобы избежать обрезки, мы можем сделать что-то вроде этого:
И это приведет к:
Помните, что размер этого изображения изменяется при загрузке сюда, не волнуйтесь, это ваш желаемый результат.
Более того, если мы хотим переместить изображение в середину большего кадра изображения; мы можем сделать что-то подобное, выполнив следующее:
CSS-спрайт – способ объединить много изображений в одно, чтобы:
- Сократить количество обращений к серверу.
- Загрузить несколько изображений сразу, включая те, которые понадобятся в будущем.
- Если у изображений сходная палитра, то объединённое изображение будет меньше по размеру, чем совокупность исходных картинок.
Рассмотрим, как это работает, на примере дерева:
Сейчас «плюс», «минус» и «статья» – три отдельных изображения. Объединим их в спрайт.
position: relative
Относительное позиционирование сдвигает элемент относительно его обычного положения.
Для того, чтобы применить относительное позиционирование, необходимо указать элементу CSS-свойство position: relative и координаты left/right/top/bottom .
Этот стиль сдвинет элемент на 10 пикселей относительно обычной позиции по вертикали:
Итого
Решение лучше всего принимать, исходя из принципов семантической вёрстки.
Задайте вопрос – что здесь делает изображение? Является ли оно самостоятельным элементом страницы (фотография, аватар посетителя), или же оформляет что-либо (иконка узла дерева)?
Элемент IMG следует использовать в первом случае, а для оформления у нас есть CSS.
- Сократить количество обращений к серверу.
- Загрузить несколько изображений сразу, включая те, которые понадобятся в будущем.
- Если у изображений сходная палитра, то объединённое изображение будет меньше по размеру, чем совокупность исходных картинок.
Если фоновое изображение нужно повторять по горизонтали или вертикали, то спрайты тоже подойдут – изображения в них нужно располагать в этом случае так, чтобы при повторении не были видны соседи, т.е., соответственно, вертикально или горизонтально, но не «решёткой».
Далее мы встретимся со спрайтами при создании интерфейсов, чтобы кнопка при наведении меняла своё изображение. Один спрайт будет содержать все состояния кнопки, а переключение внешнего вида – осуществляться при помощи сдвига background-position .
Для автоматизированной сборки спрайтов используются специальные инструменты, например SmartSprites.
Свойство position позволяет сдвигать элемент со своего обычного места. Цель этой главы – не только напомнить, как оно работает, но и разобрать ряд частых заблуждений и граблей.
Не стоит брать width/height из CSS
Мы рассмотрели метрики, которые есть у DOM-элементов, и которые можно использовать для получения различных высот, ширин и прочих расстояний.
Но как мы знаем из главы Стили и классы, CSS-высоту и ширину можно извлечь, используя getComputedStyle .
Так почему бы не получать, к примеру, ширину элемента при помощи getComputedStyle , вот так?
Почему мы должны использовать свойства-метрики вместо этого? На то есть две причины:
Во-первых, CSS-свойства width/height зависят от другого свойства – box-sizing , которое определяет, «что такое», собственно, эти CSS-ширина и высота. Получается, что изменение box-sizing , к примеру, для более удобной вёрстки, сломает такой JavaScript.
Во-вторых, CSS свойства width/height могут быть равны auto , например, для инлайнового элемента:
Конечно, с точки зрения CSS width:auto – совершенно нормально, но нам-то в JavaScript нужен конкретный размер в px , который мы могли бы использовать для вычислений. Получается, что в данном случае ширина из CSS вообще бесполезна.
Есть и ещё одна причина: полоса прокрутки. Бывает, без полосы прокрутки код работает прекрасно, но стоит ей появиться, как начинают проявляться баги. Так происходит потому, что полоса прокрутки «отъедает» место от области внутреннего содержимого в некоторых браузерах. Таким образом, реальная ширина содержимого меньше CSS-ширины. Как раз это и учитывают свойства clientWidth/clientHeight .
…Но с getComputedStyle(elem).width ситуация иная. Некоторые браузеры (например, Chrome) возвращают реальную внутреннюю ширину с вычетом ширины полосы прокрутки, а некоторые (например, Firefox) – именно CSS-свойство (игнорируя полосу прокрутки). Эти кроссбраузерные отличия – ещё один повод не использовать getComputedStyle , а использовать свойства-метрики.
Если ваш браузер показывает полосу прокрутки (например, под Windows почти все браузеры так делают), то вы можете протестировать это сами, нажав на кнопку в ифрейме ниже.
У элемента с текстом в стилях указано CSS-свойство width:300px .
На ОС Windows браузеры Firefox, Chrome и Edge резервируют место для полосы прокрутки. Но Firefox отображает 300px , в то время как Chrome и Edge – меньше. Это из-за того, что Firefox возвращает именно CSS-ширину, а остальные браузеры – «реальную» ширину за вычетом прокрутки.
Обратите внимание: описанные различия касаются только чтения свойства getComputedStyle(. ).width из JavaScript, визуальное отображение корректно в обоих случаях.
scrollWidth/Height
Эти свойства – как clientWidth/clientHeight , но также включают в себя прокрученную (которую не видно) часть элемента.
На рисунке выше:
- scrollHeight = 723 – полная внутренняя высота, включая прокрученную область.
- scrollWidth = 324 – полная внутренняя ширина, в данном случае прокрутки нет, поэтому она равна clientWidth .
Эти свойства можно использовать, чтобы «распахнуть» элемент на всю ширину/высоту.
Нажмите на кнопку, чтобы распахнуть элемент:
текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст
Шаг 3. Показать часть спрайта в «окошке»
А теперь самое забавное. Размер DIV для иконки – жёстко фиксирован:
Это значит, что если поставить в качестве background объединённую картинку, то вся она не поместится, будет видна только верхняя часть:
Если бы высота иконки была больше, например, 16x48 , как в примере ниже, то было бы видно и остальное:
…но так как там всего 16px , то помещается только одно изображение.
Простой пример
В качестве простого примера демонстрации свойств мы будем использовать следующий элемент:
У элемента есть рамка (border), внутренний отступ (padding) и прокрутка. Полный набор характеристик. Обратите внимание, тут нет внешних отступов (margin), потому что они не являются частью элемента, для них нет особых JavaScript-свойств.
Результат выглядит так:
В иллюстрации выше намеренно продемонстрирован самый сложный и полный случай, когда у элемента есть ещё и полоса прокрутки. Некоторые браузеры (не все) отбирают место для неё, забирая его у области, отведённой для содержимого (помечена как «content width» выше).
Таким образом, без учёта полосы прокрутки ширина области содержимого (content width) будет 300px , но если предположить, что ширина полосы прокрутки равна 16px (её точное значение зависит от устройства и браузера), тогда остаётся только 300 - 16 = 284px , и мы должны это учитывать. Вот почему примеры в этой главе даны с полосой прокрутки. Без неё некоторые вычисления будут проще.
Нижние внутренние отступы padding-bottom изображены пустыми на наших иллюстрациях, но если элемент содержит много текста, то он будет перекрывать padding-bottom , это нормально.
offsetWidth/Height
Теперь переходим к самому элементу.
Эти два свойства – самые простые. Они содержат «внешнюю» ширину/высоту элемента, то есть его полный размер, включая рамки.
Для нашего элемента:
- offsetWidth = 390 – внешняя ширина блока, её можно получить сложением CSS-ширины ( 300px ), внутренних отступов ( 2 * 20px ) и рамок ( 2 * 25px ).
- offsetHeight = 290 – внешняя высота блока.
Координаты и размеры в JavaScript устанавливаются только для видимых элементов.
Если элемент (или любой его родитель) имеет display:none или отсутствует в документе, то все его метрики равны нулю (или null , если это offsetParent ).
Например, свойство offsetParent равно null , а offsetWidth и offsetHeight равны 0 , когда мы создали элемент, но ещё не вставили его в документ, или если у элемента (или у его родителя) display:none .
Мы можем использовать это, чтобы делать проверку на видимость:
Заметим, что функция isHidden также вернёт true для элементов, которые в принципе показываются, но их размеры равны нулю (например, пустые ).
Отступы
Обычно отступы делаются margin/padding , но иногда их бывает удобно предусмотреть в спрайте.
Тогда если элемент немного больше, чем размер изображения, то в «окошке» не появится лишнего.
Пример спрайта с отступами:
Иконка RSS находится в нём на координатах (90px, 40px) :
Это значит, для того чтобы показать эту иконку, нужно сместить фон:
При этом в левом-верхнем углу фона как раз и будет эта иконка:
Элемент, в котором находится иконка (в рамке), больше по размеру, чем картинка.
Если бы в спрайте не было отступов, то в такое большое «окошко» наверняка влезли бы другие иконки.
Читайте также: