Reputation: 354
I want my Bootstrap tab switchers to stop eating Up and Down keys, so the page could scroll instead, as if they are not focused.
$('input[type="radio"][role="tab"]').on('keydown keyup', function (e)
{
if (e.key == 'ArrowDown' || e.key == 'ArrowUp')
{
e.stopImmediatePropagation();
e.preventDefault();
// So far so good.
$('body')[0].dispatchEvent(new KeyboardEvent(e.type, { 'key': e.key }));
// No effect :(
}
});
The code above made the controls stop responding to Up and Down, but unfortunately the page doesn't scroll nevertheless.
UPD Here's MRE: https://getbootstrap.com/docs/5.3/forms/checks-radios/#radio-toggle-buttons. Click any of the buttons (“Checked” or “Radio”) and try pressing ←, ↑, ↓ and →. I'm fine with ← and →, but I want the page to scroll, when I press ↓ and ↑.
UPD2 This kind of works:
$('input[type="radio"][role="tab"]').on('keydown keyup', function (e)
{
if (e.key == 'ArrowDown' || e.key == 'ArrowUp')
{
e.stopImmediatePropagation();
e.preventDefault();
document.activeElement.blur();
}
});
After the first pressing on ↓ or ↑, the element loses focus, then the page starts scrolling as usual. Not exactly what I wanted, but it's even better from UX viewpoint, I guess.
Upvotes: 0
Views: 80
Reputation: 22237
I don't think re-dispatching the keyboard event will work. It might work for entering text into a field but probably not for scrolling a document.
I suggest you stick with preventDefault, and take control of the scroll yourself. You might need to change that part of the code to suit your page, but here's my example.
$('input[type="radio"][role="tab"]').on('keydown keyup', function (e)
{
if (e.key == 'ArrowDown' || e.key == 'ArrowUp')
{
e.preventDefault();
if (e.type === 'keydown') {
window.scrollBy({
left: 0,
top: e.key === 'ArrowDown' ? 30 : -30,
behavior: "smooth"
});
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<p>prior content</p>
<input type="radio" role="tab" class="btn-check" name="options" id="option1" autocomplete="off" checked>
<label class="btn btn-secondary" for="option1">Checked</label>
<input type="radio" role="tab" class="btn-check" name="options" id="option2" autocomplete="off">
<label class="btn btn-secondary" for="option2">Radio</label>
<input type="radio" role="tab" class="btn-check" name="options" id="option3" autocomplete="off" disabled>
<label class="btn btn-secondary" for="option3">Disabled</label>
<input type="radio" role="tab" class="btn-check" name="options" id="option4" autocomplete="off">
<label class="btn btn-secondary" for="option4">Radio</label>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
<p>following content</p>
Upvotes: 1