javascript 像复选框一样使用图像

lkaoscv7  于 2023-01-19  发布在  Java
关注(0)|答案(8)|浏览(158)

我想有一个替代标准的复选框-基本上我想使用图像,当用户点击图像,淡出它,并覆盖一个复选框。
从本质上讲,我想做一些类似Recaptcha 2的事情,当它让你点击符合一定条件的图片时。你可以see a Recaptcha demo here,但它有时可能会让你解决文本问题,而不是图片选择。所以这里有一个截图:

当您点按其中一个图像(在本例中,包含牛排图片)时,您点按的图像会缩小大小并显示蓝色勾号,表示您已勾选了它。
假设我想重现这个例子。
我意识到我可以有9个隐藏的复选框,并附加一些jQuery,这样当我点击图像时,它会选择/取消选择隐藏的复选框。但是图像的缩小/覆盖勾号怎么办?

9w11ddsr

9w11ddsr1#

纯语义HTML/CSS解决方案

这是很容易实现自己,没有预先作出的解决方案的必要。而且它会教你很多,因为你似乎不太容易与CSS。

这是您需要做的:

你的复选框需要有不同的id属性,这样你就可以使用标签的for-属性来连接<label>
示例:

<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1"><img src="http://someurl" /></label>

将标签附加到复选框将触发浏览器行为:每当有人点击标签(或标签内的图像)时,复选框将被切换。
接下来,通过应用例如display: none;来隐藏复选框。
现在剩下要做的就是为label::before伪元素(将用作可视复选框替换元素)设置所需的样式:

label::before {
    background-image: url(../path/to/unchecked.png);
}

在最后一个棘手的步骤中,当复选框被选中时,使用CSS的:checked伪选择器来更改图像:

:checked + label::before {
    background-image: url(../path/to/checked.png);
}

+(* adjacent sibling selector *)确保只更改标记中隐藏复选框后面的标签。
您可以通过将两个图像都放在一个spritemap中,并且只在background-position中应用一个更改,而不是交换图像来优化这一点。
当然,您需要正确定位标签并应用display: block;,设置正确的widthheight

编辑:

我在这些说明之后创建的codepen示例和代码片段使用了相同的技术,但不是使用图像来替换复选框,而是纯粹使用CSS来替换复选框,在标签上创建一个::before,一旦选中,它将具有content: "✓";
下面是一个工作代码,展示了该技术,并且不需要复选框的图像:
http://codepen.io/anon/pen/wadwpx
下面是相同代码的片段:
一个三个三个一个

yhuiod9q

yhuiod9q2#

纯CSS解决方案

有三种巧妙的方法被调用:

  1. :checked选择器
  2. ::before伪选择器
  3. css content属性。
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>
6pp0gazn

6pp0gazn3#

查看此jQuery插件:imgCheckbox(位于**npmbower**上)
**免责声明:**解决这个问题不需要javascript。问题在于代码的可维护性和效率之间。虽然不需要插件(或任何javascript),但它确实使构建更快,通常更容易修改。

准系统解决方案:

使用非常简单的HTML(没有复选框和标签等混乱):

<img class="checkable" src="http://lorempixel.com/100/100" />

您可以使用jQuery的toggleClass来打开/关闭selectedchecked事件上的click类:

$("img.checkable").click(function () {
    $(this).toggleClass("checked");
});

提取选中的项目时使用

$(".checked")

加上凉爽:

你可以以此为基础设计图像的样式,但一个大问题是,如果没有其他DOM元素,你甚至不能使用::before::after来添加像复选标记这样的东西。解决方案是用另一个元素 Package 你的图像(也可以将click侦听器附加到 Package 的元素上)。

