Использовать изображения, такие как флажки
Я хотел бы иметь альтернативу стандартным флажкам - в основном, я хотел бы использовать изображения и когда пользователь щелкает изображение, исчезает и накладывает галочку.
В сущности, я хочу сделать что-то вроде Recaptcha 2, когда вам нужно щелкнуть изображения, соответствующие определенным критериям. Вы можете увидеть демонстрацию Recaptcha здесь, но иногда это может помочь вам решить текстовые вопросы, в отличие от выбора изображения. Итак, вот скриншот:
![Google Recaptcha screenshot]()
Когда вы нажимаете одно из изображений (в этом случае, содержащее изображение стейка), изображение, которое вы нажимаете, уменьшается по размеру, и появляется синий галочка, указывающий, что вы отметили его.
Скажем, я хочу воспроизвести этот точный пример.
Я понимаю, что у меня может быть 9 скрытых флажков и прикрепить некоторый jQuery, чтобы при щелчке по изображению он выбирает/отменяет скрытый флажок. Но как насчет сокращения изображения/наложения галочки?
Ответы
Ответ 1
Чистое семантическое решение HTML/CSS
Это легко реализовать самостоятельно, без предварительного решения. Также он научит вас многому, поскольку вам не кажется слишком легким использование CSS.
Это то, что вам нужно сделать:
У ваших флажков должны быть разные атрибуты id
. Это позволяет подключить к нему <label>
, используя метку for
-attribute.
Пример:
<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1"><img src="http://someurl" /></label>
Прикрепление метки к флажку приведет к поведению браузера: всякий раз, когда кто-то нажимает на метку (или изображение внутри нее), этот флажок будет переключен.
Затем вы скроете флажок, применив для него display: none;
.
Теперь все, что вам нужно сделать, это установить стиль, который вы хотите для своей метки: перед псевдоэлементом (элементы замены флажка):
label:before {
background-image: url(../path/to/unchecked.png);
}
В последнем сложном шаге вы используете селектор CSS :checked
, чтобы изменить изображение, когда установлен флажок:
:checked + label:before {
background-image: url(../path/to/checked.png);
}
+
(смежный селектор) позволяет вам только заменять метки, которые непосредственно следуют за скрытым флажком в разметке.
Вы можете оптимизировать это, поместив оба изображения в spritemap и применив только изменение background-position
вместо замены изображения.
Конечно, вам нужно правильно поместить метку и применить display: block;
и установить правильные width
и height
.
Изменить:
Пример codepen и фрагмент кода, который я создал после этих инструкций, используют ту же технику , но вместо использования изображений для флажков замены флажка выполняются исключительно с помощью CSS, создавая :before
на ярлыке, который после проверки имеет content: "✓";
. Добавьте округленные границы и сладкие переходы, и результат действительно приятный!
Вот рабочий код, который демонстрирует технику и не требует изображений для флажка:
http://codepen.io/anon/pen/wadwpx
Вот фрагмент кода:
ul {
list-style-type: none;
}
li {
display: inline-block;
}
input[type="checkbox"][id^="cb"] {
display: none;
}
label {
border: 1px solid #fff;
padding: 10px;
display: block;
position: relative;
margin: 10px;
cursor: pointer;
}
label:before {
background-color: white;
color: white;
content: " ";
display: block;
border-radius: 50%;
border: 1px solid grey;
position: absolute;
top: -5px;
left: -5px;
width: 25px;
height: 25px;
text-align: center;
line-height: 28px;
transition-duration: 0.4s;
transform: scale(0);
}
label img {
height: 100px;
width: 100px;
transition-duration: 0.2s;
transform-origin: 50% 50%;
}
:checked + label {
border-color: #ddd;
}
:checked + label:before {
content: "✓";
background-color: grey;
transform: scale(1);
}
:checked + label img {
transform: scale(0.9);
box-shadow: 0 0 5px #333;
z-index: -1;
}
<ul>
<li><input type="checkbox" id="cb1" />
<label for="cb1"><img src="http://lorempixel.com/100/100" /></label>
</li>
<li><input type="checkbox" id="cb2" />
<label for="cb2"><img src="http://lorempixel.com/101/101" /></label>
</li>
<li><input type="checkbox" id="cb3" />
<label for="cb3"><img src="http://lorempixel.com/102/102" /></label>
</li>
<li><input type="checkbox" id="cb4" />
<label for="cb4"><img src="http://lorempixel.com/103/103" /></label>
</li>
</ul>
Ответ 2
Чистое решение для CSS
Вызывается три аккуратных устройства:
label:before {
content: url("https://cdn1.iconfinder.com/data/icons/windows8_icons_iconpharm/26/unchecked_checkbox.png");
position: absolute;
z-index: 100;
}
:checked+label:before {
content: url("https://cdn1.iconfinder.com/data/icons/windows8_icons_iconpharm/26/checked_checkbox.png");
}
input[type=checkbox] {
display: none;
}
/*pure cosmetics:*/
img {
width: 150px;
height: 150px;
}
label {
margin: 10px;
}
<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1">
<img src="https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcR0LkgDZRDTgnDrzhnXGDFRSItAzGCBEWEnkLMdnA_zkIH5Zg6oag">
</label>
<input type="checkbox" id="myCheckbox2" />
<label for="myCheckbox2">
<img src="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRhJjGB3mQxjhI5lfS9SwXou06-2qT_0MjNAr0atu75trXIaR2d">
</label>
<input type="checkbox" id="myCheckbox3" />
<label for="myCheckbox3">
<img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcQuwWbUXC-lgzQHp-j1iw56PIgl_2eALrEENUP-ld72gq3s8cVo">
</label>
Ответ 3
Я бы добавил дополнительный div с position: relative;
и class="checked"
, который имеет ту же ширину/высоту, что и изображение, а не положение в left: 0; top: 0;
, содержащее значок. Он начинается с display: none;
.
Теперь вы можете слушать click
-event:
$( '.captcha_images' ).click( function() {
$(this + '.checked').css( 'display', 'block' );
$(this).animate( { width: '70%', height: '70%' } );
});
Таким образом вы можете получить значок, а также изменить размер изображения на меньший путь.
Примечание. Просто хотелось показать вам "логику" моих мыслей, этот пример может не работать или содержать некоторые ошибки.
Ответ 4
Смотрите этот плагин jQuery: imgCheckbox (на npm и bower)
Отказ от ответственности: Для решения этой проблемы не требуется javascript. Напряженность связана с ремонтопригодностью и эффективностью кода. Хотя нет необходимости в плагине (или любом javascript), он уверен, что он быстрее работает, и часто его легче изменить.
Решение Barebones:
С очень простым HTML (ни один из беспорядков с флажками и ярлыками и т.д.):
<img class="checkable" src="http://lorempixel.com/100/100" />
Вы можете использовать jQuery toggleClass, чтобы включить/выключить класс selected
или checked
в событии click
:
$("img.checkable").click(function () {
$(this).toggleClass("checked");
});
Проверяемые элементы выбираются с помощью
$(".checked")
Плюс Coolness:
Вы можете стилизовать изображения, основанные на этом, но большая проблема заключается в том, что без других элементов DOM вы даже не можете использовать ::before
и ::after
для добавления таких вещей, как отметки. Решение состоит в том, чтобы обернуть ваши изображения другим элементом (и имеет смысл прикрепить прослушиватель кликов к обернутому элементу).
$("img.checkable").wrap("<span class='fancychecks'>")
Это оставляет ваш html действительно чистым и ваш js невероятно удобочитаемым. Взгляните на фрагмент...
/* Note that this js actually responds
to a click event on the wrapped element!
(not the image) */
$("img.checkable").wrap("<span class='fancychecks'>")
.parent().click(function() {
$(this).toggleClass("checked");
});
/* style the images */
span.fancychecks img {
display: block;
margin: 0;
padding: 0;
transition-duration: 300ms;
transform: scale(1);
filter: none;
-webkit-filter: grayscale(0);
}
span.fancychecks.checked img {
transform: scale(0.8);
filter: gray;
filter: grayscale(1);
-webkit-filter: grayscale(1);
}
/* style the parent spans */
span.fancychecks {
padding: 0;
margin: 5px;
display: inline-block;
border: 1px solid transparent;
transition-duration: 300ms;
}
span.fancychecks.checked {
border-color: #ccc;
}
/* Using conexo fantastic CSS, make the checkmarks */
span.fancychecks::before {
background-color: rgba(50, 200, 50, 0.7);
color: white;
content: "✓";
font-weight: bold;
border-radius: 50%;
position: absolute;
margin: 2px;
top: 1;
left: 1;
z-index: 1;
width: 25px;
height: 25px;
text-align: center;
line-height: 28px;
transform: scale(0);
transition-duration: 300ms;
}
span.fancychecks.checked::before {
transform: scale(1);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<img class="checkable" src="http://lorempixel.com/100/100/city/1" />
<img class="checkable" src="http://lorempixel.com/100/100/city/2" />
<img class="checkable" src="http://lorempixel.com/100/100/city/3" />
Ответ 5
Вот краткий пример выбора изображения, такого как флажок
Обновленный пример с помощью Knockout.js:
var imageModel = function() {
this.chk = ko.observableArray();
};
ko.applyBindings(new imageModel());
input[type=checkbox] {
display:none;
}
input[type=checkbox] + label
{
display:inline-block;
width:150px;
height:150px;
background:#FBDFDA;
border:none;
}
input[type=checkbox]:checked + label
{
background:#CFCFCF;
border:none;
position:relative;
width:100px;
height:100px;
padding: 20px;
}
input[type=checkbox]:checked + label:after
{
content: '\2713';
position:absolute;
top:-10px;
right:-10px;
border-radius: 10px;
width: 25px;
height: 25px;
border-color: white;
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<input type='checkbox' name='image1' value='image1' id="image1" data-bind="checked: chk"/><label for="image1"></label><label for="image1"><img class='testbtn'/></label>
<div data-bind="html: chk"></div>
Ответ 6
Я заметил, что другие ответы либо не используют <label>
(почему бы и нет?), либо требуют сопоставления атрибутов for
и id
. Это означает, что если у вас есть конфликтующие идентификаторы, ваш код не будет работать, и вы должны помнить о том, чтобы каждый раз создавать уникальные идентификаторы.
Кроме того, если вы скроете input
с помощью display:none
или visibility:hidden
, браузер не будет фокусироваться на нем.
Флажок и его текст (или в этом случае, изображение) могут быть завернуты в метку:
.fancy-checkbox-label > input[type=checkbox] {
position: absolute;
opacity: 0;
cursor: inherit;
}
.fancy-checkbox-label {
font-weight: normal;
cursor: pointer;
}
.fancy-checkbox:before {
font-family: FontAwesome;
content: "\f00c";
background: #fff;
color: transparent;
border: 3px solid #ddd;
border-radius: 3px;
z-index: 1;
}
.fancy-checkbox-label:hover > .fancy-checkbox:before,
input:focus + .fancy-checkbox:before {
border-color: #bdbdff;
}
.fancy-checkbox-label:hover > input:not(:checked) + .fancy-checkbox:before {
color: #eee;
}
input:checked + .fancy-checkbox:before {
color: #fff;
background: #bdbdff;
border-color: #bdbdff;
}
.fancy-checkbox-img:before {
position: absolute;
margin: 3px;
line-height: normal;
}
input:checked + .fancy-checkbox-img + img {
transform: scale(0.9);
box-shadow: 0 0 5px #bdbdff;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">
<p>
<label class="fancy-checkbox-label">
<input type="checkbox">
<span class="fancy-checkbox"></span>
A normal checkbox
</label>
</p>
<p>
<label class="fancy-checkbox-label">
<input type="checkbox">
<span class="fancy-checkbox fancy-checkbox-img"></span>
<img src="http://placehold.it/150x150">
</label>
</p>
Ответ 7
Чтобы расширить принятый ответ для тех, кто использует WordPress и GravityForms, чтобы сгенерировать их формы и пожелать автоматически заполнить поля флажка списком сообщений и их связанной Featured Thumbnail
// Change '2' to your form ID
add_filter( 'gform_pre_render_2', 'populate_checkbox' );
add_filter( 'gform_pre_validation_2', 'populate_checkbox' );
add_filter( 'gform_pre_submission_filter_2', 'populate_checkbox' );
add_filter( 'gform_admin_pre_render_2', 'populate_checkbox' );
function populate_checkbox( $form ) {
foreach( $form['fields'] as &$field ) {
// Change '41' to your checkbox field ID
$field_id = 41;
if ( $field->id != $field_id ) {
continue;
}
// Adjust $args for your post type
$args = array(
'post_type' => 'pet',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'pet_category',
'field' => 'slug',
'terms' => 'cat'
)
)
);
$posts = get_posts( $args );
$input_id = 1;
foreach( $posts as $post ) {
$feat_image_url = wp_get_attachment_image( get_post_thumbnail_id( $post->ID ), 'thumbnail' );
$feat_image_url .= '<br />' . $post->post_title;
if ( $input_id % 10 == 0 ) {
$input_id++;
}
$choices[] = array( 'text' => $feat_image_url, 'value' => $post->post_title );
$inputs[] = array( 'label' => $post->post_title, 'id' => "{$field_id}.{$input_id}" );
$input_id++;
}
$field->choices = $choices;
$field->inputs = $inputs;
}
return $form;
}
И CSS:
.gform_wrapper .gfield_checkbox li[class^="gchoice_2_41_"] {
display: inline-block;
}
.gform_wrapper .gfield_checkbox li input[type="checkbox"][id^="choice_2_41_"] {
display: none;
}
.gform_wrapper .gfield_checkbox li label[id^="label_2_41_"] {
border: 1px solid #fff;
padding: 10px;
display: block;
position: relative;
margin: 10px;
cursor: pointer;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
label[id^="label_2_41_"]:before {
font-family: "font-icons";
font-size: 32px;
color: #1abc9c;
content: " ";
display: block;
background-color: transparent;
position: absolute;
top: -5px;
left: -5px;
width: 25px;
height: 25px;
text-align: center;
line-height: 28px;
transition-duration: 0.4s;
transform: scale(0);
}
label[id^="label_2_41_"] img {
transition-duration: 0.2s;
transform-origin: 50% 50%;
}
:checked + label[id^="label_2_41_"] {
border-color: #ddd;
}
/* FontAwesome tick */
:checked + label[id^="label_2_41_"]:before {
content: "\e6c8";
background-color: transparent;
transform: scale(1);
}
:checked + label[id^="label_2_41_"] img {
transform: scale(0.9);
box-shadow: 0 0 5px #333;
z-index: 0;
}