Rails 5.4.2中如何真正禁用链接?
这个问题的核心在于:HTML原生的<a>标签的disabled属性并没有实际的禁用行为——浏览器只会渲染它的禁用样式,但不会阻止点击跳转。所以即使你给link_to加了disabled: !@business_process.valid_for_schedule?,用户点击还是会触发链接。
下面给你几个可行的解决方案,按需选择:
方案1:用JavaScript阻止点击事件
在link_to中添加一个onclick事件,当链接处于禁用状态时,阻止默认的跳转行为。这种方法不需要改动太多现有代码,只需要加一行属性:
<%= link_to [:schedule, @business_process], method: :get, disabled: !@business_process.valid_for_schedule?, class: "mat-flat-button mat-button-base mat-primary", onclick: "if(this.disabled) return false;" do %> <span class="fa fa-bolt"></span> <%= t('business_processes.show.NewSchedule') %> <% end %>
优点:保留了<a>标签的结构,样式不需要调整;缺点:依赖JavaScript,如果用户禁用了JS,链接还是能被点击。
方案2:条件生成不同元素(最可靠)
既然link_to_if不符合你的需求,那直接用Ruby的条件判断:当流程可调度时生成正常的链接,不可调度时生成一个看起来像按钮的非链接元素(比如<div>或<button>),彻底避免跳转行为:
<% if @business_process.valid_for_schedule? %> <%= link_to [:schedule, @business_process], method: :get, class: "mat-flat-button mat-button-base mat-primary" do %> <span class="fa fa-bolt"></span> <%= t('business_processes.show.NewSchedule') %> <% end %> <% else %> <div class="mat-flat-button mat-button-base mat-primary" disabled="disabled"> <span class="fa fa-bolt"></span> <%= t('business_processes.show.NewSchedule') %> </div> <% end %>
优点:完全不依赖JS,无论用户环境如何,禁用状态的按钮都无法触发跳转;缺点:需要维护两个分支的代码,要确保非链接元素的样式和链接按钮完全一致(可能需要微调CSS)。
方案3:用CSS的pointer-events属性阻止点击
给禁用状态的链接添加pointer-events: none,让浏览器忽略它的鼠标事件,同时配合cursor: not-allowed增强禁用的视觉提示。你可以直接在项目的CSS文件中添加:
a[disabled="disabled"] { pointer-events: none; cursor: not-allowed; /* 如果默认的禁用样式不够明显,可以再加一些透明度等样式 */ opacity: 0.6; }
优点:不需要修改Ruby代码,只加几行CSS,实现简单;缺点:依赖浏览器对pointer-events的支持(现代浏览器都支持,但旧版IE可能有问题),而且如果用户手动修改CSS,可能会绕过这个限制。
你可以根据项目的兼容性要求和代码维护成本选择合适的方案,个人更推荐方案2,它的可靠性最高,适合大多数业务场景。
内容的提问来源于stack exchange,提问作者user1185081

