【问题标题】:preventDefault does not work on focus eventpreventDefault 不适用于焦点事件
【发布时间】:2011-07-18 22:40:21
【问题描述】:

我正在尝试设计一个表单,如果它具有某个类,则用户不应该能够与任何输入进行交互。由于各种原因,我想避免使用“禁用”属性。我试图阻止焦点事件的默认设置,但它不起作用。我在最新版本的 Firefox、Chrome 和 Android 中对此进行了测试。我尝试了各种事件组合,例如“单击更改触摸启动焦点聚焦”。我试着把“return false;”在处理程序中。有谁知道为什么会发生这种情况以及如何使其发挥作用?

<!DOCTYPE html>
<html><head>
<title>input test</title>
</head>
<body>
<form class="disabled">
  <input type="text">
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$(".disabled :input").bind("focus", function(e) {
  e.preventDefault();
});
</script>
</body></html>

你可以在http://jsfiddle.net/54Xka/看到一个例子

编辑:这将在一个主要用于移动浏览器的网站上。我计划在显示模式对话框时禁用输入。模态对话框是使用我自己的代码实现的。显示和隐藏 div 是非常简单的事情。

编辑 2:这是我现在拥有的:

$(".disabled :input").live({
  focus: function() {
    $(this).blur();
  },
  change: function(e) {
    e.preventDefault();
  }
});

它有一些小的美学问题,但它有效。当我有更多时间时,我可能会尝试使用透明 gif 的 jfriend00 的想法,或者类似于 jQuery UI 对话框小部件所做的事情,或者可能实际上使用 jQuery UI 对话框小部件来实现对话框。

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    您无法阻止默认设置,但您可以立即将焦点恢复到先前获得焦点的元素(这与该元素没有获得焦点几乎相同)。这很容易实现,因为 FocusEvent contains referencerelatedTarget 属性指向先前聚焦的元素。

    element.addEventListener('focus', (e) => {
      if (e.relatedTarget) {
        e.relatedTarget.focus();
      }
    });
    
    

    【讨论】:

    • 您的解决方案实际上帮助我防止了下拉菜单以获取文本区域之外的焦点。下拉菜单旨在从许多选项中选择一个文本,以插入光标在文本区域中的位置。谢谢
    【解决方案2】:

    对于文本字段,最好将它们设置为只读。这仍然允许制表符和复制,但不能修改。

    <input type="text" readonly="readonly" value="Can't change me">
    

    如果您还想停止制表符,那么正常运行的网页支持在页面上用于键盘访问的对象之间进行键盘导航。这意味着任何只是试图阻止焦点的选项都会中断任何通过键盘导航网页的尝试。因此,最好通过告诉浏览器该对象不用作制表位来阻止项目之间的制表符,并且当按下制表符键时它会很高兴地跳过它。您可以通过在对象上将 tabIndex 设置为 -1 来实现。键盘导航将永远不会停止,但会按预期工作。

    <input type="text" readonly="readonly" tabIndex="-1" value="Can't change me or tab to me">
    

    如果您使用的对象类型与文本字段不同,请更具体地说明对象的类型。在使用与网页的预期功能相混淆的脚本之前,您应该追求支持您预期行为的 HTML 属性。如果您不打算让用户与之交互,那么使用除 usereditable 标记之外的其他东西来仅显示数据(如 div)也可能是有意义的。

    您可以在此处查看 readonly 和 tabIndex 字段的示例:http://jsfiddle.net/jfriend00/9wWkQ/

    现在,听起来我们有变动的规格。现在你说你甚至不希望他们能够选择文本。即使在不可编辑的普通 div 中也可以做到这一点。如果您想阻止所有用户访问,甚至包括选择单个字段的文本,那么您将不得不求助于将空白透明 gif 图像放在表单区域的顶部。这将阻止所有鼠标与字段的交互,并且结合 readonly 和 tabIndex 也应该阻止所有键盘访问。

    【讨论】:

    • 谢谢。我没有想到tab键。 readonly 属性不是一个选项,因为我试图阻止用户与表单交互。 tabindex 是我可以考虑的。
    • 其实tabindex属性本身并不是一个选项。用户仍然可以通过触摸来选择输入。
    • 如果您真的想阻止所有交互,我会在上面的答案中添加一个选项。 readonly 属性可防止项目的所有更改。为什么这不是您的问题的解决方案的一部分?
    • 我正在尝试实现一个模态对话框,它可以防止对话框中的元素被聚焦。
    • 然后,执行此操作的标准方法是在整个页面上放置一个透明的 gif 图像(您可以缩放 1x1 图像以覆盖页面)并将您的对话框放在上面。如果您在问题中这么说,我们本可以更快地解决这个问题。
    【解决方案3】:

    你可以使用

    this.blur();
    

    ...改为。

    【讨论】:

    • 我赞成您的回答,因为它很有帮助。但是,它有一些小的审美问题。在 iPhone 上,如果我单击输入,屏幕键盘会出现几分之一秒。这并不可怕,但它有点分散注意力。在几个 Android 设备上,如果我在输入密码时尝试它,有时它看起来像是专注的,但不允许我输入任何内容。在我的 Droid 2 上,它有一个物理键盘,按键会在几分之一秒内显示我输入的字符,然后变回来。我希望有更好的解决方案,但如果我没有找到更好的解决方案,我可能会接受。
    • 不幸的是,焦点事件是不可取消的。你能解释一下为什么你不喜欢使用 disabled-attribute 吗?
    • 我试图避免禁用属性,因为它可能很麻烦。当我显示对话框时,我将不得不禁用所有输入。隐藏对话框时,必须将输入的禁用属性重置为其原始值(因为某些输入可能由于其他原因而被禁用)。因此,我需要一种方法来记住禁用属性的值。这是我可以做的事情,但可能需要更多代码。我想知道是否有更简单和更优雅的方式。
    • 我不确定您是否可以选择,但最简单的方法应该是隐藏完整的表单。隐藏的元素无法聚焦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多