开发者问题收集

点击监听器的 e.stopPropagation 不起作用

2021-11-01
407

我正在尝试构建随机颜色生成器。它为每种生成的颜色创建框。您可以将鼠标悬停在每个颜色上,然后复制或锁定您喜欢的颜色。

当我单击复制按钮或背景部分时,会出现问题。它还会触发锁定按钮,而锁定按钮也会触发复制按钮。

我不知道为什么会发生这种情况,因为在使用的函数中有 e.stopPropagation)

可视化: RGB COLOR GENERATOR

我是 js 世界的新手,所以如果您发现任何可以修复的问题,我将非常感激您告诉我如何改进它

完整代码:

//selecting JS OBJECTS

const background = document.querySelector('.background');
const copy = document.querySelector('#copy');
const p = document.querySelector('p');
const body = document.querySelector('body');
const colorContainer = document.querySelector('.color-container');

let spacebarFirstCount = 0;

body.addEventListener('keydown', (e) => {
    if (e.key === " ") {
        const color = generateRGB();
        changeBackgroundColor(color);
        p.innerText = color;

        if (copy.innerText != "copy") {
            copy.innerText = "copy";
        }

        addColorBox(color);

        if (spacebarFirstCount !== 3) {
            if (spacebarFirstCount === 2) {
                document.querySelector('.spacebar').remove();
            }
            spacebarFirstCount++;
        }
    }
});

copy.addEventListener('click', () => {
    navigator.clipboard.writeText(p.innerText);
    copy.innerText = "done";
})

const addColorBox = (color) => {
    const colorBox = document.createElement('div');
    colorBox.style.backgroundColor = color;
    colorBox.classList.toggle('color-box');

    colorBox.addEventListener('mouseover', hover2)

    fixBoxNumber();

    colorContainer.append(colorBox);


}

const generate255 = () => {
    return Math.floor(Math.random() * 255) + 1;
}

const generateRGB = () => {
    const r = generate255();
    const g = generate255();
    const b = generate255();
    const alpha = (Math.floor((Math.random() + 0.1) * 100) / 100);

    return `rgb(${r},${g},${b},${alpha})`;

}

const changeBackgroundColor = (color) => {
    background.style.backgroundColor = color;
}

function hover2() {
    const copyText = document.createElement('span');
    const lockText = document.createElement('span');

    copyText.append("copy");

    copyText.classList.toggle("hoverText");
    lockText.classList.toggle("hoverText");
    
    this.classList.toggle('box-animation');
    this.removeEventListener('mouseover', hover2);

    const currentColor = background.style.background;
    changeBackgroundColor(this.style.backgroundColor);

    function copyToClipboard(event) {
        navigator.clipboard.writeText(this.style.backgroundColor);
        copyText.innerText = "copied";
        this.removeEventListener('click', copyToClipboard);
        event.stopPropagation();
    }

    function leaving() {
        copyText.remove();
        lockText.remove();
        this.classList.remove('box-animation');
        this.addEventListener('mouseover', hover2);
        this.removeEventListener('click', copyToClipboard);
        this.removeEventListener('mouseleave', leaving);
        this.removeEventListener('click', locking);
    }

    this.addEventListener('click', copyToClipboard);

    this.addEventListener('mouseleave', leaving)



    if (!this.hasAttribute('locked')) {
        lockText.append("lock");
    }
    else {
        lockText.append("locked");
    }


    // ! Stop propagation nie działa


    function locking(e) {

        if (!this.hasAttribute('locked')) {
            this.setAttribute('locked', 'true');
            lockText.innerText = "locked";
        } else {
            this.removeAttribute('locked');
            lockText.innerText = "lock";
        }
        e.stopPropagation();
    }

    this.addEventListener('click', locking);



    this.append(lockText);
    this.append(copyText);


}

const fixBoxNumber = () => {
    if (colorContainer.childElementCount >= 19) {

        const deleteBoxes = Object.values(colorContainer.childNodes).filter((box) => !box.hasAttribute("locked"));

        if (deleteBoxes.length < 12) {
            for (let i = 0; i < deleteBoxes.length; i++) {
                deleteBoxes[i].remove();
            }
        }
        else {
            for (let i = 0; i < 12; i++) {
                deleteBoxes[i].remove();
            }
        }

    }
}
1个回答

这是一个随机颜色的片段:

  • 您可以锁定/解锁颜色
  • 您可以复制一种颜色(好的,它不适用于 navigator.clipboard 在此处禁止使用)
  • 您可以重新将颜色重新授予(锁定颜色保持相同)
101121924

您可以看到

  • 颜色列表操纵封装在 colorlist 类中:没有任何突变或修改该类外部的颜色列表。这意味着在对颜色列表进行了每次修改后,应重新渲染视图(否则修改不会显示)
  • eventlistener 在每个重新渲染中都添加:这在较大的尺度上可能无效,但是在此大小下,它并没有真正的区别(浏览器倾向于删除不需要的听众,那为什么要打扰;)
  • 而不是 class 我可以使用 factory (如今是时尚的),但这并没有任何区别( source 1 source 2 等)

另外,我会说:在单独的文件中会更好 - 因此,如果您在这样的环境中工作,请尝试将其分解为更明智的块。

muka.gergely
2021-11-01