如何定义事件的状态函数



我想向你寻求帮助,因为我无法再使用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个矩形,每个矩形都有两个状态属性,colorsize,所以我们可以将其表示为数组对象:

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>

最新更新