是否可以重构香草 JS DOM 操作

Is it possible to refactor the vanilla JS DOM manipulation

我想知道是否有可能以一种干净漂亮的方式重构以下代码,以避免在每个 is 语句中重复:

if (statement) {
    menu.style.display = "inline-block";
    emoji.style.display = "inline-block";
    del.style.display = "block";
    upload.style.display = "block";
} else if (statement) {
    menu.style.display = "none";
    emoji.style.display = "inline-block";
    del.style.display = "none";
    upload.style.display = "none";
} else {
    menu.style.display = "none";
    emoji.style.display = "none";
    del.style.display = "none";
    upload.style.display = "none";
}

我知道我可以进行对象解构,但我也想减少行数,因为我的代码中重复了很多次这种和平代码。

一个选项是创建一个元素数组,并将它们的所有样式设置为 none 无论如何,然后在条件内,设置 不是 的样式将是 none:

[menu, emoji, del, upload].forEach(elm => elm.style.display = "none");
if (statement) {
  menu.style.display = "inline-block";
  emoji.style.display = "inline-block";
} else if (statement) {
  emoji.style.display = "inline-block";
}

如果您经常有多个元素想要更改其样式,请考虑一个函数:

const setAllDisplays = (display, ...elms) => elms.forEach(elm => elm.style.display = display);
setAllDisplays('none', menu, emoji, del, upload);
if (statement) {
  setAllDisplays("inline-block", menu, emoji);
} else if (statement) {
  emoji.style.display = "inline-block";
}

“...因为我在代码中多次重复了这段代码。”

所以就把它做成一个函数,保持原样:

function(condition1, condition2, menu, emoji, del, upload){
  if (condition1) {
    menu.style.display = "inline-block";
    emoji.style.display = "inline-block";
    del.style.display = "block";
    upload.style.display = "block";
  } else if (condition2) {
    menu.style.display = "none";
    emoji.style.display = "inline-block";
    del.style.display = "none";
    upload.style.display = "none";
  } else {
    menu.style.display = "none";
    emoji.style.display = "none";
    del.style.display = "none";
    upload.style.display = "none";
  }
}

然后你可以从任何地方用任何条件 1 和条件 2 调用函数

我建议这样做:

container.classList.remove("one", "two", "three");
if (expression) {
    container.classList.add("one");
} else if (expression) {
    container.classList.add("two");
} else {
    container.classList.add("three");
}

...在可重复使用的函数中,其中 container 是最近的包含 menuemojidelupload 的元素(在最坏的情况下是 body)。然后通过 CSS 设置单个元素的样式,例如:

.one menu {
    display: inline-block;
}
.two menu, .three menu {
    display: none;
}

显然,您将使用反映状态的名称而不是 "one""two""three"


根据表达式的不同,您可以使用此代码代替上面的 if/else if/else

container.classList.toggle("one", expression);
container.classList.toggle("two", expression);
container.classList.toggle("three", expression);

您可以为每个目标维护一个包含所需状态的对象,并获取索引并更新目标。

var display = {
        menu: ["inline-block", "none", "none"],
        emoji: ["inline-block", "inline-block", "none"],
        del: ["block", "none", "none"],
        upload: ["block", "none", "none"],
        reference: { menu, emoji, del, upload }
    },
    index = statement ? 0 : statement ? 1 : 2;

Object.keys(display).forEach(k => reference[k].stype.display = display[k][index]);