禁用React中DIV的最佳方法OnClick

20

我有一个组件,其中一个 div 接受 onClick 和 aria-disabled 属性。它们都作为 props 传递进来,disabled 是可选的。在我的 render 方法中,我执行以下操作:

<div onClick={!this.props.Disabled ? this.props.Click : undefined} 
     aria-disabled={this.props.Disabled>My Div</div>

我使用CSS来显示禁用状态(opacity: 0.5,pointer-event:none等等)。但是我想知道是否有更好的处理实际onClick事件的方法。因为它是强制性的属性……所以即使项目被禁用,您仍然需要传递一个onClick来满足条件。有没有更好的解决方法?


你可以将 Click 属性设为可选,并将其默认值设置为 () => {} - Tholle
@ZeroDarkThirty 学到了新东西,div 不支持 disabled。谢谢! - dance2die
4个回答

42

CSS中为div[disabled]设置pointer-events: none

test.scss

div[disabled]
{
  pointer-events: none;
  opacity: 0.7;
}

以上代码将使div的内容被禁用,您可以通过添加“disabled”属性来使

被禁用。

Test.js

<div disabled={this.state.disabled}>
  /* Contents */
</div>

点击按钮后,您可以将状态变量disabled更改为'true'。

handleClick = () =>{
    this.setState({
      disabled: true,
    });
  }

参考资料:https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events


你可能想将其写为pointerEvents,否则它可能会抛出异常,因为React DOM的语法略有不同。 div[disabled] { pointerEvents: none; opacity: 0.7; } - Wajdan Ali

6

为什么现在回答? 我与一位合作的开发人员打算将这些答案用作参考,我认为更好的答案可以使他和其他人受益。

这个答案提供什么? 它提供了一个解决方案,既考虑了语义的准确性,又考虑了可访问性,并使用了现有的答案,同时还审查了现有的答案。

是否有其他注意事项? 当“禁用”时,<div>应该如何表现不同?它是“通用容器”……没有可禁用的内容。我使用了现有答案的行为:

  • 防止鼠标与子元素的交互
  • 向某些软件标识<div>为“已禁用”

建议的解决方案

注意:此解决方案使用函数组件语法。

div.is-disabled
{
  pointer-events: none;
  opacity: 0.7;
}

/**
 * Render a button and an element whose content it "disables"
 *
 * NOTE: The "disabling" prevents user interaction with its children and to reduce the opacity of the entire element.
 *
 * @prop {Object} props
 * @prop {*} props.children - Any React-parseable children as the content
 * @function
 */
function MyComponent({ children }) {
  /** Whether content is disabled */
  let isDisabled = false;

  /**
   * When user clicks on element that should trigger "disabling" a div
   * @param {UIEvent} event
   * @function
   */
  const onClick (event) => {
    if (!isDisabled) {
      isDisabled = true;
    }
  }

  render (
    <>
      <div
        aria-disabled={isDisabled}
        className={(isDisabled) ? 'is-disabled' : ''}
      >
        {children}
      </div>
      <button onClick={onClick}>
        Disable Content
      </button>
    </>
  );
}

已有答案的回顾

pramod-h-g的回答

很好。这提供了“禁用

”的含义和解决方案。

但是,标记让我担忧。

  • <div>标签没有disabled属性^1^2
  • 在没有此类属性的元素上使用其他元素的标准属性可能会使新开发人员感到困惑。
  • 自定义属性(截至我最后一次检查)需要一个data-前缀。

jpsimon的回答

准确地回答了问题,没有错误。

但是,我认为aria-disabled属性只会 “禁用” 一些用户体验中的

。视觉浏览器用户不会将此<div>作为“禁用”。

yts的回答

我完全同意。

但是,这个解决方案没有“禁用”一个

。原始发布者可能没有恰当地提出问题,我支持你引导他使用<button>


2
我认为你的直觉是正确的 - 根据变化的props一直添加和删除事件处理程序并不理想。那么如何简单地包装函数并根据需要返回呢?就像以下示例中所示。
<div onClick={(e) => !this.props.Disabled && this.props.Click(e)}
  aria-disabled={this.props.Disabled}>
    My Div
</div>

&&是一种缩写的if逻辑语法,用于守卫操作。


0
一个 button 可能更适合这个场景。使用 button 元素,如果 disabled 属性为 true,则 onClick 事件将自动不会触发。因此你可以这样做:
<button onClick={this.props.Click} disabled={this.props.Disabled}>My button</button>

使用按钮而不是 div,您还可以获得可访问性的好处。

当按钮被禁用时,click 属性是“额外”的事实并没有什么问题,我认为这比根据禁用状态更改传入属性的结构要好。


1
@ZeroDarkThirty,这是有原因的吗?按钮通常更适合于可访问性目的,而且您似乎很关心aria。 - yts
@yts 谢谢,非常有帮助的建议! - Nicole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接