禁用输入上的事件

Posted

技术标签:

【中文标题】禁用输入上的事件【英文标题】:Event on a disabled input 【发布时间】:2011-03-07 05:33:55 【问题描述】:

显然禁用的<input> 没有被任何事件处理

有没有办法解决这个问题?

<input type="text" disabled="disabled" name="test" value="test" />
$(':input').click(function () 
    $(this).removeAttr('disabled');
)

在这里,我需要点击输入来启用它。但是如果我不激活它,输入就不应该发布。

【问题讨论】:

这是一个不错的选择blog.pengoworks.com/index.cfm/2010/4/23/… 您可以使用 CSS-pretend-disable 并遍历 onSubmit 处理程序中的输入,从而真正禁用未激活的输入。 对读者的补充说明:如果您不介意输入beign 张贴,只需使用readonly 而不是disabled。我知道这不是 OP 所要求的,但有人可能和我处于同样的境地...... 【参考方案1】:

禁用的元素不会触发鼠标事件。大多数浏览器会将源自禁用元素的事件向上传播到 DOM 树,因此事件处理程序可以放置在容器元素上。然而,Firefox 并没有表现出这种行为,当你点击一个被禁用的元素时它什么都不做。

我想不出更好的解决方案,但为了实现跨浏览器的完全兼容性,您可以在禁用的输入之前放置一个元素,然后点击该元素。这是我的意思的一个例子:

<div style="display:inline-block; position:relative;">
  <input type="text" disabled />
  <div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div>
</div>​

jq:

$("div > div").click(function (evt) 
    $(this).hide().prev("input[disabled]").prop("disabled", false).focus();
);​

示例:http://jsfiddle.net/RXqAm/170/(更新为使用带有 prop 而不是 attr 的 jQuery 1.7)。

【讨论】:

小事:如果您使用没有值的disabled 属性,这意味着html 而不是XHTML,在这种情况下,结束斜杠是不必要的。 @Tim:确实没有必要,但它仍然是有效的 HTML。这只是一种习惯的力量,我觉得它看起来更好。 谢谢安迪,这很聪明。没有更简单的吗?你知道为什么禁用的输入无法处理吗? 这没有意义:任何其他 html 元素都处理鼠标事件,为什么不是禁用元素(例如 mouseenter 等) 您可以通过在 CSS 中添加 input[disabled] pointer-events:none 来阻止禁用元素“丢弃”您的点击。然后单击的行为就像您单击父元素一样。恕我直言,这是最简单、最干净的解决方案,但不幸的是,它仅适用于支持 pointer-events CSS 属性的浏览器:caniuse.com/#search=pointer-events【参考方案2】:

在某些浏览器中禁用元素“吃掉”点击 - 它们既不响应它们,也不允许它们被元素或其任何容器上的任何位置的事件处理程序捕获。

恕我直言,“修复”此问题的最简单、最干净的方法(如果您确实需要像 OP 那样捕获对禁用元素的点击)只需将以下 CSS 添加到您的页面:

input[disabled] pointer-events:none

这将使对禁用输入的任何点击都落入父元素,您可以在其中正常捕获它们。 (如果您有多个禁用的输入,您可能希望将每个输入放入自己的单独容器中,如果它们尚未以这种方式布置 - 额外的 &lt;span&gt;&lt;div&gt;,比如说 - 只是为了做到这一点很容易区分点击了哪个禁用的输入)。


缺点是这个技巧很遗憾不适用于不支持pointer-events CSS 属性的旧浏览器。 (它应该适用于 IE 11、FF v3.6、Chrome v4):caniuse.com/#search=pointer-events

如果您需要支持旧版浏览器,则需要使用其他答案之一!

【讨论】:

