React js中的滑块:如何设置宽度以正确填充外部div?

问题描述 投票:0回答:0

我主要使用以下代码来创建范围滑块:https://codesandbox.io/s/multi-range-slider-react-js-forked-3b5n0?file=/src/component/multiRangeSlider/MultiRangeSlider.js

在该示例的 CSS 中,滑块和滑块的宽度设置为 200px。 但是,在我的代码中,我想在网格元素内使用滑块组件,其中滑块应跨越该元素的整个宽度。但是当我将 .slider 和 .thumb 的宽度设置为 100% 时,拇指不再显示在正确的位置。

->参见图片“/></a>左手拇指离开屏幕,右手拇指离右侧太远。</p>
<p>您可以通过将代码更改为以下内容,在我上面链接的codesandbox中重新创建此效果:</p>
<p>应用程序.js</p>
<pre><code>import MultiRangeSlider from "./component/multiRangeSlider/MultiRangeSlider";
import "./styles.css";

const App = () => {
  return (
    <div className="grid-container">
      <div className="main1">
        <MultiRangeSlider
          min={0}
          max={1000}
          onChange={({ min, max }) => console.log(`min = ${min}, max = ${max}`)}
        />
      </div>
      <div className="main2">
        <p>main 2</p>
      </div>
    </div>
  );
};

export default App;
</code></pre>
<p>样式.css</p>
<pre><code>* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background-color: #242526;
  font-family: sans-serif;
}

.grid-container {
  display: grid;
  grid-template-areas:
    "main1 main2";
  grid-template-columns: 1fr 1fr;
  gap: 40px;
  margin: auto;
  margin-bottom: 40px;
}

.main1 {grid-area: main1;}
.main2 {grid-area: main2;}
</code></pre>
<p>多范围滑块.css</p>
<pre><code>.container {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.slider {
  position: relative;
  width: 100%;
}

.slider__track,
.slider__range,
.slider__left-value,
.slider__right-value {
  position: absolute;
}

.slider__track,
.slider__range {
  border-radius: 3px;
  height: 5px;
}

.slider__track {
  background-color: #ced4da;
  width: 100%;
  z-index: 1;
}

.slider__range {
  background-color: #9fe5e1;
  z-index: 2;
}

.slider__left-value,
.slider__right-value {
  color: #dee2e6;
  font-size: 12px;
  margin-top: 20px;
}

.slider__left-value {
  left: 6px;
}

.slider__right-value {
  right: -4px;
}

/* Removing the default appearance */
.thumb,
.thumb::-webkit-slider-thumb {
  -webkit-appearance: none;
  -webkit-tap-highlight-color: transparent;
}

.thumb {
  pointer-events: none;
  position: absolute;
  height: 0;
  width: 100%;
  outline: none;
}

.thumb--left {
  z-index: 3;
}

.thumb--right {
  z-index: 4;
}

/* For Chrome browsers */
.thumb::-webkit-slider-thumb {
  background-color: #f1f5f7;
  border: none;
  border-radius: 50%;
  box-shadow: 0 0 1px 1px #ced4da;
  cursor: pointer;
  height: 18px;
  width: 18px;
  margin-top: 4px;
  pointer-events: all;
  position: relative;
}

/* For Firefox browsers */
.thumb::-moz-range-thumb {
  background-color: #f1f5f7;
  border: none;
  border-radius: 50%;
  box-shadow: 0 0 1px 1px #ced4da;
  cursor: pointer;
  height: 18px;
  width: 18px;
  margin-top: 4px;
  pointer-events: all;
  position: relative;
}

</code></pre>
<p>MultiRangeSlider.js(保持不变,没有变化)</p>
<pre><code>import React, { useCallback, useEffect, useState, useRef } from "react";
import PropTypes from "prop-types";
import "./multiRangeSlider.css";

const MultiRangeSlider = ({ min, max, onChange }) => {
  const [minVal, setMinVal] = useState(min);
  const [maxVal, setMaxVal] = useState(max);
  const minValRef = useRef(min);
  const maxValRef = useRef(max);
  const range = useRef(null);

  // Convert to percentage
  const getPercent = useCallback(
    (value) => Math.round(((value - min) / (max - min)) * 100),
    [min, max]
  );

  // Set width of the range to decrease from the left side
  useEffect(() => {
    const minPercent = getPercent(minVal);
    const maxPercent = getPercent(maxValRef.current);

    if (range.current) {
      range.current.style.left = `${minPercent}%`;
      range.current.style.width = `${maxPercent - minPercent}%`;
    }
  }, [minVal, getPercent]);

  // Set width of the range to decrease from the right side
  useEffect(() => {
    const minPercent = getPercent(minValRef.current);
    const maxPercent = getPercent(maxVal);

    if (range.current) {
      range.current.style.width = `${maxPercent - minPercent}%`;
    }
  }, [maxVal, getPercent]);

  // Get min and max values when their state changes
  useEffect(() => {
    onChange({ min: minVal, max: maxVal });
  }, [minVal, maxVal, onChange]);

  return (
    <div className="container">
      <input
        type="range"
        min={min}
        max={max}
        value={minVal}
        onChange={(event) => {
          const value = Math.min(Number(event.target.value), maxVal - 1);
          setMinVal(value);
          minValRef.current = value;
        }}
        className="thumb thumb--left"
        style={{ zIndex: minVal > max - 100 && "5" }}
      />
      <input
        type="range"
        min={min}
        max={max}
        value={maxVal}
        onChange={(event) => {
          const value = Math.max(Number(event.target.value), minVal + 1);
          setMaxVal(value);
          maxValRef.current = value;
        }}
        className="thumb thumb--right"
      />

      <div className="slider">
        <div className="slider__track" />
        <div ref={range} className="slider__range" />
        <div className="slider__left-value">{minVal}</div>
        <div className="slider__right-value">{maxVal}</div>
      </div>
    </div>
  );
};

MultiRangeSlider.propTypes = {
  min: PropTypes.number.isRequired,
  max: PropTypes.number.isRequired,
  onChange: PropTypes.func.isRequired
};

export default MultiRangeSlider;

</code></pre>
<p>我尝试更改位置:绝对/相对值,但我无法找到解决方案。感谢您的帮助!</p>
    </question>
<answer tick=

只需添加一个位置:相对于外容器。这样,拇指就会将其位置定向到该容器。添加顶部:0px;到拇指课程并完成

reactjs slider uislider
© www.soinside.com 2019 - 2024. All rights reserved.