【问题标题】:jQuery toggle resetting immediately after completejQuery切换完成后立即重置
【发布时间】:2019-01-29 00:55:14
【问题描述】:

我有一些元素我想在页面较小时自动隐藏(显示:无),并在页面较大时自动显示(显示:块)。我有这个与 bootstrap4 一起使用的,它看起来像这样:

<section id="categories">
    <p data-toggle="categories-list">Categories</p>
    <ul id="categories-list" class="d-none d-lg-block">

    </ul>
</section>

但是,我还希望用户能够在列表隐藏时重新打开它,或者在它显示时隐藏它。我正在尝试使用以下代码添加切换功能:

$('[data-toggle]').each(function () {
    $(this)[0].addEventListener('click', function() {
        var target = $(this)[0].dataset.toggle;
        $('#' + target).toggle('slow');
    }); 
});

这几乎可行。如果我在 ul 隐藏(小页面)时单击,它会慢慢扩展为可见,但随后又立即消失。或者如果它已经可见(在大页面上),它会慢慢消失,但在动画完成后立即重新出现。

尽管我正在尝试进行更改,即使页面大小没有改变,boostrap 样式是否会强制执行这些显示规则?

(总的来说,我对前端开发还很陌生,尤其是引导程序。)

编辑:我知道引导程序具有某种“折叠”功能。我应该尝试使用它吗?也许它会玩得更好,而不是尝试做 jquery。

Edit2:再看一下崩溃,我看到他们使用“数据切换”,这正是我所说的。这可能是问题的一部分吗?

Edit3:我尝试完全删除我的 javascript 代码,而是使用 bootstrap4 文档中的 data-toggle 和 data-target 。我得到了与我的 javascript 代码完全相同的功能。

在 JasonB 提出解决方案后更新:

新的html:

<section id="categories">
    <p data-toggle="#categories-list">Categories</p>
    <ul id="categories-list" class="custom-none custom-lg-block">
    </ul>
</section>

新的 CSS:

.custom-none {
    display: none;
}

@media (min-width: 992px) {
    .custom-lg-block {
        display: block;
    }   
}

新的javascript:

$('[data-toggle]').each(function () {
    $(this)[0].addEventListener('click', function() {
        var target = $(this)[0].dataset.toggle;
        if ($(target).css('display') == 'none') {
            $(target).css('display', 'block');
        } else {
            $(target).css('display', 'none');
        }
    });
});

这非常接近工作。页面加载正确,菜单 display:none 在小页面上, display:block 在大页面上。一旦达到 992px 目标,我可以调整浏览器窗口的大小,并且菜单会根据需要展开或折叠。我可以点击菜单来切换它们,它可以按预期工作。

唯一剩下的问题是,一旦我单击菜单并手动设置它们的 .css('display'),该值就会被锁定。调整页面大小不再导致它们折叠或展开。这并不完全是一个交易破坏者,因为它的主要目的是处理移动设备(他们不会突然使页面变大),但如果他们在拥有所有菜单的同时缩小窗口,它在桌面上可能看起来很奇怪展开。

更新:

添加了这个javascript并删除了@media min-width,它正在工作:

window.addEventListener('resize', function(){
    if ($(window).width() < 992) {
        $('[data-toggle]').each(function () {
            var target = $(this)[0].dataset.toggle;
            $(target).css('display', 'none');
        });
    } else {
        $('[data-toggle]').each(function () {
            var target = $(this)[0].dataset.toggle;
            $(target).css('display', 'block');
        });
    }
}, true);

【问题讨论】:

  • $(target).css('display', ''); // 将其设置为继承
  • 不过,这并不是我真正想要的。我确实想更改显示值。但是如果页面调整大小,我希望它再次更改。感觉就像我需要某种 javascript 来检测宽度变化,而不是依赖 @media min-width。因为我认为仅靠 CSS 无法真正回应这一点。实际上,我希望显示值是最后的值(根据点击进行切换,或者根据屏幕调整大小进行更改,以最后发生的为准。)
  • 刚刚添加了检查宽度是否发生变化然后更新显示值的javascript。这似乎行得通。不确定这是最好的方法,尤其是在性能方面。将更新问题的详细信息。

标签: jquery bootstrap-4 web-frontend


【解决方案1】:

$('[data-toggle]').each(function() {
  $(this)[0].addEventListener('click', function() {
    var target = $(this)[0].dataset.toggle;
    $('#' + target).toggle('slow');
  });
});
.dave-d-none {
  display: none;
}

@media only screen and (min-width: 500px) {
  .dave-d-lg-block {
    display: block;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="categories">
  <p data-toggle="categories-list">Categories</p>
  <ul id="categories-list" class="dave-d-none dave-d-lg-block">
    <li>This is the hidden stuff.</li>
  </ul>
</section>

我相信 Bootstrap 的 d-none 类是问题所在。

.d-none 添加了 display:none !important; ,这就是 !important 的标志。如果您使用自己的类或只是 display:none; 的内联样式,您应该能够获得所需的效果。

【讨论】:

  • 哦,好电话。我没有想过“!重要”。不过,我认为这不像摆脱 .d-none 那样简单,因为我认为 d-lg-block 也可能是“!important”,所以当页面很大时它会保持可见。因此,如果不完全摆脱引导类,我就无法让问题完全消失,我需要它们。我可以制作自己的切换函数来执行类似 .css('display', 'block !important') 的功能吗?
  • 我尝试使用 .css('display', 'block !important')。它不起作用。之后立即读取 .css('display') 仍然显示 'none'。
  • 我添加了一个 sn-p 以表明您可以根据屏幕宽度获得所需的显示/隐藏行为,而无需使用 !important。问题在于,一旦触发了切换 javascript,它就会优先处理,因此需要对逻辑进行一些不同的处理。
  • 谢谢!我会在早上试一试。我想我也必须为 d-lg-block 做类似的事情,对吧?还是没有标记为重要?
  • 你是对的; !important 也在其中。 css 是 `.d-lg-block { display:block!important; } 带有 lg 断点的媒体查询。
【解决方案2】:

因此,正如 JasonB 指出的那样,问题在于引导 css 添加了 !important,它覆盖了我尝试以编程方式进行的任何更改。

我尝试制作自己的不使用 !important 的 CSS,但是当我手动设置 display:none/block 时,它总是会覆盖 CSS 类,即使窗口宽度发生变化。

我想出的解决方案是使用 javascript 来检测窗口宽度的变化,而不是依赖 CSS。 CSS 仍然设置初始显示状态,但之后,所有更改都由 javascript 进行。我怀疑这是最好的解决方案,但这是我迄今为止所能做的。下面是适用的 HTML、CSS 和 Javascript:

$('[data-toggle]').each(function () {
    $(this)[0].addEventListener('click', function() {
        var target = $(this)[0].dataset.toggle;
        if ($(target).css('display') == 'none') {
            $(target).css('display', 'block');
        } else {
            $(target).css('display', 'none');
        }
    });
});

window.addEventListener('resize', function(){
    if ($(window).width() < 992) {
        $('[data-toggle]').each(function () {
            var target = $(this)[0].dataset.toggle;
            $(target).css('display', 'none');
        });
    } else {
        $('[data-toggle]').each(function () {
            var target = $(this)[0].dataset.toggle;
            $(target).css('display', 'block');
        });
    }
}, true);

.custom-none {
    display: none;
}

.custom-lg-block {
    display: block;
}

<section id="categories">
    <p data-toggle="#categories-list">Categories</p>
    <ul id="categories-list" class="custom-none custom-lg-block">
    </ul>
</section>

【讨论】:

    猜你喜欢
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多