Как перезаписать переменную динамическим способом, а не жестко запрограммированным способом?

#javascript

#javascript

Вопрос:

У меня есть что-то похожее на этот код:

 addBlock = document.querySelectorAll(`[slide='B.slide1'] .TEAM`);
addBlock = addBlock[addBlock.length - 1];
function addNewSimilarBlockOfCode(x) {
  HTML = x.outerHTML;
  //insert new block of code after the previous one:
  x.insertAdjacentHTML('afterend', HTML);
  //redeclare x with the new added HTML code
  x = x; // here is the problem. this is an incorrect code!
  console.log('the new value of x is: '   x);
}
addNewSimilarBlockOfCode(addBlock);
  

как вы можете видеть, проблема в том, что новый x по-прежнему указывает на тот в аргументе, который был старым значением x.
Мне нужен динамический способ реализации этого, я не хочу его жестко кодировать, некоторые люди могут сказать «вместо того, чтобы писать x = x, напишите вместо:

 x = document.querySelectorAll(`${slide('B.slide1')} .TEAM`);
x = addBlock[x.length - 1];
  

Проблема в том, что я не хочу ее жестко кодировать.

Исходный код, который у меня есть, в настоящее время работает, но я хочу изменить его с жестко запрограммированной функции (функции addField и newField) на динамическую, чтобы я мог использовать их позже:

  const UI = (() => {
    //TOOLS:
    const $ = (x) => document.querySelector(x);
    const $$ = (x) => {
      let element = document.querySelectorAll(x);
      element = slice_array(element);
      return element;
    };
    const slice_array = (x) => {
      return Array.prototype.slice.call(x);
    };
    const slide = (path) => {
      path = path.split(".");
      return `[scope='${path[0]}'][slide='${path[1]}']`;
    };
    //-------------</TOOLS>
    const addField = (element, replace) => {
      let HTML;
      console.log("replace this: "   replace[0]   " with this: "   replace[1]);
      HTML = element.outerHTML;
      if (replace instanceof Array)
        HTML = element.outerHTML.replace(replace[0], replace[1]);
      element.insertAdjacentHTML("afterend", HTML);
    };
    return {
      addField: addField,
    };
  })();

  const controller = ((UI, model) => {
    //TOOLS:
    const $ = (x) => document.querySelector(x);
    const $$ = (x) => {
      let element = document.querySelectorAll(x);
      element = slice_array(element);
      return element;
    };
    const slice_array = (x) => {
      return Array.prototype.slice.call(x);
    };
    const slide = (path) => {
      path = path.split(".");
      return `[scope='${path[0]}'][slide='${path[1]}']`;
    };
    //-------------</TOOLS>

    let addBlock;
    addBlock = $$(`${slide("B.slide1")} .TEAM`);
    const eventList = () => {
      addBlock[addBlock.length - 1].addEventListener("input", newField);
    };
    let newField = () => {
      let replaceThis, withThis;
      addBlock = $$(`${slide("B.slide1")} .TEAM`);
      replaceThis = `<span id="TEAM_NUMBER_${counter}">${counter}</span>`;
      withThis = `<span id="TEAM_NUMBER_${counter   1}">${counter   1}</span>`;
      replace = [replaceThis, withThis];
      addField(addBlock, replace);
    };
    let counter = 1;
    const addField = (addBlock, replace) => {
      e = window.event;
      const target = e.target || e.srcElement;
      //remove previous event listener
      addBlock[addBlock.length - 1].removeEventListener("input", newField);
      console.log(addBlock);
      //insert new field
      UI.addField(target.parentNode, replace);
      counter = counter   1;
      //add new event listener
      addBlock = $$(`${slide("B.slide1")} .TEAM`);
      addBlock[addBlock.length - 1].addEventListener("input", newField);
    };
  

Комментарии:

1. Могу я узнать, почему я получаю отрицательный результат? что не так с вопросом? Я сказал, что у меня есть код, похожий на этот, но не этот точный код.

2. Я в замешательстве по поводу вашего вопроса. Подумайте о том, чтобы пересмотреть его. Сохраняйте его простым и нейтральным. Ограничимся основной проблемой. Если вы это сделаете, возможно, вы сами найдете решение. В любом случае… Набор x = x бесполезен. Возможно, вам следует вернуться x , чтобы получить новую. Но обратите внимание, что x это ссылка. Если вы хотите скопировать, используйте cloneNode . Если вы вернетесь x , она больше не будет жестко запрограммирована. (Я не голосовал против. Я также ненавижу голоса без причины. 🙂 ).

3. если вы напишете x=x, это будет означать, что x равно предыдущему блоку кода, а не недавно вставленному в dom

4. Я могу вставить исходный код, над которым я работаю здесь, но это будет длинный код

5. Но x (подумайте о переименовании на более конкретное имя) — это объект, не так ли? Вы используете x.outerHTML . Итак, я думаю, что это HTMLElement (или любой элемент ) Таким образом, установка x = x не изменяет значение. Это та же ссылка. Итак, вам следует использовать cloneNode . И, возможно, верните ее, если хотите.

Ответ №1:

Вы можете использовать cloneNode вместо получения outerHtml и appending это. И используйте x.insertAdjacentElement('afterend', clone); amp; x = clone; .

Попробуйте это ниже.

 var addBlock = document.querySelectorAll(`.slide1 .TEAM`);
addBlock = addBlock[addBlock.length - 1];

function addNewSimilarBlockOfCode(x) {
  // pass true as parameter to copy with children nodes
  var clone = x.cloneNode(true);

  //insert new block of code after the previous one:
  // use insertAdjacentElement instead of insertAdjacentHTML
  x.insertAdjacentElement('afterend', clone);

  //redeclare x with the new clone
  x = clone; // here is the problem. this is an incorrect code!
  console.log('the new value of x is: '   x);
}
addNewSimilarBlockOfCode(addBlock);  
 <div class='slide1'>
  <div class='TEAM'>
    hello world
  </div>
</div>  

Ответ №2:

Если вы хотите, чтобы что-то было динамическим, это обычно означает, что вы хотите, чтобы функция возвращала значение для вас.

Вы можете попробовать что-то вроде этого:

 // Gets a live collection of HTML elements
const blocks = document.getElementsByClassName("block");
printLength(blocks);

// Adds more elements and reports the new lengths
addNewBlock(blocks);
printLength(blocks);

addNewBlock(blocks);
printLength(blocks);


// Gets the block that is __currently__ the last one
function getLastBlock(blocks){
  const lastIndex = blocks.length - 1;
  const lastBlock = blocks[lastIndex];
  return lastBlock;
}

// Uses `getLastBlock` to determine where to add more content
function addNewBlock(blocks){
  let last = getLastBlock(blocks);
  last.insertAdjacentHTML("afterend", last.outerHTML);
  
  last = getLastBlock(blocks); // Now, `last` is the new block
  last.insertAdjacentHTML("beforeend", "I"); // To distinguish it from previous block
}

// Reports the current total number of blocks
function printLength(blocks){
  console.log(`blocks.length = ${blocks.length}`);
}  
 <div class="block">Block I</div>  

ПРИМЕЧАНИЕ: querySelectorAll Метод возвращает статический список, поэтому, если вы используете его, вам следует вызвать его внутри вашей getLastBlock функции, чтобы она могла получить самую последнюю версию.