javascript - Firefox 上的范围 slider 重置为默认值

标签 javascript html css

所以我正在制作一个带有范围 slider 的 eclipse 刻草图来更改网格大小,但是一旦我在更改值后移动鼠标, slider 就会不断重置为其默认大小(16x16)(如果我更改值并且不移动鼠标,大小不会重置)。由于某种原因,这在 Chrome 上不会发生:值和网格大小都会发生变化并保持这种状态,直到我再次更改它们。

这是 JSFiddle:https://jsfiddle.net/CamiCoding/7zpt14cs/

HTML:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>Etch-a-Sketch</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" type="text/css" href="css/style.css">
    </head>
    <body>
        <div class="title">
            <h1>Etch-a-Sketch</h1>
        </div>
        <div class="btns">
            <button id="blackBtn">Black</button>
            <button id="rainbowBtn">Rainbow</button>
            <button id="colorBtn">Color</button>
            <button id="eraserBtn">Eraser</button>
            <button id="resetBtn">Reset</button>
            <div class="colorPicker">
                <input type="color" id="color" value="#000000">
                <span>Pick a color</span>
            </div>
            <div class="sliderAndValue">
                <input type="range" min="2" max="100" value="16" id="slider">
                <p class="value">16</p>
            </div>
        </div>
        <div class="grid">
        </div>
        <script src="script.js" defer></script>
    </body>
    </html>

CSS:

@font-face {
  src:  url("../fonts/sf-atarian-system.regular.ttf");
  font-family: Atarian;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-family: Atarian;
  background-color: #D1D1D1;
}

.title h1 {
  font-size: 80px;
  margin: 0px;
}

.btns {
  display: flex;
  flex-direction: row;
  width: 700px;
  height: 50px;
  justify-content: space-evenly;
  margin-top: 20px;
  margin-bottom: 20px;
}

.btns button {
  font-family: Atarian;
  font-size: 24px;
  height: 40px;
  width: 80px;
  border-radius: 5px;
  transition: transform 0.2s ease-in-out;
}

.btns button:hover {
  transform: scale(1.2);
}

.btns .active {
  background-color: #505050;
  color: white;
}

.colorPicker {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 20px;
}

.color span {
  text-align: center;
}

#color {
  width: 90px;
}

.sliderAndValue {
  -webkit-appearance: none;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  font-size: 24px;
}

#slider {
  -webkit-appearance: none;
  width: 150px;
  height: 10px;
  background: #000;
  outline: none;
  border: 4px solid gray;
  border-radius: 4px;
}

/* for firefox */
#slider::-moz-range-thumb {
  width: 5px;
  height: 20px;
  background: #000;
  cursor: pointer;
  border: 4px solid gray;
  border-radius: 4px;
}

/* for chrome/safari */
#slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 5px;
  height: 20px;
  background: #000;
  cursor: pointer;
  border: 4px solid gray;
  border-radius: 4px;
}

.cell {
  border: 1px solid black;
}

.cell.active {
  background-color: black;
}

.grid {
  display: inline-grid;
  grid-template-columns: repeat(16, 2fr);
  grid-template-rows: repeat(16, 2fr);
  border: 5px solid gray;
  border-radius: 5px;
  height: 700px;
  width: 700px;
  background-color: white;
}

JS:

const grid = document.querySelector('.grid');
const resetBtn = document.getElementById('resetBtn');
const eraserBtn = document.getElementById('eraserBtn');
const blackBtn = document.getElementById('blackBtn');
const colorBtn = document.getElementById('colorBtn')
const colorValue = document.getElementById('color');
const slider = document.getElementById('slider');
const sliderValue = document.querySelector('.value');
const DEFAULT_COLOR = '#000000';
const DEFAULT_MODE = 'black';
const DEFAULT_SIZE = 16;

let currentColor = DEFAULT_COLOR;
let currentMode = DEFAULT_MODE;
let mouseDown = false

document.body.onmousedown = () => (mouseDown = true)
document.body.onmouseup = () => (mouseDown = false)

function setCurrentColor(newColor) {
    currentColor = newColor;
}

function setCurrentMode(newMode) {
    activateButton(newMode);
    currentMode = newMode;
}

blackBtn.onclick = () => setCurrentMode('black');
rainbowBtn.onclick = () => setCurrentMode('rainbow');
eraserBtn.onclick = () => setCurrentMode('eraser');
colorBtn.onclick = () => setCurrentMode('color');
resetBtn.onclick = () => createGrid();

function createGrid() {
    removeCells(grid);
    let val = document.getElementById('slider').value;
    sliderValue.textContent = val;
    grid.style.gridTemplateColumns = (`repeat(${val}, 2fr`);
    grid.style.gridTemplateRows = (`repeat(${val}, 2fr`);
    for(let i = 0; i < val * val; i++) {
        const cell = document.createElement('div');
        cell.classList.add('cell');
        cell.addEventListener('mouseover', changeColor);
        cell.addEventListener('mousedown', changeColor);
        grid.appendChild(cell);
    }
}

