我有一个类型编号的输入,它使用以下代码呈现:
<input class="quantity" id="id_form-0-quantity" min="0" name="form-0-quantity" value="1" type="number">
它看起来像这样:
我想把它变成这样的东西:
第二个视图使用两个单独的按钮进行模拟。
我如何按照所描述的样式设计箭头?
医生:
在被私下问过很多次关于以下设置的问题后,我决定为它添加一个演示(Bootstrap 4 + jQuery + Font Awesome 输入组设置) :
$('.btn-plus, .btn-minus').on('click', function(e) { const isNegative = $(e.target).closest('.btn-minus').is('.btn-minus'); const input = $(e.target).closest('.input-group').find('input'); if (input.is('input')) { input[0][isNegative ? 'stepDown' : 'stepUp']() } })
.inline-group { max-width: 9rem; padding: .5rem; } .inline-group .form-control { text-align: right; } .form-control[type="number"]::-webkit-inner-spin-button, .form-control[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" /> <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script> <div class="input-group inline-group"> <div class="input-group-prepend"> <button class="btn btn-outline-secondary btn-minus"> <i class="fa fa-minus"></i> </button> </div> <input class="form-control quantity" min="0" name="quantity" value="1" type="number"> <div class="input-group-append"> <button class="btn btn-outline-secondary btn-plus"> <i class="fa fa-plus"></i> </button> </div> </div>
长(初始)答案:
本机 input[type=number]控件不能跨浏览器显示样式。要实现跨浏览器/跨设备的目的,最简单、最安全的方法是:
input[type=number]
input[type="number"] { -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; } input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; }
... 它允许您使用您的自定义按钮,它可以链接到执行函数的自旋器(箭头)(.stepUp()和 .stepDown()) ,只要您保持输入的 type="number"。
.stepUp()
.stepDown()
type="number"
例如:
input[type="number"] { -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; } input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; } .number-input { border: 2px solid #ddd; display: inline-flex; } .number-input, .number-input * { box-sizing: border-box; } .number-input button { outline:none; -webkit-appearance: none; background-color: transparent; border: none; align-items: center; justify-content: center; width: 3rem; height: 3rem; cursor: pointer; margin: 0; position: relative; } .number-input button:before, .number-input button:after { display: inline-block; position: absolute; content: ''; width: 1rem; height: 2px; background-color: #212121; transform: translate(-50%, -50%); } .number-input button.plus:after { transform: translate(-50%, -50%) rotate(90deg); } .number-input input[type=number] { font-family: sans-serif; max-width: 5rem; padding: .5rem; border: solid #ddd; border-width: 0 2px; font-size: 2rem; height: 3rem; font-weight: bold; text-align: center; }
<div class="number-input"> <button onclick="this.parentNode.querySelector('input[type=number]').stepDown()" ></button> <input class="quantity" min="0" name="quantity" value="1" type="number"> <button onclick="this.parentNode.querySelector('input[type=number]').stepUp()" class="plus"></button> </div>
注意: 为了改变输入的值,需要找到它。为了提供灵活性,在上面的示例中,我将按钮和 <input>分组在一个共同的父级下,并使用该父级来查找 <input>(选择不依赖于它们的邻近性或 DOM 中的特定顺序)。上述方法 < em > 将把任何 input[type=number] < em > 兄弟更改为按钮 。如果不方便的话,可以使用其他方法从按钮中找到输入:
<input>
.querySelector('#some-id')
<button onclick="this.parentNode.querySelector('#some-id').stepUp()"></button>
.querySelector('.some-class')
<button onclick="this.parentNode.querySelector('.some-class').stepUp()"></button>
还要注意上面的例子只在 .parentNode中搜索,而不是在整个 document中搜索,这也是可能的: 即 onclick="document.getElementById('#some-id').stepUp()"
.parentNode
document
onclick="document.getElementById('#some-id').stepUp()"
previousElementSibling
nextElementSibling
<button onclick="this.previousElementSibling.stepUp()"></button>
<button onclick="$(this).prev()[0].stepUp()"></button>
使用 jQuery 时需要注意的一点是,stepUp()和 stepDown()方法放在 DOM 元素上,而不是 jQuery 包装器上。DOM 元素位于 jQuery包装器的 0属性中。
stepUp()
stepDown()
jQuery
0
关于 preventDefault()的注释 。单击 <form> 威尔中的 <button>触发表单提交。因此,如果像上面那样使用内部形式,onclick也应该包含 preventDefault();。例如:
preventDefault()
<form>
<button>
onclick
preventDefault();
<button onclick="$(this).prev()[0].stepUp();preventDefault()"></button>
但是,如果使用 <a>标记而不是 <button>标记,则没有必要这样做。此外,可以通过一个小的 JavaScript 代码片段对所有表单按钮进行全局设置:
<a>
var buttons = document.querySelectorAll('form button:not([type="submit"])'); for (i = 0; i < buttons.length; i++) { buttons[i].addEventListener('click', function(e) { e.preventDefault(); }); }
或者使用 jQuery:
$('form').on('click', 'button:not([type="submit"])', function(e){ e.preventDefault(); })
你可以很容易地将第一个设计转换为第二个设计,如下所示:
超文本标示语言
<div class="quantity"> <button class="btn minus1">-</button> <input class="quantity" id="id_form-0-quantity" min="0" name="form-0-quantity" value="1" type="number"> <button class="btn add1">+</button>
CSS
.quantity{ display:flex; width:160px; } /* it will support chrome and firefox */ .quantity input[type=number]::-webkit-inner-spin-button, .quantity input[type=number]::-webkit-outer-spin-button{ -webkit-appearance:none; } .quantity input,.quantity button{ width:50px; padding:.5em; font-size:1.2rem; text-align:center; font-weight:900; background:white; border:1px solid #aaa; } .quantity input{ border-left:none; border-right:none; }
我找到了一个好办法。只需旋转箭头键并将不透明度设置为0。然后在这些不可见的按钮上设置一个: after 和: before 元素。然后这些元素可以按照需要设置样式。
input[type="number"]::-webkit-outer-spin-button, input[type="number"]::-webkit-inner-spin-button { transform: rotate(90deg); height: 80px; opacity: 0; } .quantity-wrapper { position: relative; } .quantity-wrapper:after { content: "+"; position: absolute; right: 5px; height: 100%; top: 8px; pointer-events: none; } .quantity-wrapper:before { content: "-"; position: absolute; left: 5px; height: 100%; top: 8px; }
<div class="quantity-wrapper"> <input class="quantity" id="id_form-0-quantity" min="0" name="form-0-quantity" value="1" type="number"> </div>
数字输入可以通过以下我最近发现的脚本以这种方式程式化:
演示。
这个脚本是一个超轻量级(1.49 kb 未压缩,0.71 kb 压缩,0.35 kb 压缩) ,可用和可靠的数量输入,取代了可怕的,精细的小输入按钮内置的数字输入在浏览器中。它是使用 ES6模块编写的,因此需要为较老的浏览器进行翻译。
作者的知识库是 给你。 希望这有所帮助;)
编辑: 或者,如果您希望使用向上/向下箭头按钮,而不是加/减按钮,则使用 另一个基于 jQuery 的解决方案。
$(document).ready(function () { jQuery('<div class="quantity-nav"><button class="quantity-button quantity-up"></button><button class="quantity-button quantity-down"></button></div>').insertAfter('.quantity input'); jQuery('.quantity').each(function () { var spinner = jQuery(this), input = spinner.find('input[type="number"]'), btnUp = spinner.find('.quantity-up'), btnDown = spinner.find('.quantity-down'), min = input.attr('min'), max = input.attr('max'); btnUp.click(function () { var oldValue = parseFloat(input.val()); if (oldValue >= max) { var newVal = oldValue; } else { var newVal = oldValue + 1; } spinner.find("input").val(newVal); spinner.find("input").trigger("change"); }); btnDown.click(function () { var oldValue = parseFloat(input.val()); if (oldValue <= min) { var newVal = oldValue; } else { var newVal = oldValue - 1; } spinner.find("input").val(newVal); spinner.find("input").trigger("change"); }); }); });
body { display: flex; justify-content: center; align-items: center; min-height: 100vh; min-width: 100vw; background: #34495E; font-size: 1rem; } .quantity { position: relative; } input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; } input[type=number] { -moz-appearance: textfield; } .quantity input { width: 45px; height: 42px; line-height: 1.65; float: left; display: block; padding: 0; margin: 0; padding-left: 20px; border: none; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08); font-size: 1rem; border-radius: 4px; } .quantity input:focus { outline: 0; } .quantity-nav { float: left; position: relative; height: 42px; } .quantity-button { position: relative; cursor: pointer; border: none; border-left: 1px solid rgba(0, 0, 0, 0.08); width: 21px; text-align: center; color: #333; font-size: 13px; font-family: "FontAwesome" !important; line-height: 1.5; padding: 0; background: #FAFAFA; -webkit-transform: translateX(-100%); transform: translateX(-100%); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } .quantity-button:active { background: #EAEAEA; } .quantity-button.quantity-up { position: absolute; height: 50%; top: 0; border-bottom: 1px solid rgba(0, 0, 0, 0.08); font-family: "FontAwesome"; border-radius: 0 4px 0 0; line-height: 1.6 } .quantity-button.quantity-down { position: absolute; bottom: 0; height: 50%; font-family: "FontAwesome"; border-radius: 0 0 4px 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="quantity"> <input type="number" min="1" max="9" step="1" value="1"> </div>
下面是另一个版本,基于@Tao 的回答,使用 font-Awesome:
input[type="number"] { -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; } input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; } .number-input { border: 2px solid #ddd; display: inline-flex; } .number-input, .number-input * { box-sizing: border-box; } .number-input button { outline:none; -webkit-appearance: none; background-color: transparent; border: none; align-items: center; justify-content: center; width: 3rem; height: 3rem; cursor: pointer; margin: 0; position: relative; } .number-input button:after { display: inline-block; position: absolute; font-family: "Font Awesome 5 Free"; font-weight: 900; content: '\f077'; transform: translate(-50%, -50%) rotate(180deg); } .number-input button.plus:after { transform: translate(-50%, -50%) rotate(0deg); } .number-input input[type=number] { font-family: sans-serif; max-width: 5rem; padding: .5rem; border: solid #ddd; border-width: 0 2px; font-size: 2rem; height: 3rem; font-weight: bold; text-align: center; }
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" integrity="sha512-HK5fgLBL+xu6dm/Ii3z4xhlSUyZgTT9tuc/hSrtw6uzJOvgRr2a9jyxxT1ely+B+xFAmJKVSTbpM/CuL7qxO8w==" crossorigin="anonymous" /> <div class="number-input"> <button onclick="this.parentNode.querySelector('input[type=number]').stepDown()" class="minus"></button> <input class="quantity" min="0" name="quantity" value="1" type="number"> <button onclick="this.parentNode.querySelector('input[type=number]').stepUp()" class="plus"></button> </div>
这个代码可以帮助你
$.fn.spinInput = function (options) { var settings = $.extend({ maximum: 1000, minimum: 0, value: 1, onChange: null }, options); return this.each(function (index, item) { var min = $(item).find('>*:first-child').first(); var max = $(item).find('>*:last-child').first(); var v_span = $(item).find('>*:nth-child(2)').find('span'); var v_input = $(item).find('>*:nth-child(2)').find('input'); var value = settings.value; $(v_input).val(value); $(v_span).text(value); async function increment() { value = Number.parseInt($(v_input).val()); if ((value - 1) > settings.maximum) return; value++; $(v_input).val(value); $(v_span).text(value); if (settings.onChange) settings.onChange(value); } async function desincrement() { value = Number.parseInt($(v_input).val()); if ((value - 1) < settings.minimum) return; value-- $(v_input).val(value); $(v_span).text(value); if (settings.onChange) settings.onChange(value); } var pressTimer; function actionHandler(btn, fct, time = 100, ...args) { function longHandler() { pressTimer = window.setTimeout(function () { fct(...args); clearTimeout(pressTimer); longHandler() }, time); } $(btn).mouseup(function () { clearTimeout(pressTimer); }).mousedown(function () { longHandler(); }); $(btn).click(function () { fct(...args); }); } actionHandler(min, desincrement, 100); actionHandler(max, increment, 100) }) } $('body').ready(function () { $('.spin-input').spinInput({ value: 1, minimum: 1 }); });
:root { --primary-dark-color: #F3283C; --primary-light-color: #FF6978; --success-dark-color: #32A071; --sucess-light-color: #06E775; --alert-light-color: #a42a23; --alert-dark-color: #7a1f1a; --secondary-dark-color: #666666; --secondary-light-color: #A6A6A6; --gold-dark-color: #FFA500; --gold-light-color: #FFBD00; --default-dark-color: #1E2C31; --default-light-color: #E5E5E5; } .fx-row { display: flex; flex-direction: row; flex-wrap: wrap; } .fx-colum { display: flex; flex-direction: column; flex-wrap: wrap; } .fx-colum.nowrap, .fx-row.nowrap { flex-wrap: nowrap; } .fx-row.fx-fill>*, .fx-colum.fx-fill>* { flex-grow: 1; } .spin-input { border: 1px solid var(--secondary-light-color); } .spin-input>div:first-child { cursor: pointer; border-right: 1px solid var(--secondary-light-color); } .spin-input>div:first-child:active { transform: translate3d(1px, 0px, 1px) } .spin-input>div:last-child { flex: none; border-left: 1px solid var(--secondary-light-color); cursor: pointer; } .spin-input>div:last-child:active { transform: translate3d(1px, 0px, 1px) } .icon { font-weight: bold; text-align: center; vertical-align: middle; padding: 12px; font-size: 28px; } .icon.primary, .icon.primary .ci { color: var(--primary-dark-color); } .icon.reactive:hover .ci { color: var(--primary-light-color); } .hidden { display: none; }
<script src="https://releases.jquery.com/git/jquery-3.x-git.min.js"></script> <div class="spin-input nowrap fx-row fx-fill" > <div class="icon reactive"> <span class="ci ci-minus">-</span> </div> <div class="icon"> <span>0</span> <input type="text" class="hidden" value="0"> </div> <div class="icon reactive"> <span class="ci ci-plus">+</span> </div> </div>
259)