我不确定input[disabled] 是否也会匹配被 javascript (element.disabled = true;) 禁用的元素,但它似乎确实如此。无论如何,我找到了input:disabled 清洁工。 这似乎是一个很好的解决方案,但在 IE11 中对我不起作用!您还说 FF 38+ 和 Chrome 31+,但您的 caniuse 链接说 FF 3.6+ 和 Chrome 4+? @user764754 ...我的错误,我没有意识到我需要点击caniuse页面上的“显示全部”才能获得早期的浏览器版本!已经解决了。至于 IE11,我刚刚对其进行了测试,它运行良好(有关代码,请参阅 jsfiddle.net/7kkszq1c/1,但由于某种原因,jsFiddle 站点在 IE11 中对我不起作用,我不得不将其粘贴到 .htm 文件中) 感谢您的更新!与此同时,我还观察到它可以在 IE11 的网站上运行,但不能在 jsfiddle 上运行。也许是因为 jsfiddle iframe... @Protectorone :disabled 是自 CSS 3 以来的伪类:w3.org/TR/css3-selectors/#UIstates【参考方案3】:

也许您可以将字段设为只读并在提交时禁用所有只读字段

$(".myform").submit(function(e) 
  $("input[readonly]").prop("disabled", true);
);

输入(+脚本)应该是

<input type="text" readonly="readonly" name="test" value="test" />
$('input[readonly]').click(function () 
  $(this).removeAttr('readonly');
);

一个活生生的例子:

$(".myform").submit(function(e) 
  $("input[readonly]").prop("disabled", true);
  e.preventDefault();
);


$('.reset').click(function () 
  $("input[readonly]").prop("disabled", false);
)

$('input[readonly]').click(function () 
  $(this).removeAttr('readonly');
)
input[readonly] 
  color: gray;
  border-color: currentColor;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="myform">
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  <input readonly="readonly" value="test" />
  
  <button>Submit</button>
  <button class="reset" type="button">Reset</button>
</form>

【讨论】:

+1,这是一个不错的替代建议。唯一的缺点是输入框不会采用禁用样式,这在浏览器之间会有所不同,因此很难使其看起来与用户对禁用输入的期望保持一致。 真的。也许这可以用 CSS 解决?但是是的,它的外观与普通的禁用输入字段不同 优秀的替代解决方案。我更喜欢这个,因为您可以使用 CSS 进行任何必要的样式设置(即禁用 LOOK),但仍然有可用的事件。 这正是我所需要的!【参考方案4】:

我会建议一个替代方案 - 使用 CSS:

input.disabled 
    user-select : none;
    -moz-user-select : none;
    -webkit-user-select : none;
    color: gray;
    cursor: pointer;

而不是 disabled 属性。然后,您可以添加自己的 CSS 属性来模拟禁用的输入,但具有更多控制权。

【讨论】:

仅适用于 ie10,太多用户拥有 ie9 / 8。所以不是可靠的替代方案。 这仍然会导致在提交表单时要发布字段,这在很多情况下是不可取的。【参考方案5】:

$(function() 

  $("input:disabled").closest("div").click(function() 
    $(this).find("input:disabled").attr("disabled", false).focus();
  );

);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

<div>
  <input type="text" disabled />
</div>

【讨论】:

但这在 FireFox 上不起作用 - 这就是重点!【参考方案6】:

您可以考虑使用readonly,而不是disabled。使用一些额外的 CSS,您可以设置输入样式,使其看起来像 disabled 字段。

实际上还有另一个问题。事件change 仅在元素失去焦点时触发,考虑到disabled 字段,这不符合逻辑。可能您正在从另一个调用将数据推送到该字段中。要完成这项工作,您可以使用事件“绑定”。

$('form').bind('change', 'input', function () 
    console.log('Do your thing.');
);

【讨论】:

如果我没记错的话,一个只读的输入仍然会和表单一起提交 没错。然后它应该与@npth anwsner 结合使用。 谢谢,这对我的情况来说非常干净和优化。【参考方案7】:

或者用 jQuery 和 CSS 来做这个!

$('input.disabled').attr('ignore','true').css(
    'pointer-events':'none',
     'color': 'gray'
);

