Обработка событий
Следующая демонстрация при запуске события "input"
* на <input type="number">
изменит <select>
<option>
в соответствии со значением <input type="number">
, находящимся в динамическом * Диапазон 1103 *. Хотя демонстрационная версия имеет жестко заданные значения для data-min
и data-max
, функция обратного вызова cbd()
может обрабатывать любые допустимые значения, установленные динамически для каждой пары data-min/max
, назначенной каждому <option>
.
* (преимущество события "input"
над событием "change"
заключается в том, что оно происходит мгновенно)
КСТАТИ никогда используйте атрибут on-event:
? Пример того, что НЕ нужно делать для обработки событий с jQuery или JavaScript
<button onclick="functionName()">LAME</button>
...
function functionName(event) {...
При использовании jQuery всегда используйте правильный метод (например, .click()
) или делегируйте события с помощью метода .on()
(я настоятельно рекомендую использовать последние 99% времени.)
? Пример наиболее эффективного способа обработки событий с jQuery
<button class='btn'>NOT LAME</button>
...
$('.btn').on('click', functionName)
function functionName(event) {...
Демонстрация широко комментируется, также есть ссылки.
Демонстрация
// Delegate input#cdbData to the input event -- callback is cdb()
$(function() {
$('#cbdData').on('input', cbd);
});
// Callback function/Event handler passes Event Object by default
function cbd(event) {
/*
Dereferenced jQuery Object $('#cbdRate') to DOM Object
NOTE: Plain JavaScript equivelant would be:
const select = document.getElementById('cdbRate');
or
const select = document.querySelector('#cdbRate');
*/
const select = $('#cbdRate')[0];
// Collect all select#cdbRate option into an Array
const rates = [...select.options];
/*
Store the value of input#cdbData as a real Number in a variable
IMPORTANT NOTE: input#cdbData is $(this)
*/
let float = parseFloat($(this).val());
/*
Ensure that integer values are suffixed with ".0"
(this is just for aesthetics and is not required)
*/
$(this).val(float.toFixed(1));
/*
IF input#cdbData value is :out-of-range...
add .out class and remove .in class
OTHERWISE...
do vice versa of the above actions
(this is just for aesthetics and is not required)
*/
if ($(this).is(':out-of-range')) {
$(this).addClass('out').removeClass('in');
} else {
$(this).addClass('in').removeClass('out');
}
/*
.flatMap() method (a combo of .map() and .flat() methods), will run a
function over each element within a given array and will return a flattened
array of results. NOTE: the callback function returns an Array of an Array --
so the final return will be an Array of Arrays
(aka two dimensional array, aka data-table)
On each select#cdbRate option...
Get the value of data-min convert it into a real Number and add it to the
minMax sub-Array[0]
Then do likewise for data-max and minMax sub-Array[1]
Final returned minMax Array has the following pattern:
minMax = [['', ''], [data-min, data-max], [data-min, data-max], [data-min, data-max]];
Each sub-Array represents the min/max values of an <option>
Use the .data() jQuery method to set/get data-* attributes
*/
let minMax = rates.flatMap((opt, idx) => {
return idx === 0 ? [
["", ""]
] : [
[Number($(opt).data('min')), Number($(opt).data('max'))]
]
});
// Get length of minMax Array
let size = minMax.length;
// Get the least and the greatest values of minMax Array
let min = minMax[1][0];
let max = minMax[size - 1][1];
// Assign min and max values to input#cbdData
this.min = min;
this.max = max;
/*
Iterate through rates Array...
IF `float` is greater OR equal to current value of minMax sub-Array[0]
AND...
IF `float` is less OR equal to current value of minMax sub-Array[1]...
then select the current <option>
OR IF `float` is not a Number OR `float` is greater than the last value of
minMax Array[1]...
then select <option> at index 0
IMPORTANT NOTE: The dereferenced jQuery Object `select` must be used because
the Plain JavaScript property .selectedIndex and .selected are not recognized
by jQuery
*/
for (let [index, option] of rates.entries()) {
if (float >= minMax[index][0] && float <= minMax[index][1]) {
option.selected = true;
} else if (Number.isNaN(float) || float > max) {
select.selectedIndex = 0;
}
}
// Uncomment the comment below to review the log of minMax Array
// log(minMax);
// Stop event bubbling and terminate function
return false;
}
// Optional utility function (not required)
function log(data) {
return console.log(JSON.stringify(data));
}
:root {
font: 400 3vw/6vh Consolas
}
.form-control {
display: inline-block;
font: inherit;
font-size: 1rem
}
#cbdData {
width: 6ch;
text-align: center;
}
.in {
background: initial;
}
.out {
background: tomato;
}
<input id="cbdData" name="cbdData" class="form-control" type="number" step="0.1">
<select id="cbdRate" name="cbdRate" class="form-control">
<option value="" default>-----</option>
<option data-min="0.0" data-max="0.0" value='{D6C3B40F-9559-473A-8B24-44A911A82D52}'>CBD 0</option>
<option data-min="0.1" data-max="1.9" value='{4FD86F65-74BA-4F10-9D5F-57281ECFC76A}'>CBD 1</option>
<option data-min="2.0" data-max="2.9" value='{3AC0F33C-D48E-4C10-B64A-B5473AF8DB98}'>CBD 2</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Ссылки
Делегирование событий с помощью jQuery .on()
метод
Разыменование jQuery Объект в объект DOM
Создание или клонирование массив через оператор спреда
$(this)
.flatMap()
Разрушающие массивы с .entries()
и for...of
l oop
.selectedIndex
и .selected
свойства и .options
HTML Коллекция