function activateButton(newMode) {
    if (currentMode === 'rainbow') {
        rainbowBtn.classList.remove('active');
    } else if (currentMode === 'color') {
        colorBtn.classList.remove('active');
    } else if (currentMode === 'eraser') {
        eraserBtn.classList.remove('active');
    } else if (currentMode === 'black') {
        blackBtn.classList.remove('active');
    }

    if (newMode === 'rainbow') {
        rainbowBtn.classList.add('active');
    } else if (newMode === 'color') {
        colorBtn.classList.add('active');
    } else if (newMode === 'eraser') {
        eraserBtn.classList.add('active');
    } else if (newMode === 'black') {
        blackBtn.classList.add('active');
    }
}

function changeColor(e) {
    if (e.type === 'mouseover' && !mouseDown) return;
    if (currentMode === 'rainbow') {
        const randomR = Math.floor(Math.random() * 256);
        const randomG = Math.floor(Math.random() * 256);
        const randomB = Math.floor(Math.random() * 256);
        e.target.style.backgroundColor = `rgb(${randomR}, ${randomG}, ${randomB})`;
    } else if (currentMode === 'color') {
        e.target.style.backgroundColor = colorValue.value;
    } else if (currentMode === 'eraser') {
        e.target.style.backgroundColor = '#ffffff';
    } else if (currentMode === 'black') {
        e.target.style.background = '#000000';
    }
}

slider.addEventListener('input', function(){
    let val = document.getElementById('slider').value;
    sliderValue.textContent = val;
    removeCells(grid);
    grid.style.gridTemplateColumns = (`repeat(${val}, 2fr`);
    grid.style.gridTemplateRows = (`repeat(${val}, 2fr`);
    for (let i = 0; i < val * val; i++) {
        const cell = document.createElement('div');
        cell.classList.add('cell');
        cell.addEventListener('mouseover', changeColor);
        cell.addEventListener('mousedown', changeColor);
        grid.appendChild(cell);
    }
});

function removeCells(parent){
    while(grid.firstChild){
        grid.removeChild(grid.firstChild);
    }
}

window.onload = () => {
    createGrid(DEFAULT_SIZE);
    activateButton(DEFAULT_MODE);
}

我确实对同一个元素有另一个问题,但关于不同的问题,请告诉我是否应该为此发布不同的问题,或者我是否也应该在这里发布!

提前非常感谢:)。

最佳答案

我能够找到问题的根源并解决它。听起来很奇怪,但 document.body.onmousedowndocument.body.onmouseup 正在造成问题。
addEventListener 替换它们似乎可以修复它。

通过最大限度地利用 createGrid() 函数,我还删除了一些重复的代码(在 slider 的输入监听器中)

const grid = document.querySelector('.grid');
const resetBtn = document.getElementById('resetBtn');
const eraserBtn = document.getElementById('eraserBtn');
const blackBtn = document.getElementById('blackBtn');
const colorBtn = document.getElementById('colorBtn')
const colorValue = document.getElementById('color');
const slider = document.querySelector('#slider');
const sliderValue = document.querySelector('.value');
const DEFAULT_COLOR = '#000000';
const DEFAULT_MODE = 'black';
const DEFAULT_SIZE = 16;

let currentColor = DEFAULT_COLOR;
let currentMode = DEFAULT_MODE;
let mouseDown = false

document.body.addEventListener("mousedown", () => (mouseDown = true))
document.body.addEventListener("mouseup", () => (mouseDown = false))

function setCurrentColor(newColor) {
  currentColor = newColor;
}

function setCurrentMode(newMode) {
  activateButton(newMode);
  currentMode = newMode;
}

blackBtn.onclick = () => setCurrentMode('black');
rainbowBtn.onclick = () => setCurrentMode('rainbow');
eraserBtn.onclick = () => setCurrentMode('eraser');
colorBtn.onclick = () => setCurrentMode('color');
resetBtn.onclick = () => createGrid();

function createGrid(val = 16) {
  slider.value = val;
  sliderValue.textContent = val;
  removeCells(grid);
  grid.style.gridTemplateColumns = (`repeat(${val}, 2fr`);
  grid.style.gridTemplateRows = (`repeat(${val}, 2fr`);
  for (let i = 0; i < val * val; i++) {
    const cell = document.createElement('div');
    cell.classList.add('cell');
    cell.addEventListener('mouseover', changeColor);
    cell.addEventListener('mousedown', changeColor);
    grid.appendChild(cell);
  }

}