这样你可以使元素看起来被禁用并且不会触发任何指针事件,但它允许传播,如果提交你可以使用属性“忽略”来忽略它。

【讨论】:

@Precastic,没错,但它目前几乎适用于所有其他浏览器,您可以使用polyfill for ie < 11。 sidonaldson,为什么不直接使用 CSS 来应用样式? @KyleMit 你可以添加一个类而不是设置样式,但这不是这个线程的主题!我只是建议指针事件,这仍然是一个很好且正确的答案,具体取决于您正在构建的浏览器矩阵。感谢所有将这个答案标记下来的人,这有点糟糕,因为这里没有什么不正确的:/ @sidonaldson,这是一个很好的答案,所以我也希望它的排名也更高。我是not sure what the ignore attribute does。但我关于 CSS 的观点是,我认为我们不需要 jQuery 作为应用 CSS 的工具。您可以设置一个针对相同选择器并禁用指针事件的 CSS 规则。 In this fiddle,jQuery 和 CSS 应该做同样的事情,但 CSS 的性能会更高。 @KyleMit 啊,假设表单已提交,您将不得不以某种方式告诉后端忽略该字段,如果它包含一个值(因为我们正在欺骗禁用)。 我同意 CSS 可以更强大,因为您可以使用基于属性的选择器!检查这个演示,我已经匹配了 chrome 自己的禁用字段:jsfiddle.net/KyleMit/pxx8pk6v【参考方案8】:

我们今天遇到了这样的问题,但我们不想更改 HTML。所以我们使用mouseenter 事件来实现这一点

var doThingsOnClick = function() 
    // your click function here
;

$(document).on(
    'mouseenter': function () 
        $(this).removeAttr('disabled').bind('click', doThingsOnClick);
    ,
    'mouseleave': function () 
        $(this).unbind('click', doThingsOnClick).attr('disabled', 'disabled');
    ,
, 'input.disabled');

【讨论】:

【参考方案9】:

我做了一些与 Andy E 非常相似的事情;除了我使用了周围的标签。但是,我需要“名称”,所以我将其更改为没有“href”的标签。

【讨论】:

【参考方案10】:

没有理由不能使用 CSS 和 readonly 的组合来模拟 disabled 属性:

Faux-Disabled: <input type="text" value="1" readonly="1" style="background-color:#F6F6F6;"><br>

Real-Disabled: <input type="text" disabled="true" value="1"></input>

注意:这不会有disabled&lt;form&gt; 中的常规行为,这会阻止服务器看到该字段。这只是以防万一您想禁用与服务器端无关的字段。

【讨论】:

【参考方案11】:

我找到了另一个解决方案:

<input type="text" class="disabled" name="test" value="test" />

“禁用”类通过不透明度模仿禁用元素:

<style type="text/css">
    input.disabled 
        opacity: 0.5;
    
</style>

如果元素被禁用则取消事件并移除类:

$(document).on('click','input.disabled',function(event) 
    event.preventDefault();
    $(this).removeClass('disabled');
);

【讨论】:

JavaScript 部分对我不起作用。除此之外,它没有回答问题,因为它是关于启用禁用的输入。然而,在这个例子中,它在开始时并没有被禁用,因此在提交时被发送。【参考方案12】:

这里的建议看起来也很适合这个问题

Performing click event on a disabled element? Javascript jQuery

jQuery('input#submit').click(function(e) 
    if ( something )         
        return false;
     
);

【讨论】:

点击事件可能不会发生在禁用的属性上。

以上是关于禁用输入上的事件的主要内容,如果未能解决你的问题,请参考以下文章

UIAlertController 禁用屏幕上的所有触摸事件

识别禁用的 UIButton 上的单击或手势事件

EditText:禁用文本选择处理程序单击事件上的粘贴/替换菜单弹出

如何在android中检测禁用复选框上的触摸事件

在 iOS 中禁用 uiwebview 上的某些触摸事件

如何禁用右键单击事件或如何隐藏 Autodesk Forge 查看器上的上下文菜单