Псевдоклассы СSS :not() и :target
Сегодня мы рассмотрим менее распространенные псевдоклассы CSS , которые поддерживаются в современных браузерах: child-indexed и typed child-indexed , а также псевдоклассы для элементов ввода input . Псевдоклассы child-indexed и typed child-indexed позволяют выделять элементы по их расположению в дереве документа. Псевдоклассы input определяют поля формы на основе их значений и состояний.
Подсветка фрагментов страницы псевдоклассом :target
В этом случае идентификатор фрагмента является частью URL , который следует после хеша # ( например, #top или #footnote1 ). Такое часто используется для организации навигации по странице при помощи так называемой « jump-link ». С помощью псевдокласса :target можно подсветить фрагмент документа:
Comments on this post
. . .
После нескольких штрихов и работы с CSS получается результат, который приведен ниже:
Каждый comment в коде обозначен идентификатором, который позволяет ссылаться на конкретный фрагмент. Например, . Всё что остаётся – это стилизовать комментарий, используя псевдокласс CSS child :target :
.comment:target
Когда идентификатор фрагмента в URL совпадает с комментарием ( например , http://example.com/post/#comment-1146937891 ), он будет подсвечен жёлтым цветом, как показано ниже:

Псевдокласс CSS :target позволяет создавать комбинации, что открывает пространство для манёвров и позволяет не использовать JavaScript . Стилизуем наш пример с помощью CSS3 . Для начала посмотрите на HTML-код :
Здесь всё просто: три вкладки и контент с привязкой. Добавим CSS :
[id^=tab] < position: absolute; >[id^=tab]:first-child < z-index: 1; >[id^=tab]:target
Здесь и начинается волшебство. Сначала мы задаём вкладкам абсолютное позиционирование. Затем располагаем первую вкладку поверх контента при помощи свойства z-index: 1 . Это важно, если при первом посещении пользователи должны видеть именно эту вкладку. Добавляем свойство z-index 1 к нашей вкладке target . Это гарантирует, что выделенный слой всегда будет расположен поверх остального контента. Результат представлен ниже:

Улучшаем доступность
В более доступной версии ( в том числе и псевдоклассах CSS ссылок ) можно использовать JavaScript для переключения атрибутов hidden и aria-hidden=true .
Клик по вкладке обновляет URL с использованием нового идентификатора фрагмента, после чего приводится в действие состояние :target .
Отрицание селекторов при помощи :not()
Одним из самых многофункциональных считается псевдокласс :not() . Он возвращает все элементы, за исключением тех, которые совпадают с аргументом селектора. Например, p:not(.message) выделяет все элементы p без класса message .
Псевдокласс :not() принимает один аргумент, как и большинство функций в других языках программирования. Любой аргумент, заданный в :not() , должен быть простым селектором, названием класса или ID , другим псевдоклассом. Псевдоклассы не работают так, как составные селекторы типа label.checkbox или сложные селекторы типа p img .
Посмотрите на пример формы, в которой используется текстовые элементы ввода и radio buttons :
В HTML label , ассоциированные с элементами типа radio , имеют класс .label-radio . Можно использовать псевдокласс CSS нажатия :not() для выделения элементов, не имеющих класса label-radio , как это показано на картинке ниже:
label:not(.label-radio)

Рассмотрим более сложный пример. Используем стилизацию текстовых полей. Сюда входят элементы ввода number , email и text , а также password и url . Кроме этого мы исключим элементы radio , checkbox и range . Вам наверняка захочется воспользоваться следующим списком селектора:
([type=radio]), input:not([type=checkbox]), input:not([type=range])
К сожалению, это не поможет, так как каждый новый селектор переписывает предыдущий. Это всё равно, что писать:
input:not([type=radio]) < . >input:not([type=checkbox]) < . >input:not([type=range])
Вместо этого, нужно связать псевдоклассы :not() в цепочку, чтобы они отфильтровывали все элементы input :
input:not([type=radio]):not([type=checkbox]):not([type=range])
Приведённая цепочка селекторов также соответствует элементам [type=image], [type=reset], [type=color] и [type=submit]
Использование псевдоклассов и псевдоэлементов CSS без простого селектора эквивалентно его использованию с универсальным селектором. Другими словами, :not([type=radio]) – то же, что и *:not([type=radio]) . В данном случае нашему критерию отвечает любой элемент без атрибута type и значения radio , включая html и body . Чтобы предотвратить это, используйте :not() с названием класса, ID или селектор атрибутов в качестве селектора.
В CSS Class-селекторах Level 4 изменен принцип работы :not() , так что, теперь он принимает в качестве аргумента не только простые селекторы, но и списки. Вместо того чтобы связывать классы, как это делалось раньше, можно указывать аргументы через запятую:
input:not([type=radio], [type=checkbox], [type=range])
К сожалению, пока далеко не все браузеры поддерживают этот вариант, поэтому мы рекомендуем и дальше использовать цепочки.
Валентин Сейидов автор-переводчик статьи « CSS Pseudo-classes: :not() and :target »
Как правильно использовать функцию createSelector (библиотека reselect) с хуком useSelector в приложении React?
Первая закомментированная строка в компоненте App (где я деструктурирую объект) работает хорошо: я получаю билеты с сервера и отображаю их в компоненте. Но мне необходимо добавить сайд-эффекты в массив билетов (сортировка, фильтрация), поэтому я решил использовать селектор. Однако, при использовании такой записи const tickets = useSelector(sorterSelector) , селектор возвращает undefined (ошибка TypeError: Cannot read property ‘map’ of undefined ). При данной записи и логике, которую я описал в sorterSelector , я даже не вижу, что функция fetchData в useEffect запускается. Как решить эту проблему?
Два шаблона тикетов
День добрый сообщество, возникла такая ситуация.
Есть два разных вызова сниппета TicketForm, необходимо что бы при создание тикета в первом вызове применялся Шаблон тикет 1, во втором вызове применялся Шаблон тикет 2.
Подскажите пожалуйста как такое реализовать?
Заранее благодарен!
23 ноября 2015, 12:18
Дмитрий Середюк /users/palma modx.pro https://modx.pro
Комментарии: 9
04 августа 2016, 23:55
Мне вот тоже интересно, потому как в вызове двух TicketForm на странице (с разными полями и логикой их заполнения), в одной есть WYSIWYG-редактор, а во второй, для аналогичной textarea, не появляется. Дело, видимо, в том, что у них одинаковый, и применяется он лишь один раз. Но как бы это обойти, или чтобы шаблон с полями формы менялся в зависимости от выбранной секции в списке с
05 августа 2016, 00:51
Дело в том, что по логике html атрибут id считается уникальным. Исходя из этого, например, поиск значений через айди будет быстрее, чем через классы:
//первое условие выполнится быстрее, т.к. после первого нахождения подходящего элемента, скрипт прекратит работу $("#id").css("display", "block"); //а эта функция будет искать до конца html-разметки $(".class").css("display", "block);
В твоем случае решение очень простое — подключай визуальный редактор через идентификатор класса.
05 августа 2016, 00:48
Вариант 1 (менее надежный — пользователь может отредактировать значение через консоль браузера):
//также нужно указать параметр template в списке допустимых и обязательных полей (в настройках сниппета TicketForm)
Вариант 2 (через плагин):
event->name == 'OnDocFormSave' && $mode == 'new') { if (любым условием при помощи входящих POST-данных фильтруешь нужную форму ) { $resource->set('template', 'айди_шаблона'); $resource->save(); } }
05 августа 2016, 01:19
Спасибо, но, увы, не догоняю. Временно решил вопрос, сделав отдельные две страницы с разными формами. Но хотелось бы, конечно, разжеванных инструкций «для чайников», если, конечно, не затруднит.
Вот у меня два шаблона для разных вызовов TicketForm. «Шаблон1», если пишем в «секция1» и «шаблон2», если в «секция2». И страница для публикации. Где:
Вариант «красивый» — это общий вызов TicketForm, но, выбирая секцию из списка, прописанном в вызове (&resources=`секция1, секция2`), у меня на страницу сразу подгружается соответствующий шаблон с полями и правилами их заполнения.
Вариант «норм» — это два вызова с разными шаблонами. Но тут идентичные поля путаются между собой, и может дело не только в id.
Вроде бы предложенный плагин — из серии «красивого», но как его применить, где и как вызывать?
05 августа 2016, 02:11
Конкретно для вашей задачи, из серии «красивого», я бы сделал так (используется fenom):
1.На нужной странице (допустим, «Управление товарами») ставим селектор секций:
Чанк section.option.item:
2. На событие переключения селектора пишем скрипт, выставляющий в адресную строку соответствующий гет-параметр:
Что мы имеем: селектор, который при переключении прописывает в адресную строку гет-параметр вида
?category=айди_выбранной_категории
и перезагружает страницу. Нам осталось только перехватывать значение этого гет-параметра и в зависимости от него выставлять соответствующую форму:
{var $category_id = $.get.category} if $category_id {switch $category_id} 0} [[!ticketform? {$params}]] {else} Указана некорректная категория. {/if} {else} Выберите категорию. {/if}
TicketForm и поля multiselect (multiple)
Искал решения для заполнения полей типа multiselect htmlbook.ru/html/select/multiple через ticketForm. Есть решение для select modx.pro/help/6325/#comment-45022, но хотелось бы использовать ТВ-поля «множественный список» в админке, а на фронтенде — multiselect. Нужно это для последующей фильтрации через mFilter2. У страницы будут выбраны одно или несколько значений из списка с множественным выбором.
Если у вас есть наработки в этой области и вы готовы поделиться — я с удовольствием отблагодарю небольшим спасибо на карту или телефон.
10 мая 2018, 07:55
Wassi Wassinen /users/vasilueff modx.pro https://modx.pro
Комментарии: 3
15 мая 2018, 16:25
На мой взгляд, плагин тут нецесообразен, так как, во-первых, увеличит время сохранения тикета, а во-вторых его относительно-универсальная реализация (в случае, если нужен точечный контроль формы, родителей и тд) будет куда более громоздкой, чем тоже самое, но на js:
1. Добавляем в параметры допустимых полей сниппета ticketForm необходимое тв-поле (tvname1)
2. Добавляем внутри формы создания/обновления мультиселектор:
2. Добавляем для тега select атрибут data-real, со значением, равным названию нашего тв-поля и произвольный класс (пусть будет bimbo-input, от слова «пустышка»):
select data-real="tvname1" > 3. После тега select (или в любом другом месте внутри тега form) добавляем настоящий инпут, хранящий значение тв-поля:
//Для формы создания //Для формы обновления
4. В js добавляем событие, переносящие заполненные значения от селектора-пустышки в настоящий инпут при изменении первого:
$(document).on('change', '.bimbo-input', function(e) { $('input[name="' + $(this).attr("data-real") + '"]').val($(this).val()); });
5. В тот же js добавляем событие, переносящие реальное значение из скрытого инпута в пустышку при загрузке страницы:
$(document).ready(function(){ $('.bimbo-real').each(function(){ $('.bimbo-input[data-real="' + $(this).attr("name") + '"]').val($(this).val()); }); });
В итоге:
— решение относительно универсально, т.к. не привязано ни к ticket-ам, ни к конкретным родителям, а упирается только в наличие нужных классов и скрытых полей
— вся лишняя нагрузка происходит в процессе заполнения
— может работать не только с мультиселекторами, но и простыми селекторами или инпутами (удобно в случаях, если селектор нужно кастомизировать каким-либо js-скриптом, который в процессе видоизменяет его структуру)
