我有这样的链接:
- @glossaries.each do |g|
%a.{ :href => glossary_path(g), data: { 'turbo_frame': :'entry' } }
= g.title
如果单击
g.title
链接的结果在另一个框架中呈现,如何设置活动链接(活动词汇表)的样式?
如果当前路径等于请求的路径,我尝试使用帮助器提供某个类的链接,但它不起作用。没有为链接提供“活动”类别:
def current_class?(test_path)
return 'active' if request.path == test_path
''
end
使用框架时,当前路径未显示在浏览器地址栏中,因此我尝试通过
data-turbo-action" => "advance"
强制它。使用该浏览器,地址栏中有当前路径,但链接仍然没有“活动”类..
我编写这个刺激控制器来处理
turbo:click
事件并使单击的元素处于活动状态。当另一个 turbo:click
事件处理程序取消访问时会出现问题,但在这个地方我不关心它。
import { Controller } from "@hotwired/stimulus";
export default class extends Controller{
static targets = ['link']
static classes = ['active']
initialize(){
this.handleTurboClick = this.handleTurboClick.bind(this)
}
connect(){
this.element.addEventListener('turbo:click', this.handleTurboClick)
}
disconnect(){
this.element.removeEventListener('turbo:click', this.handleTurboClick)
}
handleTurboClick(event){
this.linkTargets.forEach(target => {
if(target == event.target){
target.classList.add(...this._activeClasses)
}else{
target.classList.remove(...this._activeClasses)
}
})
}
get _activeClasses(){
return this.activeClasses.length == 0 ? ['active'] : this.activeClasses
}
}
<div data-controller="turbo-active-link" data-turbo-active-link-active-class="bg-gray-300 hover:bg-gray-300" data-turbo-frame="main">
<a href="/a" data-turbo-active-link-target="link">link A</a>
<a href="/b" data-turbo-active-link-target="link">link B</a>
</div
它不会更新的原因是因为另一个框架正在导航,而页面的其余部分保持不变。要使其显示活动导航链接,您需要重新加载两者或使用一些自定义 JavaScript。我宁愿重新加载两侧,我会在导航和侧面板周围做另一个涡轮框架,就像这样
<%= turbo_frame_tag "glosarries_index" do %>
... Navigation links would be here but remove the data-turbo-frame it will automatically use the closest parent.
<%= turbo_frame_tag "entry" do %>
...
<% end %>
<% end %>
我发现上面的答案有效,但过于复杂,所以我构建了一个更简单的解决方案,需要更少的样板。该解决方案还更好地遵循刺激约定,因为它不使用自定义事件处理程序而仅使用目标
刺激控制器:
import { Controller } from "stimulus";
export default class extends Controller {
static classes = ['active']
connect() {
this.active_link = null;
}
disconnect() {
this.active_link = null;
}
handleTurboClick(event) {
if (this.active_link) {
this.active_link.classList.remove(this.activeClass);
}
this.active_link = event.target.closest('a');
this.active_link.classList.add(this.activeClass);
}
}
html:
<div data-controller="turbo-active-link" data-turbo-active-link-active-class="bg-gray-300 hover:bg-gray-300">
<a href="/a" action="turbo:click->turbo-active-link#handleTurboClick" data-turbo-frame="main">link A</a>
<a href="/b" action="turbo:click->turbo-active-link#handleTurboClick" data-turbo-frame="main">link B</a>
</div
我将发布另一种方法。这就是我现在设计选项卡的方式。
active_tab_controller.js:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["link"]
connect() {
this.linkTargets[0].classList.add("active");
this.linkTargets[1].classList.add("shadow-inner");
}
setActive(event) {
this.linkTargets.forEach(link => {
link.classList.remove("active")
link.classList.add("shadow-inner")
})
event.currentTarget.classList.add("active")
event.currentTarget.classList.remove("shadow-inner ")
}
}
application.tailwind.css:
.active { @apply
border border-b-0 border-gray-300 bg-gradient-to-b from-neutral-50 to-neutral-100
}
html:
.flex{ data: { controller: "active-tab" } }
= link_to main_tab_user_project_path(@user, @project), data: {turbo_frame: "tab_content", action: "click->active-tab#setActive", "active-tab-target" => "link"} do
= image_tag "list.svg"
.px-1 to-dos
= link_to second_tab_user_project_path(@user, @project), data: {turbo_frame: "tab_content", action: "click->active-tab#setActive", "active-tab-target" => "link"} do
= image_tag "link.svg"
.px-1 links
= turbo_frame_tag "tab_content" do
= render "main_tab"