如何正确定位CSS元素?

6
我正在使用noUi Slider制作一个滑块。试图实现“优雅”的解决方案。由于我的ui手柄很大,我将ui基础稍微放大了一点,并在基础上增加了额外的值。但是这些值是不允许的,手柄会跳回到允许的值。我决定把加号和减号按钮放在受限制的值的位置。

但问题是,我无法实现这样的效果:当您将手柄移动到控制符号(加号/减号)时,它们会隐藏在手柄后面。在我的情况下,它们仍然在顶部。我很难解决这个问题。

需要一些帮助/建议。

这是我的代码(样式在JSFiddle上):

$(document).ready(function(){

    var sliders = document.getElementById('red'),
        input = document.getElementById('handle'),
        sliderPlus = document.getElementById('slider-amount-plus'),
        sliderMinus = document.getElementById('slider-amount-minus'),
        termCur = 500;

    noUiSlider.create(sliders, {
        start: termCur,
        step: 50,
        connect: "lower",
        range: {
            'min': 0,
            'max': 1100
        },
        pips: {
            mode: 'values',
            values: [100, 500, 1000],
            density: 4.5
        }
    });
    $('<div class="value">' + termCur + ' zł' + '</div>').appendTo($('.noUi-handle', sliders));


sliders.noUiSlider.on('change', function ( values, handle ) {
    if ( values[handle] < 100 ) {
        sliders.noUiSlider.set(100);
    } else if ( values[handle] > 1000 ) {
        sliders.noUiSlider.set(1000);
    }
});
sliders.noUiSlider.on('update', function( values ) {
    termCur = values;
    if( termCur >= 100 && termCur <= 1000 ) {
    $('.value', sliders).text(parseInt(termCur) + ' zł');}
});
sliderPlus.addEventListener('click', function(){
    if(termCur < 1000) {
        var setValue = parseInt(termCur) + 50;
        sliders.noUiSlider.set(setValue);
    }
}); 
sliderMinus.addEventListener('click', function(){
    if(termCur > 100) {
        var setValue = parseInt(termCur) - 50;
        sliders.noUiSlider.set(setValue);
    }
}); 

<div class="sliders" id="red">
        <a class="controls-symbols slider-minus" id="slider-amount-minus"><i class="fa fa-minus"></i></a>
        <a class="controls-symbols slider-plus" id="slider-amount-plus"><i class="fa fa-plus"></i></a>
    </div>

https://jsfiddle.net/o7Ly845j/


你是否在寻找类似于Fiddle这样的东西? - zgood
1
如果您要使用DOM操作,那么您可能希望使用jQuery的on方法附加单击事件,如下所示:$(document).on('click', sliderMinus, function(e){ alert('click'); }); 这将确保事件始终附加。在引用sliderMinus之前,它被克隆然后删除,因此事件没有得到适当处理。 - zgood
你有那个的代码演示吗? - Ilya K
是的,这个Fiddle演示了我所说的内容。 - zgood
工作得很好。唯一的问题是,在加号或减号(100/1000)的最后一次单击时,不会触发.on(update)。如果使用val>=100 && val<=1000代替val>100 && val<1000,则on(click)就会出现问题。我不得不将$('.value',sliders).text(termCur + 'zł');放入单击事件中,现在它可以正常工作了。演示代码 - Ilya K
显示剩余6条评论
2个回答

2
具有共同父元素的元素组成了堆叠上下文,这些元素一起向前或向后移动。充分理解堆叠上下文对于真正掌握 z-index 和堆叠顺序的工作方式至关重要。
每个堆叠上下文都有一个 HTML 元素作为其根元素。当在元素上形成新的堆叠上下文时,该堆叠上下文将其所有子元素限制在堆叠顺序的特定位置。这意味着,如果元素包含在堆叠顺序底部的堆叠上下文中,则无论使用多少亿的 z-index,也无法使它出现在堆叠顺序更高的不同堆叠上下文中的另一个元素前面。
新的层叠上下文可以通过以下方式在元素中形成:
- 当一个元素是文档的根元素(即 `` 元素)时; - 当一个元素具有非 static 的定位值和非 auto 的 z-index 值时; - 当一个元素具有小于 1 的不透明度值时; - 除了 opacity 外,还有一些 CSS 属性也会创建层叠上下文。这些属性包括:transforms、filters、css-regions、paged media 等,可能还有其他属性。
以下是单个堆叠上下文中确定堆叠顺序的基本规则(从后往前):
  • 堆叠上下文的根元素
  • 具有负 z-index 值的定位元素(及其子元素)(较高值在较低值前面堆叠;具有相同值的元素按照在 HTML 中的出现顺序堆叠)
  • 非定位元素(按照在 HTML 中的出现顺序排序)
  • 具有自动 z-index 值的定位元素(按照在 HTML 中的出现顺序排序)
  • 具有正 z-index 值的定位元素(及其子元素)(较高值在较低值前面堆叠;具有相同值的元素按照在 HTML 中的出现顺序堆叠)
注意:具有负 z-index 的定位元素首先在堆叠上下文中排序,这意味着它们出现在所有其他元素的后面。因此,一个元素可能会出现在其父元素的后面,这通常是不可能的。只有当元素的父元素在同一个堆叠上下文中且不是该堆叠上下文的根元素时,才能实现这一点。
我用jQuery创建了一种“hackish”的方法来做到这一点,你可以在这里查看Fiddle。不过这不是一个永久的解决方案,我正在努力抽象出位置,因为它使用的是静态值。我还会找出CSS无法正常工作的原因,并在此发布。
     $(document).mousemove(function (e) {
         var newpos = $(".noUi-handle").offset().left;

         if (newpos < 0) {
             $(".slider-minus").hide();
         } else { 
             $(".slider-minus").show();
         }

         if (newpos > 830) {
             $(".slider-plus").hide();  
         } else {  
             $(".slider-plus").show();
         }     
    });

更新: 这里是一个更好的版本,现在我正在解决为什么 CSS 无法实现它的问题。

@HimeshAadeshara 抱歉,什么?我不明白你在说什么。 - Tech Savant
看起来问题已经被你回答了。你想通过悬赏获得什么?我不介意深入研究,但我想知道我要达到的目标是什么,除了你已经完成的内容之外。 - Guy Schalnat
@GuySchalnat 关于CSS部分。JQuery的解决方案最多只能算是“hackish”。它真正应该在CSS中完成,我想知道为什么z-index的东西不起作用,因为我花了一些时间却无法弄清楚。 - Tech Savant
@NotoriousPet0 是的,不幸的是我仍在努力解决这个问题。 - Ilya K
我想我明白了。请看我的答案。 - Guy Schalnat
显示剩余2条评论

2
因此,根据最后一个@zgood小提琴,我猜测问题不再是z顺序,而是滑块条和加/减元素都在获取事件,并且当加/减事件获取到时,滑块已经达到1100或0。所以,我改变了事件的顺序,让加/减先获取事件并阻止它传递给滑块条。我只需要停止mousedown,大部分问题就自己解决了。之后,我可以删除所有> 100和< 1000的检查,因为滑块表现良好。
我还注意到,一旦到达50/1050,滑块按钮会覆盖加/减。因此,我将fiddle中的加/减z-index从3更改为13。我不确定哪个更好,所以请尝试3和13并自行决定。

https://jsfiddle.net/guyschalnat/radpjf47/2/

$(document).ready(function(){

    var sliders = document.getElementById('red'),
        input = document.getElementById('handle'),
        termCur = 500;

    noUiSlider.create(sliders, {
        start: termCur,
        step: 50,
        connect: "lower",
        range: {
            'min': 0,
            'max': 1100
        },
        pips: {
            mode: 'values',
            values: [100, 500, 1000],
            density: 4.5
        }
    });
    $('<div class="value">' + termCur + ' zł' + '</div>').appendTo($('.noUi-handle', sliders));

    var c = $('#red > span').clone(true);
    $('#red > span').remove();
    $('.noUi-base').prepend(c);

    sliders.noUiSlider.on('update', function( values ) {
        var val = parseInt(values);
        termCur = val;
        $('.value', sliders).text(termCur + ' zł');
    });
    $('#slider-amount-plus').click(function(e){
        if(termCur < 1100) {
            termCur = termCur + 50;
            sliders.noUiSlider.set(termCur);
            $('.value', sliders).text(termCur + ' zł');
        }
       e.stopPropagation();
    }).mousedown(function(e){
       e.stopPropagation();
    });     
    $('#slider-amount-minus').click(function(e){ 
        if(termCur > 0) {
            termCur = termCur - 50;
            sliders.noUiSlider.set(termCur);
            $('.value', sliders).text(termCur + ' zł');
        }
    }).mousedown(function(e){
       e.stopPropagation();
    }); 

});

太好了! 滑块按钮覆盖加号/减号实际上是个好主意。 noUI滑块原本不支持禁用边缘,所以手柄会停在轨道的末端,而不是越过,所以想法是使其更宽(使其更具视觉吸引力),如果用户向左或向右滑动额外的距离(0、50、1050、1100),则手柄会反弹。 当处于自制边缘时,您可以看到加号/减号,因此这也是单击事件的限制。添加了额外的内容-[fiddle](https://jsfiddle.net/ilyakapitan/radpjf47/3/)。现在完美运行。 - Ilya K
@llyaK 太好了!我不确定你的意图,但现在我明白了。我喜欢它。 - Guy Schalnat
现在有一个小问题。如果我只是将按钮代码插入到prepend中,而不进行克隆和添加额外的代码行,那么这样做是否更好呢?$('.noUi-base').prepend( '<a class="controls-symbols slider-minus" id="slider-amount-minus"><i class="fa fa-minus"></i></a><a class="controls-symbols slider-plus" id="slider-amount-plus"><i class="fa fa-plus"></i></a>' );当然,我怀疑这个小代码会影响页面的整体性能,但还是要考虑一下。 - Ilya K
@llyaK 我认为这是一个判断性的决定。我通常会努力编写最易维护的代码,而不是最快的代码,这更多是一种直觉。在某些方面,我更喜欢避免克隆,也许是因为我担心当您更新滑块基础代码时会发生什么,并且它们进行了重大更改。所以请根据您的最佳猜测去做。我没有太多实际的滑块库使用经验,所以我对此并没有太多感觉。很抱歉我的回答有些含糊。 - Guy Schalnat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接