function activateButton(newMode) {
  if (currentMode === 'rainbow') {
    rainbowBtn.classList.remove('active');
  } else if (currentMode === 'color') {
    colorBtn.classList.remove('active');
  } else if (currentMode === 'eraser') {
    eraserBtn.classList.remove('active');
  } else if (currentMode === 'black') {
    blackBtn.classList.remove('active');
  }

  if (newMode === 'rainbow') {
    rainbowBtn.classList.add('active');
  } else if (newMode === 'color') {
    colorBtn.classList.add('active');
  } else if (newMode === 'eraser') {
    eraserBtn.classList.add('active');
  } else if (newMode === 'black') {
    blackBtn.classList.add('active');
  }
}

function changeColor(e) {
  if (e.type === 'mouseover' && !mouseDown) return;
  if (currentMode === 'rainbow') {
    const randomR = Math.floor(Math.random() * 256);
    const randomG = Math.floor(Math.random() * 256);
    const randomB = Math.floor(Math.random() * 256);
    e.target.style.backgroundColor = `rgb(${randomR}, ${randomG}, ${randomB})`;
  } else if (currentMode === 'color') {
    e.target.style.backgroundColor = colorValue.value;
  } else if (currentMode === 'eraser') {
    e.target.style.backgroundColor = '#ffffff';
  } else if (currentMode === 'black') {
    e.target.style.background = '#000000';
  }
}

slider.addEventListener('input', function(e) {
  let val = parseInt(document.getElementById('slider').value);
  createGrid(val);
});

function removeCells(parent) {
  while (grid.firstChild) {
    grid.removeChild(grid.firstChild);
  }
}

window.onload = () => {
  createGrid(DEFAULT_SIZE);
  activateButton(DEFAULT_MODE);
}
@font-face {
  src:  url("../fonts/sf-atarian-system.regular.ttf");
  font-family: Atarian;
}

body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  font-family: Atarian;
  background-color: #D1D1D1;
}

.title h1 {
  font-size: 80px;
  margin: 0px;
}

.btns {
  display: flex;
  flex-direction: row;
  width: 700px;
  height: 50px;
  justify-content: space-evenly;
  margin-top: 20px;
  margin-bottom: 20px;
}

.btns button {
  font-family: Atarian;
  font-size: 24px;
  height: 40px;
  width: 80px;
  border-radius: 5px;
  transition: transform 0.2s ease-in-out;
}

.btns button:hover {
  transform: scale(1.2);
}

.btns .active {
  background-color: #505050;
  color: white;
}

.colorPicker {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 20px;
}

.color span {
  text-align: center;
}

#color {
  width: 90px;
}

.sliderAndValue {
  -webkit-appearance: none;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  font-size: 24px;
}

#slider {
  -webkit-appearance: none;
  width: 150px;
  height: 10px;
  background: #000;
  outline: none;
  border: 4px solid gray;
  border-radius: 4px;
}

/* for firefox */
#slider::-moz-range-thumb {
  width: 5px;
  height: 20px;
  background: #000;
  cursor: pointer;
  border: 4px solid gray;
  border-radius: 4px;
}

/* for chrome/safari */
#slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 5px;
  height: 20px;
  background: #000;
  cursor: pointer;
  border: 4px solid gray;
  border-radius: 4px;
}

.cell {
  border: 1px solid black;
}

.cell.active {
  background-color: black;
}

.grid {
  display: inline-grid;
  grid-template-columns: repeat(16, 2fr);
  grid-template-rows: repeat(16, 2fr);
  border: 5px solid gray;
  border-radius: 5px;
  height: 700px;
  width: 700px;
  background-color: white;
  user-select: none;
}
<!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>Etch-a-Sketch</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" type="text/css" href="css/style.css">
    </head>
    <body>
        <div class="title">
            <h1>Etch-a-Sketch</h1>
        </div>
        <div class="btns">
            <button id="blackBtn">Black</button>
            <button id="rainbowBtn">Rainbow</button>
            <button id="colorBtn">Color</button>
            <button id="eraserBtn">Eraser</button>
            <button id="resetBtn">Reset</button>
            <div class="colorPicker">
                <input type="color" id="color" value="#000000">
                <span>Pick a color</span>
            </div>
            <div class="sliderAndValue">
                <input type="range" min="2" value="16" id="slider">
                <p class="value">16</p>
            </div>
        </div>
        <div class="grid">
        </div>
        <script src="script.js" defer></script>
    </body>
    </html>

关于javascript - Firefox 上的范围 slider 重置为默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71497690/

相关文章:

javascript - 如何获得一定数量的、在一定范围内唯一的随机数?

javascript - Google+ signinCallback 调用了两次并且在处理过程中丢失了 authresult

Javascript 功能在主页上运行,但在第二页上停止

javascript - 未捕获的 TypeError : this. get(...).querySelectorAll 不是函数

javascript - iPad Safari 的悬停事件

javascript - HTML5 与 javascript 解析和显示文本文件

javascript - 使用 document.write 编写 HTML 导致尝试嵌入 YouTube 时出错

CSS 列 - 如果元素位于列底部则强制中断

html - Iframe 没有控件工作,视频不播放

html - 响应表 - 静态标题列到行