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

How can I use declared variables of a function outside the function but keeping their values in 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

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

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

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

基于您的目标的可能解决方案

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

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

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

下面的怎么样:

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, 0);
  background-color: rgba(0, 0, 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, 0, 0.4);
  padding: 60px;
}

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