我有3个div作为颜色可供选择,还有3个空白的div。我想让用户能够:
(1)单击彩色div,然后单击空白div,然后将空白div着色为用户选择的颜色。代码似乎起作用。
(2)我希望用户能够再次单击彩色的空白div,它变成白色。代码似乎起作用。
问题是,如果空白div是彩色的,并且用户选择了另一种颜色,然后再次单击该彩色的空白div,则会将新的颜色类别添加到div,并且事情变得不可预测。您可以打开控制台并跟踪空白div类的混乱更改。
如何解决此问题?我只希望空白div在两个类之间切换。
var chosenColor;
function pickColor(arg){
chosenColor=arg.id;
}
function draw(id){
document.getElementById(id).classList.toggle("white");
document.getElementById(id).classList.toggle(chosenColor);
}
.box{
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
}
.red{background: red}
.blue{background: blue;}
.yellow{background: yellow;}
.white{background: white;}
<html>
<body>
<div class="box red" id="red" onclick="pickColor(this)">1</div>
<div class="box blue" id="blue" onclick="pickColor(this)">2</div>
<div class="box yellow" id="yellow" onclick="pickColor(this)">3</div>
<br><br>
<div class="box white" id="4" onclick="draw(4)">4</div>
<div class="box white" id="5" onclick="draw(5)">5</div>
<div class="box white" id="6" onclick="draw(6)">6</div>
</body>
</html>
答案 0 :(得分:4)
不是使用类,而是遇到分配多个嵌套类的问题,或者不得不使用复杂的 white 逻辑...
我将使用data-*
属性:
var chosenColor;
function pick(el) {
chosenColor = el.dataset.color;
}
function draw(el) {
el.dataset.color = el.dataset.color ? "" : chosenColor;
}
body { background: #eee; }
.box {
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
background: white; /* BY DEFAULT !!! */
}
[data-color=red] { background: red; }
[data-color=blue] { background: blue; }
[data-color=yellow] { background: yellow; }
<div class="box" onclick="pick(this)" data-color="red">1</div>
<div class="box" onclick="pick(this)" data-color="blue">2</div>
<div class="box" onclick="pick(this)" data-color="yellow">3</div>
<br><br>
<div class="box" onclick="draw(this)">4</div>
<div class="box" onclick="draw(this)">5</div>
<div class="box" onclick="draw(this)">6</div>
三元组el.dataset.color = el.dataset.color ? "" : chosenColor;
的作用是:
data-color
设置为data-color
的{{1}} (无) ""
设置为预先选择的data-color
答案 1 :(得分:1)
检查元素的classname
是否为white
。如果不是,则将其类名称设置为white
-否则,将其设置为所选颜色。您可以将盒子放在容器中,并使用.container > div
选择器,而无需为盒子提供.box
类。另外,在侦听器中,this
会引用被单击的元素-当您已经有对该元素的引用时,就无需使用getElementById
。
var chosenColor;
function pickColor(arg) {
chosenColor = arg.id;
}
function draw(element, id) {
if (element.className !== 'white') element.className = 'white';
else element.className = chosenColor;
}
.container > div {
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
}
.red {
background: red
}
.blue {
background: blue;
}
.yellow {
background: yellow;
}
.white {
background: white;
}
<div class="container">
<div class="red" id="red" onclick="pickColor(this)">1</div>
<div class="blue" id="blue" onclick="pickColor(this)">2</div>
<div class="yellow" id="yellow" onclick="pickColor(this)">3</div>
<br><br>
<div class="white" id="4" onclick="draw(this, 4)">4</div>
<div class="white" id="5" onclick="draw(this, 5)">5</div>
<div class="white" id="6" onclick="draw(this, 6)">6</div>
</div>
答案 2 :(得分:1)
请参阅-https://codepen.io/stephanieschellin/pen/xyYxrj/(带注释的代码)
或...
var activeColor
function setPickerColor(event) {
activeColor = event.target.dataset.boxColorIs
}
function setThisBoxColor(event) {
let element = event.target
let the_existing_color_of_this_box = element.dataset.boxColorIs
if (the_existing_color_of_this_box == activeColor) {
delete element.dataset.boxColorIs
} else {
element.dataset.boxColorIs = activeColor
}
}
.box {
width: 100px;
height: 100px;
border: 1px solid black;
display: inline-block;
background: white;
}
[data-box-color-is="red"] {
background: red
}
[data-box-color-is="blue"] {
background: blue;
}
[data-box-color-is="yellow"] {
background: yellow;
}
<html>
<body>
<div id="box-1" class="box" data-box-color-is="red" onclick="setPickerColor(event)">1</div>
<div id="box-2" class="box" data-box-color-is="blue" onclick="setPickerColor(event)">2</div>
<div id="box-3" class="box" data-box-color-is="yellow" onclick="setPickerColor(event)">3</div>
<br>
<br>
<div id="box-4" class="box" onclick="setThisBoxColor(event)">4</div>
<div id="box-5" class="box" onclick="setThisBoxColor(event)">5</div>
<div id="box-6" class="box" onclick="setThisBoxColor(event)">6</div>
</body>
</html>
使用data-
属性,您可以将JavaScript功能问题与CSS类分离。这简化了您的逻辑,但最重要的是,它使样式化应用程序的人们可以独立于添加JS功能的人们工作。当您的团队使用BEM或OOCSS模式时,这种去耦变得非常重要。
理想情况下,您无需使用data-
来维护'state',而是将样式附加到data-
属性,并具有另一个基于classList
状态设置data-
的功能。让您100%确定所做的样式更改将永远不会影响JS功能(QA会爱上您)。但这是本文以外的发展。
在此设置中,我们没有使用id
,但是我将它们留在了这里,因为它是重要的最佳实践。此代码很可能会演变成具有侦听器的组件,而不是内联onClick
调用。 JavaScript选择器应始终附加到id
或data-
变量,而不是类。而且,ID应该始终存在,以供质量检查小组在其脚本中使用。您可能会冒险更改类名或将其删除以调整样式,并无意间破坏了JS侦听器。
我切换了参数以传递“事件”而不是元素“ this”。使用JS事件函数的任何人都将事件对象作为第一个参数。您可以根据需要将“ this”作为第二个参数,但是event.target会给您同样的东西。
要注意的另一件事是在声明data-
变量和从JS调用它之间的语法变化。
HTML <div data-box-color-is="red">1</div>
JS event.target.dataset.boxColorIs
无论数据格式如何格式化,在JS中引用它时,它总是会解析为camelCase ... data-box_color--IS
仍会变成... dataset.boxColorIs
作为代码的改进,您可以删除全局JS var,然后使用<body>
将值存储在data-
或页面上的其他元素上。这将为您提供一个真理或“状态”的单一来源,多个要素/组件可以在不混乱全局空间的情况下进行引用。
https://css-tricks.com/bem-101/
https://philipwalton.com/articles/side-effects-in-css/
https://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/
https://philipwalton.com/articles/decoupling-html-css-and-javascript/