在 Keydown 上调用函数

问题描述 投票:0回答:2

文档准备好后,此函数

performNext
调用正常:

$(document).ready(function() {
  performNext();
});

performNext
函数隐藏当前字段集并显示下一个字段集,我的问题是另一个问题的扩展,具有我问的最小可重现示例here

但是它没有被调用

keydown
:

$(document).on("keydown", (e) => {
  if (e.key === "F1") {
    e.preventDefault();
    performNext();
    console.log("F1");
  };
});

执行Next函数:

function performNext() {
    console.log("performNext started");

    var current_fs, next_fs; //fieldsets
    var opacity;
    var current = 1;
    var steps = $("fieldset").length;

    $(".next").click(function() {

        $current_fs = $(this).closest("fieldset");
        $next_fs = $current_fs.next();

        //show the next fieldset
        $next_fs.show();
        //hide the current fieldset with style
        $current_fs.animate({
            opacity: 0
        }, {
            step: function(now) {
                // for making fielset appear animation
                opacity = 1 - now;

                $current_fs.css({
                    'display': 'none',
                    'position': 'relative'
                });
                $next_fs.css({
                    'opacity': opacity
                });
            },
            duration: 500
        });
    });

    $("#msform").on("submit", function(e) {
        e.preventDefault()
    })
    
    console.log("performNext ended");

}

尝试过这个答案但不起作用。

console.log("performNext started"); 
console.log("performNext ended"); 
console.log("F1");

全部登录控制台,因此映射 F 键有效。我错过了什么?

javascript jquery keyboard-events
2个回答
0
投票

你的逻辑不好。您在功能聊天中创建点击和提交处理程序可能会被多次调用。这些事件将添加到现有事件之上。因此

$(".next").click(function() {
$("#msform").on("submit", function(e) {
不应该是
performNext
函数的一部分。此外,使用 CSS
$current_fs.animate({
属性,只需几行 CSS 代码即可实现 13 行
transition
。相反,使用索引来导航字段集并将所需的索引存储在按钮的
data-*
属性中:

const $msForm = $("#msform");
const $fieldset = $msForm.find("fieldset");
const stepsTotal = $fieldset.length; // i.e: 4
let stepCurrent = 0; // Start at step index 0

// Instead of "performNext()", use a more flexible goToStep() 
// function that accepts a step index:
function goToStep(index) {
  const $step = $fieldset.eq(index);
  $fieldset.not($step).removeClass("is-active");
  $step.addClass("is-active");
}

// Got to step index (stored in button's data-* attribute)
$("[data-gotostep]").on("click", function() {
  stepCurrent = Number($(this).data("gotostep"));
  goToStep(stepCurrent);
});

// Go to next step
$(document).on("keydown", (evt) => {
  if (evt.originalEvent.key === "F1") {
    evt.preventDefault();
    stepCurrent += 1;
    stepCurrent = Math.min(stepCurrent, stepsTotal - 1); 
    goToStep(stepCurrent);
  };
});

// Init:
goToStep(0); // Show first step

// Other stuff...
$msForm.on("submit", function(evt) {
  evt.preventDefault()
});
#msform fieldset {
  position: absolute;
  width: 100%;
  visibility: hidden;
  opacity: 0;
  transition: 0.5s; /* instead of jQuery .animate() */
}

#msform fieldset.is-active {
  position: relative;
  visibility: visible;
  opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<form id="msform">
  <fieldset>
    <label>1/3 Your name:<br><input name="name" type="text"></label><br>
    <button type="button" data-gotostep="1">Next</button>
  </fieldset>
  <fieldset>
    <button type="button" data-gotostep="0">Back</button><br>
    <label>2/3 Your surname<br><input name="surname" type="text"></label><br>
    <button type="button" data-gotostep="2">Next</button>
  </fieldset>
  <fieldset>
    <button type="button" data-gotostep="1">Back</button><br>
    <label>3/3 Your age<br><input name="age" type="number"></label><br>
    <button type="button" data-gotostep="3">Next</button>
  </fieldset>
  <fieldset>
    <button type="submit" data-gotostep="0">Start all over</button><br>
    <label>You're all set!</label><br>
    <button type="submit">Finish</button>
  </fieldset>
</form>


-1
投票

如果您想按F1并关注下一个

<fieldset>
,您可以尝试以下步骤:

$(document).ready(function() {
  performNext();
});

$(document).on('keydown', (e) => {
  if (e.key === 'F1') {
    e.preventDefault();
    performNext();
  };
});

function performNext() {
  var $focusedInput = $(':focus');
  if ($focusedInput.length === 0) {
    $('form > fieldset input').first().focus();
    return; // Short-circuit
  }
  var $currFieldset = $focusedInput.closest('fieldset');
  var $nextFieldset = $currFieldset.next('fieldset');
  // Wrap around
  if ($nextFieldset.length === 0) {
    var $form = $currFieldset.closest('form');
    $nextFieldset = $form.find('fieldset:first-child'); 
  }
  $nextFieldset.find('input').first().focus();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="#">
  <fieldset id="name-fs">
    <legend>What is your name?</legend>
    <label for="given-name-txt">Given name:</label>
    <input type="text" id="given-name-txt" name="given-name" placeholder="Jane" />
    <label for="surname-txt">Surname</label>
    <input type="text" id="surname-txt" name="surname" placeholder="Doe" />
  </fieldset>
  <fieldset id="agree-fs">
    <legend>Do you agree?</legend>
    <input type="checkbox" id="agree-cbx-yes" name="agree" value="true" />
    <label for="agree-cbx-yes">I agree</label>
    <input type="checkbox" id="agree-cbx-no" name="agree" value="false" />
    <label for="agree-cbx-no">No</label>
  </fieldset>
</form>

© www.soinside.com 2019 - 2024. All rights reserved.