HTMLInputElement
Input type "text"
не имеет атрибутов min
max
или step
, поэтому ваш HTML абсолютно неверно . Старайтесь не писать Работает, я фреймворк -код. Соблюдайте стандарты W3 C. Используйте type="number"
(CSS псевдонимы могут помочь вам удалить стрелки по умолчанию spinner из таких элементов)
Также step
может быть плавающими. Уважайте это и используйте parseFloat()
в JS
CSS Flex для выравнивания материала
Кажется, вы знаете о CSS -flex, используйте его! Высота, значит - строка-высота ... 19? 20? 23px? Нет. Просто используйте flex .
CSS! Important
!important
является признаком плохого стиля кодирования, и его следует оставить только для Bootstrap. Или в надежде переопределить Bootstrap стилей - или в тех случаях, когда разработчики действительно знают, что они делают.
jQuery Плагины
jQuery плагины , я предлагаю прочитать DOCS и получить более глубокие знания о том, как работают плагины. Почти каждый jQuery метод - это плагин. .hide()
, .addClass()
... Я не буду их всех считать. Плагины объединяются в цепочки .removeClass("foo").stop().fadeTo(1)
, и таким же должен быть ваш .number()
плагин.
Чтобы достичь цепочки, вы просто возвращаете привязку this
. PS: это не jQuery ... так работает JS.
jQuery Плагины не предназначены для вызова внутри $.each()
l oop. $()
уже представляет собой коллекцию узлов DOM, заключенных в объект jQuery. Не нужно .each()
. То же самое: вы бы предпочли использовать $('a').css({color:'blue'})
вместо $('a').each(){ $(this).css({color: 'blue'}); });
. Тот же эффект, меньше кода. Плагины.
jQuery Готовность к DOM
jQuery(function($) { }); // DOM ready and $ alias in scope
Или, если вас не волнует ± IE, или вы используете синтаксис ES6 и набор инструментов, например Babel, чем: jQuery($ => { })
будет достаточно.
jQuery $ Object Constructor
jQuery позволяет вам определить HTMLElement , который в конечном итоге станет новым элементом DOM, обернутым всеми jQuery полномочия, методы. Это означает, что если вместо передачи селектора вы передадите более сложную строку, похожую на тег (скажем: $("<span/>", {});
- jQuery, создаст элемент inMemory SPAN и позволит вам использовать второй параметр {}
для большинства доступных jQuery методов для этого $ Element . Давайте воспользуемся этим!
jQuery обратные вызовы плагина
Если вы хотите предоставить обратный вызов после того, как пользователь изменит входное значение, предоставьте метод обратного вызова . Не заставляйте программиста писать новый код спагетти , придерживайтесь в объем доступных внутренних методов плагина.
Значения сумм элементов
Для суммирования значений элементов вы можете использовать Array.prototype.reduce , просто убедитесь, что вы используете initialValue
для предотвращения возможных ошибок типа.
Пример
Наконец, вот упрощенный CSS и улучшенный JS:
(function($) {
$.fn.number = function(customOptions) {
const options = $.extend(true, {
containerTag: "div",
containerClass: "number-style",
minusClass: "number-minus", // consistency in wording!
minusText: "-", // Give power to the user!
plusClass: "number-plus",
plusText: "+",
btnTag: "button",
onChange() {}, // Provide a nifty callback!
}, customOptions);
this.each(function() { // Use .each() here!
const $input = $(this);
let val = parseFloat($input.value || 0); // floats!
const min = parseFloat($input.attr("min"));
const max = parseFloat($input.attr("max"));
const step = parseFloat($input.is("[step]") ? $input.attr("step") : 1);
const handleStyles = () => {
$minus.toggleClass('disabled', val <= min);
$plus.toggleClass('disabled', val >= max);
};
const change = () => {
val = Math.max(min, Math.min(max, val)); // Keep val in range.
$input.val(val); // Update input value
handleStyles(); // Update styles
options.onChange.call($input[0], val); // Trigger a public callback
}
const decrement = () => {
val -= step;
change();
};
const increment = () => {
val += step;
change();
};
const $minus = $(`<${options.btnTag}>`, {
type: "button",
title: "Decrement",
class: options.minusClass,
text: options.minusText,
on: {
click: decrement
}
});
const $plus = $(`<${options.btnTag}>`, {
class: options.plusClass,
title: "Increment",
text: options.plusText,
on: {
click: increment
}
});
const $wrapper = $(`<${options.containerTag}>`, {
class: options.containerClass,
});
$input.after($wrapper);
$wrapper.append($minus, $input.detach(), $plus); // Append all
handleStyles(); // handle initial styles
});
return this; // make your plugin chainable!
};
})(jQuery);
jQuery(function($) { // DOM ready and $ alias in scope
const $quantityInp = $('.quantity-input'); // Cache your elements!
const $dropdown = $('#yolcudropdown'); // Cache your elements!
$quantityInp.number({
onChange(val) { // our custom onChange callback!
const tot = $quantityInp.get().reduce((acc, el) => {
acc += parseFloat(el.value);
return acc;
}, 0);
$dropdown.text(tot);
}
});
});
/* QuickReset */ * { margin:0; box-sizing:border-box; }
.number-style input::-webkit-outer-spin-button,
.number-style input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
.number-style {
display: flex;
}
.number-style > * {
height: 2em;
min-width: 2em;
border-radius: 2em;
display: flex; /* Use flex. */
justify-content: center;
text-align: center;
border: 0;
background: #ddd;
}
.number-style button {
background: #fff;
box-shadow: inset 0 0 0 2px #ccc;
cursor: pointer;
user-select: none;
/* no highlight, please! */
}
.number-style button:active {
background: #0bf;
}
.number-style input {
background: #e00f23;
color: #fff;
margin: 0 5px;
}
.number-style .disabled {
opacity: 0.2;
cursor: default;
}
/* Custom overrides: */
.number-style>* {
width: 2em;
/* just for roundness */
}
<input class="quantity-input" type="number" value="0" step="1" min="0" max="10">
<input class="quantity-input" type="number" value="0" step="1" min="0" max="10">
<div id="yolcudropdown">0</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
Дополнительное чтение:
И PS: это «количество» , а не «количество»