我想向你寻求帮助,因为我无法再使用JS,因为我不明白别人问我什么。你能帮我定义reDisplay函数吗?我不得不在每个"显示"的末尾称之为(reDisplay(;控制器";函数,因为它必须为事件而不是事件函数工作。
reDisplay函数必须根据表示矩形状态的两个变量重新绘制矩形。它必须在我的3个点击函数中调用,这些函数被挂接到事件
我很震惊,因为我的JS水平不好,不明白别人问我什么。:(
代码为:
<body>
<div class="rectContainer">
<div class="rect red bigRect"></div>
<div class="rect red bigRect"></div>
<div class="rect red bigRect"></div>
</div>
<script>
let rectAreBig = true;
console.log(rectAreBig);
let stateRect1Color = "red";
console.log(stateRect1Color);
const rect1 = document.querySelector(".rect:nth-child(1)");
rect1.addEventListener("click", () => {
switch (stateRect1Color) {
case "red":
stateRect1Color = "blue";
rect1.classList.remove("red");
rect1.classList.add("blue");
break;
case "blue":
stateRect1Color = "yellow";
rect1.classList.remove("blue");
rect1.classList.add("yellow");
break;
case "yellow":
stateRect1Color = "green";
rect1.classList.remove("yellow");
rect1.classList.add("green");
break;
case "green":
stateRect1Color = "red";
rect1.classList.remove("green");
rect1.classList.add("red");
break;
default:
stateRect1Color = "red";
}
});
let rect2 = document.querySelector(".rectContainer :nth-child(2)");
let allRects = document.querySelectorAll(".rect");
rect2.addEventListener("click", () => {
if (rectAreBig) {
for (let i = 0; i < allRects.length; i++) {
allRects[i].classList.add("smallRect");
rectAreBig = false;
}
} else {
for (let i = 0; i < allRects.length; i++) {
allRects[i].classList.remove("smallRect");
rectAreBig = true; // comme dans les cours de algo
}
}
});
const rect3 = document.querySelector(
".rectContainer :nth-child(3)"
);
rect3.addEventListener("click", () => {
for (let i = 0; i < allRects.length; i++) {
allRects[i].classList.remove("smallRect", stateRect1Color);
allRects[0].classList.add("red");
}
});
</script>
</body>
</html>
我提前感谢你能给我的任何帮助。
这是应用迷你模型-视图-控制器(MVC(模式的绝佳机会。
- 模型仅包含状态
-
视图仅处理渲染。
- 将模型作为其输入
-
控制器处理逻辑/事件、更新模型并调用视图方法。
- 将视图和模型都作为输入
将所有3个函数放在一个函数中是可能的,但更难消化和导航。
型号
我们有3个矩形,每个矩形都有两个状态属性,color
和size
,所以我们可以将其表示为数组对象:
const model = [
{color: 'red', size: 'big'},
{color: 'red', size: 'big'},
{color: 'red', size: 'big'}
]
查看
视图将我们的模型作为输入,并根据它来操纵DOM。我们可以通过多种方式来实现它的方法,例如每次重新渲染元素,或者更新特定的类名等。为此,我们可以保持它的简单性,并使其清晰,并基于每次重新渲染。
所有与DOM相关的函数都会放在视图中。
function view(model) {
const container = document.querySelector('.rectContainer');
const rectElements = {}
function createRectHTML(rect) {
return `<div class="rect ${rect.color} ${rect.size}"></div>`
}
function render() {
const HTMLArray = model.map(rectObj => createRectHTML(rectObj));
const elementHTML = HTMLArray.join('');
container.innerHTML = '';
container.innerHTML = elementHTML;
rectElements.one = container.children[0];
rectElements.two = container.children[1];
rectElements.three = container.children[2];
}
return {render, rectElements}
}
控制器
控制器将获取我们的模型实例和视图函数,然后将模型传递到视图函数中以创建视图实例。它设置侦听器,并包含将操作模型和调用视图方法的处理程序。
function controller(model, viewFunction) {
const view = viewFunction(model);
let rectAreBig = true;
function update() {
view.render();
setListeners();
}
update();
function changeColor(){
const color = model[0].color;
const newColor = color === 'red'? 'blue'
: color === 'blue' ? 'yellow'
: color === 'yellow' ? 'green'
: 'red'
model[0].color = newColor;
update();
}
function changeSize(){
const newSize = rectAreBig ? 'small' : 'big';
rectAreBig = !rectAreBig;
model.forEach(rect => rect.size = newSize);
update();
}
function reset() {
model.forEach(rect => {
rect.size = 'big';
rect.color = 'red';
})
rectAreBig = true;
update();
}
function setListeners() {
view.rectElements.one.onclick = () => changeColor();
view.rectElements.two.onclick = () => changeSize();
view.rectElements.three.onclick = () => reset();
}
}
综合起来:
const model = [
{color: 'red', size: 'big'},
{color: 'red', size: 'big'},
{color: 'red', size: 'big'}
]
function view(model) {
const container = document.querySelector('.rectContainer');
const rectElements = {}
function createRectHTML(rect) {
return `<div class="rect ${rect.color} ${rect.size}"></div>`
}
function render() {
const HTMLArray = model.map(rectObj => createRectHTML(rectObj));
const elementHTML = HTMLArray.join('');
container.innerHTML = '';
container.innerHTML = elementHTML;
rectElements.one = container.children[0];
rectElements.two = container.children[1];
rectElements.three = container.children[2];
}
return {render, rectElements}
}
function controller(model, viewFunction) {
const view = viewFunction(model);
let rectAreBig = true;
function update() {
view.render();
setListeners();
}
update();
function changeColor(){
const color = model[0].color;
const newColor = color === 'red'? 'blue'
: color === 'blue' ? 'yellow'
: color === 'yellow' ? 'green'
: 'red'
model[0].color = newColor;
update();
}
function changeSize(){
const newSize = rectAreBig ? 'small' : 'big';
rectAreBig = !rectAreBig;
model.forEach(rect => rect.size = newSize);
update();
}
function reset() {
model.forEach(rect => {
rect.size = 'big';
rect.color = 'red';
})
rectAreBig = true;
update();
}
function setListeners() {
view.rectElements.one.onclick = () => changeColor();
view.rectElements.two.onclick = () => changeSize();
view.rectElements.three.onclick = () => reset();
}
}
controller(model, view)
.rectContainer{
display: flex;
gap: 20px;
}
.rect.big{
width: 100px;
height: 100px;
}
.rect.small{
width: 70px;
height: 70px;
}
.rect.red{
background-color: red;
}
.rect.blue{
background-color: blue;
}
.rect.green{
background-color: green;
}
.rect.yellow{
background-color: yellow;
}
<div class="rectContainer"></div>