如何在函数外使用函数的声明变量但将它们的值保留在 javascript 中?

问题描述

我有这个对象数组

const galLERY = [
{
    color: "red",titulo: "Stuff"
},{
    color: "pink",titulo: "Thing"
},{
    color: "green",titulo: "Something"
}
];

以及这些带有模板文字函数

function galTemplate(gal) {
    let modalBtn = gal.color + "-btn";
    return `
    <div class="content-entry" id="${modalBtn}">
        <div href="" style="background-color: ${gal.color};"></div>
        <p class="gallery-entry-titulo">${gal.titulo}</p>
    </div>
    `
}

function galModal(modal) {
    let modalModal = modal.color + "-modal";
    return `
    <div class="popup-bg" id="${modalModal}">
      <div class="entry-popup">
        <div style="background-color: ${modal.color};></div>
      </div>
    </div>
    `
}

情况是我想使用变量 modalBtn 和 modamodal 及其值来创建一个简单的模态函数,如下所示

modalBtn.onclick = function() {
    modalModal.style.display = "block";
}

当然,这是真实项目的一个例子。 这是最佳理解的完整示例的Codepen

解决方法

在 JavaScript 中,我们有一个叫做 Global Variables 的东西。我们可以利用这类似于下面的一段代码:

let global_var;
function set_var(){
    global_var = "Hello"
}
set_var();
console.log(global_var);
,

变量

您可以像这样使用关键字 var 声明函数范围之外的变量:

var my_global = 1;
function do_something_with_global() {
    console.log(my_global++);
}
do_something_with_global(); // will print: 1
console.log(my_global); // will print: 2

它们将存在于全球空间中,因此您可以从任何地方访问它们。这通常是一个糟糕的设计选择,因为这些东西不会被垃圾收集(在函数范围内,内存将在执行后被释放)。

此外,现在可以从任何地方修改全局变量,因此您也不希望这样做。当您不小心覆盖变量时,也可能存在难以发现的错误。

请注意这一点。您可能还想在这里阅读:https://www.w3.org/wiki/JavaScript_best_practices

根据您的目标可能的解决方案

我可能会选择一种不同的方式来创建元素并一次性渲染它们(即 createElement(),然后依次添加侦听器和模态)。

但是,我想尽可能少地更改,以便您可以更轻松地使用它。

您可以也可能应该只切换 CSS 类,而不是修改单个属性。

以下情况如何:

const GALLERY = [{
    color: 'red',titulo: 'Stuff'
  },{
    color: 'pink',titulo: 'Thing'
  },{
    color: 'green',titulo: 'Something'
  }
];

function galTemplate(gal) {
  let modalBtn = gal.color + '-btn';
  return `
    <div class="content-entry" id="${modalBtn}">
        <div href="" style="background-color: ${gal.color};"></div>
        <p class="gallery-entry-titulo">${gal.titulo}</p>
    </div>
    `;
}

function galModal(modal) {
  let modalModal = modal.color + '-modal';
  return `
    <div class="popup-bg" id="${modalModal}">
      <div class="entry-popup">
        <div style="background-color: ${modal.color};"></div>
      </div>
    </div>
    `;
}

function addClickListeners(gal) {
  let btnId = gal.color + '-btn';
  let modalId = gal.color + '-modal';
  let elBtn = document.getElementById(btnId);
  let elModal = document.getElementById(modalId);
  elBtn.onclick = function() {
    console.log('click: btn: ' + this.id + ',modal: ' + elModal.id);
    elModal.classList.toggle('show-popup');
  }
  /* to dispose the popup on click */
  elModal.onclick = function() {
    this.classList.toggle('show-popup');
  }
  /* --- */
}

document.getElementById("my-content").innerHTML = `
  <div class="content">
    ${GALLERY.map(galTemplate).join('')}
  </div>
  ${GALLERY.map(galModal).join('')}
`;
GALLERY.map(addClickListeners);
body {
  background: #01235f;
  color: white;
}

.content {
  display: grid;
  grid-template-columns: repeat(5,1fr);
  grid-gap: 0px;
  grid-auto-rows: 1fr;
}

.content-entry {
  width: 150px;
  height: 150px;
  position: relative;
  cursor: pointer;
}

.content-entry div {
  width: 100%;
  height: 100%;
}

.gallery-entry-titulo {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translate(-50%,-30%);
  cursor: pointer;
}

.popup-bg {
  display: none;
  position: fixed;
  z-index: 3;
  left: 0;
  top: 0;
  bottom: 0;
  right: 0;
  width: 100%;
  height: 100%;
  background-color: rgb(0,0);
  background-color: rgba(0,0.6);
  backdrop-filter: blur(5px);
}

.show-popup {
  display: block;
}

.entry-popup {
  position: absolute;
  z-index: 9;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: auto;
  width: 50%;
  height: 80%;
  overflow: auto;
  background-color: rgba(0,0.4);
  padding: 60px;
}

.entry-popup div {
  width: 100%;
  height: 100%;
  margin: 20px auto;
}
<div class="content" id="my-content"></div>