$("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's 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" />

使用imgCheckbox jQuery插件:

受上面的解决方案的启发,我已经建立了一个插件,可以很容易地使用:

$("img").imgCheckbox();
  • 将选中图像的数据注入表单
  • 支持自定义复选标记
  • 支持自定义CSS
  • 支持预选图元
  • 支持单选按钮组,而不是简单地切换图像
  • 具有事件回调
  • 合理的默认值
  • 重量轻,超级容易使用

查看**in action**(以及see the source

kmb7vmvb

kmb7vmvb4#

我会用position: relative;class="checked"附加一个额外的div,它的宽度/高度与图像的宽度/高度相同,并且在包含图标的left: 0; top: 0;中的位置相同,它以display: none;开头。
现在您可以收听click-event:

$( '.captcha_images' ).click( function() {
    $(this + '.checked').css( 'display', 'block' );
    $(this).animate( { width: '70%', height: '70%' } );
});

这样你就可以得到图标,也可以调整图像的大小,以一个更小的方式。
注意:我只是想告诉你我的想法背后的“逻辑”,这个例子可能不起作用,或者有一些bug。

w8ntj3qf

w8ntj3qf5#

我举了一个例子**"Angular -使用复选框和收音机之类的图像"**
Link to Stackblitz

在app.component.html文件中:

<div class="cont-bg">
  <h5 class="text-white">Checkbox</h5>
  <div class="cont-main">
    <div class="cont-checkbox" *ngFor="let car of cars; index as i">
      <input type="checkbox" [id]="'myCheckbox-' + i" />
      <label [for]="'myCheckbox-' + i">
        <img [src]="car.img" />
        <span class="cover-checkbox">
          <svg viewBox="0 0 12 10">
            <polyline points="1.5 6 4.5 9 10.5 1"></polyline>
          </svg>
        </span>
        <div class="info">{{ car.name }}</div>
      </label>
    </div>
  </div>
  <h5 class="text-white">Radio</h5>
  <div class="cont-main">
    <div class="cont-checkbox" *ngFor="let car of cars; index as i">
      <input type="radio" name="myRadio" [id]="'myRadio-' + i" />
      <label [for]="'myRadio-' + i">
        <img [src]="car.img" />
        <span class="cover-checkbox">
          <svg viewBox="0 0 12 10">
            <polyline points="1.5 6 4.5 9 10.5 1"></polyline>
          </svg>
        </span>
        <div class="info">{{ car.name }}</div>
      </label>
    </div>
  </div>
</div>

在应用程序组件. scss文件中:

* {
  font-family: Lato;
  --transition: 0.15s;
  --border-radius: 0.5rem;
  --background: #ffc107;
  --box-shadow: #ffc107;
  // --box-shadow: #0082ff;
}

.cont-bg {
  min-height: 100vh;
  background-image: radial-gradient(
    circle farthest-corner at 7.2% 13.6%,
    rgba(37, 249, 245, 1) 0%,
    rgba(8, 70, 218, 1) 90%
  );
  padding: 1rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.cont-main {
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
}

.cont-checkbox {
  width: 150px;
  height: 100px;
  border-radius: var(--border-radius);
  box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
  transition: transform var(--transition);
  background: white;
  margin-bottom: 0.75rem;
  margin-right: 0.75rem;
  &:active {
    transform: scale(0.9);
  }
  input {
    display: none;
    &:checked + label {
      opacity: 1;
      box-shadow: 0 0 0 3px var(--background);
      .cover-checkbox {
        opacity: 1;
        transform: scale(1);
        svg {
          stroke-dashoffset: 0;
        }
      }
      img {
        -webkit-filter: none; /* Safari 6.0 - 9.0 */
        filter: none;
      }
    }
  }
  label {
    cursor: pointer;
    border-radius: var(--border-radius);
    overflow: hidden;
    width: 100%;
    height: 100%;
    position: relative;
    opacity: 0.6;
    img {
      width: 100%;
      height: 70%;
      object-fit: cover;
      clip-path: polygon(0% 0%, 100% 0, 100% 81%, 50% 100%, 0 81%);
      -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
      filter: grayscale(100%);
    }
    .cover-checkbox {
      position: absolute;
      right: 5px;
      top: 3px;
      z-index: 1;
      width: 23px;
      height: 23px;
      border-radius: 50%;
      background: var(--box-shadow);
      border: 2px solid #fff;
      transition: transform var(--transition),
        opacity calc(var(--transition) * 1.2) linear;
      opacity: 0;
      transform: scale(0);
      svg {
        width: 13px;
        height: 11px;
        display: inline-block;
        vertical-align: top;
        fill: none;
        margin: 5px 0 0 3px;
        stroke: #fff;
        stroke-width: 2;
        stroke-linecap: round;
        stroke-linejoin: round;
        stroke-dasharray: 16px;
        transition: stroke-dashoffset 0.4s ease var(--transition);
        stroke-dashoffset: 16px;
      }
    }
    .info {
      text-align: center;
      margin-top: 0.2rem;
      font-weight: 600;
      font-size: 0.8rem;
    }
  }
}

在应用程序组件. ts文件中:

import { Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  cars = [
    {
      id: '1',
      name: 'Mazda MX-5 Miata',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-mazda-mx-5-miata-mmp-1-1593459650.jpg?crop=0.781xw:0.739xh;0.109xw,0.0968xh&resize=480:*',
    },
    {
      id: '2',
      name: 'Toyota Supra',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2020-chevrolet-corvette-c8-102-1571146873.jpg?crop=0.548xw:0.411xh;0.255xw,0.321xh&resize=980:*',
    },
    {
      id: '3',
      name: 'Chevy Corvette',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-porsche-cayman-mmp-1-1593003674.jpg?crop=0.648xw:0.485xh;0.129xw,0.263xh&resize=980:*',
    },
    {
      id: '4',
      name: 'Porsche 718 Cayman',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-porsche-718-cayman-mmp-1-1593003156.jpg?crop=0.735xw:0.551xh;0.138xw,0.240xh&resize=980:*',
    },
    {
      id: '5',
      name: 'Porsche 718 Boxster',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-bmw-m2-mmp-1-1599687968.jpg?crop=0.706xw:0.528xh;0.102xw,0.268xh&resize=980:*',
    },
    {
      id: '6',
      name: 'BMW M2',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-bmw-z4-mmp-1-1599583762.jpg?crop=0.779xw:0.584xh;0.0782xw,0.196xh&resize=980:*',
    },
    {
      id: '7',
      name: 'BMW Z4',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-chevrolet-camaro-mmp-1-1585333717.jpg?crop=0.344xw:0.331xh;0.241xw,0.328xh&resize=980:*',
    },
    {
      id: '8',
      name: 'Chevy Camaro',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-chevrolet-camaro-zl1-mmp-1-1604071262.jpg?crop=0.818xw:0.663xh;0.0799xw,0.163xh&resize=980:*',
    },
    {
      id: '9',
      name: 'Chevy Camaro ZL1',
      img: 'https://hips.hearstapps.com/hmg-prod.s3.amazonaws.com/images/2021-chevrolet-camaro-zl1-mmp-1-1604071262.jpg?crop=0.818xw:0.663xh;0.0799xw,0.163xh&resize=768:*',
    },
  ];
}
    • 纯CSS复选框和单选按钮:**

一个三个三个一个

o3imoua4

o3imoua46#

我注意到其他的答案要么不使用<label>(为什么不呢?),要么要求匹配forid属性,这意味着如果你有冲突的ID,你的代码将无法工作,你必须记住每次都要创建唯一的ID。
此外,如果您使用display:nonevisibility:hidden隐藏input,浏览器将不会关注它。
复选框及其文本(在本例中为图像)可以包含在标签中:

.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="https://picsum.photos/seed/1/100">
  </label>
</p>
lf3rwulv

lf3rwulv7#

下面是一个选择类似复选框的图像的快速示例

    • 使用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>
pcww981p

pcww981p8#

要扩展任何人使用WordPress & GravityForms生成他们的表单并希望自动填充复选框字段的帖子列表及其相关的特色缩略图的可接受答案

// 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;
}

相关问题