jQuery切换完成后立即重置

时间:2019-01-29 00:55:14

标签: jquery bootstrap-4 web-frontend

我有一些元素要在页面较小时自动隐藏(显示:无),而在页面较大时自动显示(显示:块)。我在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');
        }
    });
});

这非常接近工作。页面正确加载,菜单在小页面上显示:无,在大页面上显示:块。一旦命中了992px目标,我就可以调整浏览器窗口的大小,并根据需要扩展或折叠菜单。而且我可以单击菜单来切换它们,它可以按预期工作。

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

更新:

添加了此javascript并删除了@media最小宽度,它可以正常工作:

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);

2 个答案:

答案 0 :(得分: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;的内联样式,则应该能够获得所需的效果。

答案 1 :(得分:0)

因此,正如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>