#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
функции, чтобы она могла получить самую последнюю версию.