使用自定义包装器输入:优点和缺点?

时间:2015-04-20 10:10:02

标签: javascript jquery html css

有时我需要完全自定义输入元素:复选框,单选按钮,选择等。

只是想问一下这种做法是否可以接受:

  1. 我们为输入创建了某种包装器(在这种情况下为单选框)
  2. 我们隐藏了我们真正的收音机盒(不透明度:0,可见性:隐藏,左:-9999px等)
  3. 单击父包装器:我们获取输入名称属性,使用[type =" radio] [name =" clickedInputName"]查找所有输入,将它们全部设置为未选中设置我们点击的那个将其设置为选中。
  4. 附加一些不太漂亮的 jsfiddle:https://jsfiddle.net/moLvh9dd/

        $('.radio-wrapper').on('click', function(e){
    e.preventDefault();
    var targetInput = $(this).find($('input'));
    
    var clickedInputName = 'input[type="radio"]    [name="'+targetInput.attr('name')+'"]';
    
    $(clickedInputName).each(function(){
        $(this).prop('checked', false);
        $(this).parent().removeClass('input-checked');
    })
    
    targetInput.prop('checked', true); 
    $(this).addClass('input-checked');
    
    });
    

    检查浏览器兼容性,+ - 到处都是IE8,所以尽管它只是工作,我想知道它是否正确?可以接受吗?

    尽管它依赖于javascript / jQuery。

    编辑:

    感谢收音机和复选框输入的一些很好的答案,但是自定义选择元素呢?每个选择都有不同的选项?

    例如像这里 - 再一些丑陋的jQuery:https://jsfiddle.net/4gt7gavq/

3 个答案:

答案 0 :(得分:1)

您可以在不使用纯CSS或使用图像的JS的情况下使用替代方案。 在这里你可以找到解释的两种技术,我当然会建议纯CSS的方式,但这取决于你的跨浏览器要求。

纯CSS样式

下面的演示纯粹是使用CSS设计的。与基于图像的方法不同,纯CSS方法随文本大小而缩放。 用于每个复选框或单选按钮的HTML类似于基于图像的方法中的HTML:

<div>
  <input id="option" type="checkbox" name="field" value="option">
  <label for="option"><span><span></span></span>Value</label>
</div>

标签内的span元素用于创建替代图形。虽然单选按钮需要两个跨度,但复选框只需要一个。

我们隐藏样式表中的复选框和单选按钮:

input[type=checkbox]:not(old),
input[type=radio   ]:not(old){
  width     : 2em;
  margin    : 0;
  padding   : 0;
  font-size : 1em;
  opacity   : 0;
}

该技术与基于图像的方法相同,但由于宽度是相对于第3行中的字体大小设置的,因此我们必须恢复第6行中的字体大小,因为浏览器使用较小的字体大小来复选框和单选按钮默认。

然后我们定位标签:

input[type=checkbox]:not(old) + label,
input[type=radio   ]:not(old) + label{
  display      : inline-block;
  margin-left  : -2em;
  line-height  : 1.5em;
}

同样,该技术与基于图像的方法相同,但使用相对单位。填充不是必需的,因为可缩放图形与背景图像不同,将推动标签文本。

然后,我们设置第一个范围的样式以创建未选中的图形:

input[type=checkbox]:not(old) + label > span,
input[type=radio   ]:not(old) + label > span{
  display          : inline-block;
  width            : 0.875em;
  height           : 0.875em;
  margin           : 0.25em 0.5em 0.25em 0.25em;
  border           : 0.0625em solid rgb(192,192,192);
  border-radius    : 0.25em;
  background       : rgb(224,224,224);
  background-image :    -moz-linear-gradient(rgb(240,240,240),rgb(224,224,224));
  background-image :     -ms-linear-gradient(rgb(240,240,240),rgb(224,224,224));
  background-image :      -o-linear-gradient(rgb(240,240,240),rgb(224,224,224));
  background-image : -webkit-linear-gradient(rgb(240,240,240),rgb(224,224,224));
  background-image :         linear-gradient(rgb(240,240,240),rgb(224,224,224));
  vertical-align   : bottom;
}

此处使用的技术在CSS3样式按钮页面中有详细介绍。第15行确保图形位于标签的底部而不是文本的基线。

在该示例中,背景渐变在所选复选框和单选按钮上反转:

input[type=checkbox]:not(old):checked + label > span,
input[type=radio   ]:not(old):checked + label > span{
  background-image :    -moz-linear-gradient(rgb(224,224,224),rgb(240,240,240));
  background-image :     -ms-linear-gradient(rgb(224,224,224),rgb(240,240,240));
  background-image :      -o-linear-gradient(rgb(224,224,224),rgb(240,240,240));
  background-image : -webkit-linear-gradient(rgb(224,224,224),rgb(240,240,240));
  background-image :         linear-gradient(rgb(224,224,224),rgb(240,240,240));
}

然后我们在所选复选框中显示一个勾号:

input[type=checkbox]:not(old):checked + label > span:before{
  content     : '✓';
  display     : block;
  width       : 1em;
  color       : rgb(153,204,102);
  font-size   : 0.875em;
  line-height : 1em;
  text-align  : center;
  text-shadow : 0 0 0.0714em rgb(115,153,77);
  font-weight : bold;
}

第1行中的选择器使用:before伪类,以便第2行可以在span元素内插入tick符号。第3,4,6,7和8行在元素中居中显示勾号,而第5,9和10行则为文本设置样式。

最后,我们在选定的单选按钮中显示一个“项目符号”,将与未选中图形相同的技术应用于第二个span元素:

input[type=radio]:not(old):checked + label > span > span{
  display          : block;
  width            : 0.5em;
  height           : 0.5em;
  margin           : 0.125em;
  border           : 0.0625em solid rgb(115,153,77);
  border-radius    : 0.125em;
  background       : rgb(153,204,102);
  background-image :    -moz-linear-gradient(rgb(179,217,140),rgb(153,204,102));
  background-image :     -ms-linear-gradient(rgb(179,217,140),rgb(153,204,102));
  background-image :      -o-linear-gradient(rgb(179,217,140),rgb(153,204,102));
  background-image : -webkit-linear-gradient(rgb(179,217,140),rgb(153,204,102));
  background-image :         linear-gradient(rgb(179,217,140),rgb(153,204,102));
}

http://code.stephenmorley.org/html-and-css/styling-checkboxes-and-radio-buttons/#pureCSS

选择元素

在选择元素上,您可以更改颜色,边框和下拉箭头。不多了。

为此,请使用自定义箭头创建一个png并将其设置为元素包围:

.styled-select {
   width: 240px;
   height: 34px;
   overflow: hidden;
   background: url(new_arrow.png) no-repeat right #ddd;
   border: 1px solid #ccc;
   }

http://bavotasan.com/2011/style-select-box-using-only-css/

答案 1 :(得分:1)

这些做法非常可以接受。在大多数情况下,只要表单仍然可以访问并且可以在禁用JavaScript和/或CSS的情况下使用,那么您就可以了。

要使用原始问题中提供的示例的一些示例代码扩展我上面的一条评论,您可以单独通过CSS实现此目的,而无需任何JavaScript。

您需要做的是使用带有伪元素的标签,然后将:checked伪类与相邻的选择器一起使用来更改这些伪元素的样式。

这还有一个额外的好处,即需要更少的标记,但这将取决于您的整体布局。

以下是示例代码:

*,*:before,*:after{box-sizing:border-box;font-family:sans-serif;}
input.radio{
    left:-9999px;
    position:absolute;
}
label.radio{
    cursor:pointer;
    display:block;
    line-height:20px;
    margin:0 0 10px;
    padding:0 0 0 26px;
    position:relative;
}
label.radio:before{
    border:1px solid #f00;
    border-radius:50%;
    content:"";
    display:block;
    height:16px;
    left:5px;
    position:absolute;
    top:2px;
    width:16px;
}
label.radio:after{
    background:#f00;
    border-radius:50%;
    content:"";
    display:block;
    height:8px;
    left:9px;
    opacity:0;
    position:absolute;
    top:6px;
    transform:scale(0);
    transition:transform .25s,opacity .5s;
    width:8px;
}
input.radio:checked+label.radio:after{
    opacity:1;
    transform:scale(1);
}
<input class="radio" name="radio-option" id="option1" type="radio" value="1">
<label class="radio" for="option1">Option 1</label>
<input class="radio" name="radio-option" id="option2" type="radio" value="2">
<label class="radio" for="option2">Option 2</label>
<input class="radio" name="radio-option" id="option3" type="radio" value="3">
<label class="radio" for="option3">Option 3</label>
<input class="radio" name="radio-option" id="option4" type="radio" value="4">
<label class="radio" for="option4">Option 4</label>

答案 2 :(得分:0)

作为替换原始输入元素的缺点,您将无法使用键盘(tabindex)来关注和更改此元素的值。