【问题标题】:Replicate CSS :focus selector for multiple elements using javascript使用javascript复制CSS:多个元素的焦点选择器
【发布时间】:2021-01-23 19:20:15
【问题描述】:

我有这个网站:https://www.australianathleticscalendar.com.au/

我想这样做,这样您就可以同时选择一个“事件”过滤器和“状态”过滤器(即同时选择 100m 和 QLD),并且每个过滤器中的气泡都将具有样式(即像 :focus)。对于每个过滤器,选择一个类别。当您在过滤器中更改类别时,之前选择的类别也必须是无样式的(即不能同时选择 100m 和 200m。从 100m 移动到 200m 会从 100m 移除样式并将其添加到 200m)。

css 的问题在于您一次只能 :focus 一个元素。

如何使用 javascript 实现这一点?

我已将相关代码提取到codepen here。

这是绘制两个过滤器的函数:

function drawCategories() {
var template = Handlebars.compile(document.getElementById("menu-template").innerHTML);
console.log('draw ', this.products);
document.getElementById('menu-container').innerHTML = template(this.events);
}

function drawStates() {
    var template = Handlebars.compile(document.getElementById("menu-template-2").innerHTML);
    console.log('draw ', this.products);
    document.getElementById('menu-container-states').innerHTML = template(this.states);
}


function showCategory(event) {
    this.title = event;
    drawProducts();
}

function showState(state) {
    this.titleStates = state;
    drawProducts();
}

这是两个过滤器的 HTML:

        <!-- Events filter -->
<div class="container">
    <script id="menu-template" type="text/x-handlebars-template">           
                <ul class="navbar-nav">
                    {{#each this as |event|}}
                        <li class="nav-item"></li>
                            <a class="nav-link" href="#" onclick="showCategory('{{event.name}}');">{{event.name}}</a>
                    {{/each}}
                    <a class="navbar-brand hover-color" href="#" onclick="showAllEvents();">All Events</a>
                </ul>
                
                <ul class="navbar-nav ml-auto"></ul>
                    <li class="nav-item">                       
                    </li>
                </ul>
        </div>
    </script>
</div>

<!-- States filter -->
<div class="container">
    <script id="menu-template-2" type="text/x-handlebars-template">
                <ul class="navbar-nav">
                    {{#each this as |state|}}
                        <li class="nav-item"></li>
                            <a class="nav-link nav-link-states" href="#" onclick="showState('{{state.name}}');">{{state.name}}</a>
                    {{/each}}
                    <a class="navbar-brand hover-color-states" href="#" onclick="showAllStates();">All States</a>
                </ul>               
                <ul class="navbar-nav ml-auto"></ul>
                    <li class="nav-item">                       
                    </li>
                </ul>
        </div>
    </script>
</div>

【问题讨论】:

  • 顺便说一句,您的 HTML 将有重复的 id 属性值(如 stateFilter),这在 HTML 中是无效的。您应该删除那些 id 属性。它们似乎没有任何目的。
  • 有一个eventsFilter 和stateFilter,当我尝试将classList 用于:focus 时,我添加了它们,但我似乎找不到重复的stateFilter
  • 当模板被把手#each循环展开时,它变成重复的。此类循环中的任何 HTML 都不应具有 id 属性。
  • 另外,您关闭 &lt;/li&gt; 的次数比打开 &lt;li&gt; 的次数要多。
  • 谢谢,我已经删除了这些 ID 和 &lt;/li&gt;。

标签: javascript html jquery json filter


【解决方案1】:

通常有很多方法可以实现这一目标。我认为最简单的可能是在点击处理程序中的调用中添加一个额外的参数——传递this——这样处理程序就可以准确地知道哪个 DOM 元素需要获得样式:

<a onclick="showCategory(this, '{{event.name}}');">
<a onclick="showAllEvents(this);">
<a onclick="showState(this, '{{state.name}}');">
<a onclick="showAllStates(this);">

然后在您的代码中定义一个函数,将 CSS 类应用于给定的 DOM 元素,但同时确保它是具有该类的 only 元素。然后在点击处理程序中使用这个实用函数,它现在还必须接受那个额外的参数:

// Utility function that ensures only one element has the given CSS class:
function selectElem(elem, className) {
    let prevSelected = document.querySelector("." + className);
    if (prevSelected) prevSelected.classList.remove(className);
    elem.classList.add(className);
}

function showCategory(elem, event) { // <-- extra parameter, here and below...
    selectElem(elem, "selectedEvent"); // <-- add this call, here and below...
    this.title = event;
    drawProducts();
}

function showAllEvents(elem) {
    selectElem(elem, "selectedEvent");
    this.title = "All Events";
    drawProducts();
}

function showState(elem, state) {
    selectElem(elem, "selectedState"); // <-- different style here and below
    this.titleStates = state;
    drawProducts();
}

function showAllStates(elem) {
    selectElem(elem, "selectedState");
    this.titleStates = "All States";
    drawProducts();
}

现在由您来定义两个新 CSS 类的样式:selectedEvent 和 selectedState。你可以用逗号给它们同样的定义:

.selectedState, .selectedEvent {
    # Your styling ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-03
    • 2013-09-14
    • 2022-01-13
    • 2012-12-26
    • 2020-07-25
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多