JS: Какая функция сделает мой код СУХИМ? - PullRequest
0 голосов
/ 26 мая 2018

Моя программа
Этюд, который изначально рисует на сетке черным цветом.Пользователь нажимает Стереть , чтобы закрасить черные квадраты.Пользователь также может щелкнуть ** Rainbow ", чтобы нарисовать случайный цвет на каждом квадрате, то есть квадрат [0] может быть синим, квадрат [1] может быть фиолетовым ... и т. Д., Они рандомизированы при каждом наведении мыши .

Задача Вы заметите, что код для eraseGrid () и drawRainbow () почти идентичны.сделать это, иначе программа не будет работать должным образом. Это единственный способ для Радуга рисовать разные цвета на каждом наведении мыши .

Цель Если вы посмотрите на функцию, которую я прокомментировал внизу, я попытался придумать что-то, что я мог бы использовать для eraseGrid () и drawRainbow () , но при тестировании функциион не работал должным образом. Вместо того, чтобы рисовать случайный цвет на каждом указателе мыши , он создавал бы случайный цвет (скажем, синий) и рисовал синий на сетках. Если бы я переключил При включении Rainbow будет создан еще один случайный цвет (например, зеленый) и нарисован на нем.Сетка.
Я не понимаю, почему созданная мною функция не работает так, как задумано, тогда как повторный код работает.


/**************************** Input->Button DOM ****************************/

const newGrid = document.getElementById('new-grid');
newGrid.addEventListener('click', createGrid);

const erase = document.getElementById('erase');
erase.addEventListener('click', eraseGrid);

const rainbow = document.getElementById('rainbow');
rainbow.addEventListener('click', drawRainbow);

/*********************** Grid variable and creation ***********************/

const main = document.querySelector('main');
const div = main.getElementsByTagName('div');

drawGrid(16, ((600 / 16) - 2) + 'px');
pickColor('#333');

function createGrid() {

    // removes divs from largest to smallest
    for (let i = main.childNodes.length - 1; i >= 0 ; i--) {
        main.removeChild(main.childNodes[i]);
    }

    let size;
    do {
        size = parseInt(prompt("Please enter a number from 1 to 64", ""), 10);
    } while(Number.isNaN(size) || size > 64 || size < 1);

    const numPx = (600 / size) - 2;
    let px = numPx + 'px';

    drawGrid(size, px);
    pickColor('#333');
}


function pickColor(color) {
    for (let i = 0; i < main.childNodes.length; i++) {
        main.childNodes[i].addEventListener('mouseover', function change() {
            main.childNodes[i].style.backgroundColor = color;
        })
    }
}

// draw grid of div elements
function drawGrid(size, px) {
    for (let i = 0; i < size; i++) {
        for (let j = 0; j < size; j++) {
            const div = document.createElement('div');
            main.appendChild(div);
            div.setAttribute('style', `width: ${px}; height: ${px}; 
                float: left; border: 1px solid #333;`);
        }
    }

    // clear floats
    const div = document.createElement('div');
    div.setAttribute('class', 'clear');
    main.appendChild(div);
}

function eraseGrid() {
    erase.classList.toggle('erase');
    if (erase.className === 'erase') {
        rainbow.classList.remove('rainbow');
        main.addEventListener('mouseover', function(){
            pickColor('#f2f2f2');
        })
    }
    else {
        main.addEventListener('mouseover', function(){
            pickColor('#333');
        })
    }
}

function randColor() {
    let arr = [];
    for (let i = 0; i < 3; i++) {
        arr.push(Math.floor(Math.random() * 255));
    }
    return arr;
}

function drawRainbow() {
    rainbow.classList.toggle('rainbow');
    if (rainbow.className === 'rainbow') {
        erase.classList.remove('erase');
        main.addEventListener('mouseover', function(){
            pickColor('rgb(' + randColor() + ')');
        })
    }
    else {
        main.addEventListener('mouseover', function(){
            pickColor('#333');
        })
    }
    // changeColor(rainbow, 'rainbow', erase, 'erase', 'rgb(' + randColor() + ')')
}

/*function changeColor(newClass, newClassStr, oldClass, oldClassStr, color) {
    newClass.classList.toggle(newClassStr);
    if (newClass.className === newClassStr) {
        oldClass.classList.remove(oldClassStr);
        main.addEventListener('mouseover', function(){
            pickColor(color);
        })
    }
    else {
        main.addEventListener('mouseover', function(){
            pickColor('#333');
        })
    }
}*/

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Что касается закомментированной функции changeColor, вы должны иметь возможность выполнить ее рефакторинг следующим образом, если вы поместите радугу и сотрете в родительском объекте, чтобы вы могли найти их по имени.

const objects = {erase, rainbox};

function changeColor(str1, str2) { 
    objects[str1].classList.toggle(str1);
    if (objects[str1].className === str1) {
        objecs[str2].classList.remove(str2);
        main.addEventListener('mouseover', function(){
            pickColor('rgb(' + randColor() + ')');
        })
    }
    else {
        main.addEventListener('mouseover', function(){
            pickColor('#333');
        })
    }
}

Опять же, как @me_ упоминается в комментарии.Добавление eventListener на каждый клик, скорее всего, не то, что вы хотите.После пятого щелчка у вас будет пять EventListener и пять функций function(){pickColor('rgb(' + randColor() + ')');}, которые будут вызываться каждый раз, когда вы наводите курсор мыши на «main» (когда-либо расширяющийся для каждого щелчка ...)

(Изменить, потому чтокомментарии настолько ограничены:)

00Saad: я видел, что есть метод removeEventListener (), я бы реализовал его, добавив main.removeEventListener ('mouseover', function () {pickColor ('rgb (')+ randColor () + ')');}) после addEventListener?

Нет, сохранить функцию в переменной, если вы хотите легко удалить ее позже.

function(){...} <- это фрагмент кода, который создает новую функцию.Так вот: <code>main.removeEventListener('mouseover', function(){...}) создаст новую анонимную функцию и попытается удалить ее из прослушивателей событий main (там, где ее нет).

Кроме того, если вы используете хранимую функцию (const a = function(){..})), а затем addEventListener('mouseover', a)), что своего рода решит проблему, поскольку в любом случае вы не можете привязать одну и ту же функцию к одному и тому же событию несколько раз (это не будет иметь никакого эффекта).

Но тогда следующие addEventListener -колланы не будут иметь никакого значения, так что в вашем случае было бы гораздо разумнее вывести ваш mouseover-слушатель за пределы changeColor().

let isRandomColor = true;
main.addEventListener('mouseover', function(){
  pickColor( isRandomColor ? randomColor() : '#333' );
});

function changeColor(){
  if (...){
    isRandomColor = true;
  } else {
    isRandomColor = false;
  }
}
0 голосов
/ 26 мая 2018

Вы можете работать с именами, но похоже, что вы просто делаете

function go(str1, str2){
    document.getElementById(str1).classList.toggle(str1);
    if (document.getElementById(str1).className === str1) {
        document.getElementById(str2).classList.remove(str2);
        main.addEventListener('mouseover', function(){
            pickColor('#f2f2f2');
        })
    }
    else {
        main.addEventListener('mouseover', function(){
            pickColor('#333');
        })
    }
}

Просто позвоните с помощью go('erase', 'rainbow') или go('rainbow', 'erase')

function eraseGrid(){
    go('erase', 'rainbow');
}

function drawRainbow(){
    go('rainbow', 'erase');
}
...