如何在javascript中具有特定文本的循环中的所有元素中appendChild?

问题描述 投票:0回答:1

我正在使用数组值创建元素的动态树,该数组值按 Parent 的属性值维护级别,该属性值与元素 Button Text 匹配 我后来用作手风琴。

这里出现的问题是,它不会为具有该特定文本

的所有元素创建元素

我什至使用了 For Loop,然后尝试使用 nextElementSibling 插入,如下面的函数所示

function appendSymptomToForm(symptom, symptomElements, container) {
    if (symptom.parent === 'none') {
        symptomForm.appendChild(container);
    } else {
        
var aTags = document.getElementsByTagName("button");
var searchText = symptom.parent;
var found;

for (var i = 0; i < aTags.length; i++) {    
  if (aTags[i].textContent == searchText) {  

    found = aTags[i].nextElementSibling;    
            found.insertBefore(container, found.nextElementSibling);
  }
}
    }
    console.log(`Symptom ${symptom.text} appended to the form.`);
}

下面正是附加子元素的代码行。

found.insertBefore(container, found.nextElementSibling);

下面我创建了 fiddle,它可以让您充分理解,我在名为 window.symptomData 的数组中有 3 个级别。 每个元素根据其父属性

添加

例如注意第二级B

{ 深度:3,文本:'第三级 B',父级:'第二级 B',工具提示: “描述简单的矿石周期”}

在这里你会看到有多个第二级B的按钮,但它只在最后一个元素下添加了第三级

请参考fiddle中的函数appendSymptomToForm,其中 它确实appendChild

工作小提琴

window.symptomData = [
    { depth: 0, text: 'De aproximativ', parent: 'none', tooltip: 'Perioadă nespecificată de timp, folosită pentru estimări' },
    { depth: 1, text: '1', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },
    { depth: 1, text: '2', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },
    { depth: 1, text: '3', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },
    { depth: 1, text: '4', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },
    
    { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în ore' },
    { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în zile' },
    { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată de timp' },    
    { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în luni' },
    { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în ani' },

    { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în ore' },
    { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în zile' },
    { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în săptămâni' },
    { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în luni' },
    { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în ani' },

    { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în ore' },
    { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în zile' },
    { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în săptămâni' },
    { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în luni' },
    { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în ani' },
    
    { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în ore' },
    { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în zile' },
    { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în săptămâni' },
    { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în luni' },
    { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în ani' },
    
    { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de ore' },
    { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de zile' },
    { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de săptămâni' },
    { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de luni' },
    { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de ani' },
    
    { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de ore' },
    { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de zile' },
    { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de săptămâni' },
    { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de luni' },
    { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de ani' },
];

// script.js
document.addEventListener('DOMContentLoaded', function() {
    console.log('DOMContentLoaded event triggered, initializing symptoms setup...');
    const symptomData = window.symptomData; // Now pulling from the global variable set by sd.js

    const symptomForm = document.getElementById('symptomForm');
    if (!symptomForm) {
        console.error('Failed to find symptom form on the page.');
        return;
    }

    let symptomElements = {};
    const tooltipDiv = document.createElement('div');
    setupTooltipDiv(tooltipDiv);
    document.body.appendChild(tooltipDiv);

    symptomData.forEach(symptom => {
        const container = document.createElement('div');
        setupSymptomContainer(symptom, container);

        const button = document.createElement('button');
        setupSymptomButton(symptom, button, container);

        const childrenContainer = document.createElement('div');
        setupChildrenContainer(childrenContainer, container);

        symptomElements[symptom.text] = { button, container, childrenContainer };

        setupButtonEvents(button, childrenContainer);
        appendSymptomToForm(symptom, symptomElements, container);
    });

    setupSendButton();
});

function setupTooltipDiv(tooltipDiv) {
    tooltipDiv.id = 'tooltipDiv';
    tooltipDiv.style = "position: fixed; bottom: 20px; left: 20px; padding: 10px; " +
                       "background-color: rgba(0, 0, 0, 0.75); color: white; border-radius: 5px; display: none;";
    console.log('Tooltip div setup completed.');
}

function setupSymptomContainer(symptom, container) {
    container.className = `symptom-instance depth-${symptom.depth}`;
    console.log(`Setup container for symptom: ${symptom.text}`);
}

function setupSymptomButton(symptom, button, container) {
    button.textContent = symptom.text;
    button.className = 'symptom-button';
    button.title = symptom.tooltip;
    container.appendChild(button);
    console.log(`Button created for symptom: ${symptom.text}`);
}

function setupChildrenContainer(childrenContainer, container) {
    childrenContainer.className = 'sub-symptoms hidden';
    container.appendChild(childrenContainer);
    console.log('Children container setup completed.');
}

function setupButtonEvents(button, childrenContainer) {
    button.onclick = () => {
        childrenContainer.classList.toggle('hidden');
        button.classList.toggle('pressed');
        scrollToButton(button);
        console.log(`Visibility toggled for: ${button.textContent}, New state: ${childrenContainer.className}`);
    };
    button.addEventListener('touchstart', () => showTooltip(button, button.title), { passive: true });
    button.addEventListener('touchend', hideTooltip, { passive: true });
}

function appendSymptomToForm(symptom, symptomElements, container) {
       if (symptom.parent === 'none') {
        symptomForm.appendChild(container);
    } else {
        
var aTags = document.getElementsByTagName("button");
var searchText = symptom.parent;
var found;

for (var i = 0; i < aTags.length; i++) {    
  if (aTags[i].textContent == searchText) {  

    found = aTags[i].nextElementSibling;    
            found.insertBefore(container, found.nextElementSibling);
  }
}
    }
    console.log(`Symptom ${symptom.text} appended to the form.`);
}

function scrollToButton(button) {
    const buttonRect = button.getBoundingClientRect();
    const visibleAreaStart = window.innerHeight / 4;
    const scrollYOffset = buttonRect.top - visibleAreaStart + window.scrollY;
    window.scrollTo({
        top: scrollYOffset,
        behavior: 'smooth'
    });
    console.log(`Scrolled to button: ${button.textContent}`);
}

function setupSendButton() {
    const sendButton = document.createElement('button');
    sendButton.textContent = 'Copiaza Selectate';
    sendButton.addEventListener('click', () => {
        const selectedSymptoms = Array.from(document.querySelectorAll('.symptom-button.pressed'))
            .map(btn => btn.textContent.trim())
            .join(', ');
        navigator.clipboard.writeText(selectedSymptoms)
            .then(() => {
                console.log('Selected symptoms copied to clipboard.');
                alert('Selected symptoms copied to clipboard.');
            })
            .catch(err => {
                console.error('Error copying to clipboard:', err);
                alert('Failed to copy symptoms. See console for errors.');
            });
    });
    document.body.appendChild(sendButton);
    console.log('Send button setup completed.');
}

function showTooltip(button, text) {
    const tooltipDiv = document.getElementById('tooltipDiv');
    tooltipDiv.textContent = text;
    tooltipDiv.style.display = 'block';
    console.log(`Tooltip shown for ${button.textContent}: ${text}`);
}

function hideTooltip() {
    const tooltipDiv = document.getElementById('tooltipDiv');
    tooltipDiv.style.display = 'none';
    console.log('Tooltip hidden.');
}
    <div id="symptomForm">
    </div>

javascript dom
1个回答
0
投票

问题出在插入

appendSymptomToForm
(子级)的
container
函数中。

这段代码只是将容器从一个地方转移到另一个地方(第一个父容器,第二个容器,...第五个容器)。这是一个孩子正在被移动。

            for (var i = 0; i < aTags.length; i++) {
                if (aTags[i].textContent == searchText) {

                    found = aTags[i].nextElementSibling;
                    found.insertBefore(container, found.nextElementSibling);
                }
            }

您需要做的是在插入之前拥有

container
(子级)的副本/克隆。比如:

var clonedContainer = container.cloneNode(true);

这就是必须插入的子项:

found.insertBefore(clonedContainer, found.nextElementSibling);

你的函数应该是这样的:

        function appendSymptomToForm(symptom, symptomElements, container) {
        if (symptom.parent === 'none') {
            symptomForm.appendChild(container);
        } else {

            var aTags = document.getElementsByTagName("button");
            var searchText = symptom.parent;
            var found;

            for (var i = 0; i < aTags.length; i++) {
                if (aTags[i].textContent == searchText) {
                    var clonedContainer = container.cloneNode(true);
                    found = aTags[i].nextElementSibling;
                    found.insertBefore(clonedContainer, found.nextElementSibling);
                }
            }
        }
        console.log(`Symptom ${symptom.text} appended to the form.`);
    }

这是工作代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="symptomForm">
    </div>
    <script>
        window.symptomData = [
            { depth: 0, text: 'De aproximativ', parent: 'none', tooltip: 'Perioadă nespecificată de timp, folosită pentru estimări' },
            { depth: 1, text: '1', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },
            { depth: 1, text: '2', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },
            { depth: 1, text: '3', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },
            { depth: 1, text: '4', parent: 'De aproximativ', tooltip: 'Al doilea nivel de timp estimat, similar cu primul' },

            { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în ore' },
            { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în zile' },
            { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată de timp' },
            { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în luni' },
            { depth: 2, text: 'second level A', parent: '1', tooltip: 'Durată exprimată în ani' },

            { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în ore' },
            { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în zile' },
            { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în săptămâni' },
            { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în luni' },
            { depth: 2, text: 'second level B', parent: '2', tooltip: 'Durată exprimată în ani' },

            { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în ore' },
            { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în zile' },
            { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în săptămâni' },
            { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în luni' },
            { depth: 2, text: 'second level B', parent: '3', tooltip: 'Durată exprimată în ani' },

            { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în ore' },
            { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în zile' },
            { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în săptămâni' },
            { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în luni' },
            { depth: 2, text: 'second level B', parent: '4', tooltip: 'Durată exprimată în ani' },

            { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de ore' },
            { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de zile' },
            { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de săptămâni' },
            { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de luni' },
            { depth: 3, text: 'Third level A', parent: 'second level A', tooltip: 'Descrie simptomele după o perioadă de ani' },

            { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de ore' },
            { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de zile' },
            { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de săptămâni' },
            { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de luni' },
            { depth: 3, text: 'Third level B', parent: 'second level B', tooltip: 'Descrie simptomele după o perioadă de ani' },
        ];

        // script.js
        document.addEventListener('DOMContentLoaded', function () {
            console.log('DOMContentLoaded event triggered, initializing symptoms setup...');
            const symptomData = window.symptomData; // Now pulling from the global variable set by sd.js

            const symptomForm = document.getElementById('symptomForm');
            if (!symptomForm) {
                console.error('Failed to find symptom form on the page.');
                return;
            }

            let symptomElements = {};
            const tooltipDiv = document.createElement('div');
            setupTooltipDiv(tooltipDiv);
            document.body.appendChild(tooltipDiv);

            symptomData.forEach(symptom => {
                const container = document.createElement('div');
                setupSymptomContainer(symptom, container);

                const button = document.createElement('button');
                setupSymptomButton(symptom, button, container);

                const childrenContainer = document.createElement('div');
                setupChildrenContainer(childrenContainer, container);

                symptomElements[symptom.text] = { button, container, childrenContainer };

                setupButtonEvents(button, childrenContainer);
                appendSymptomToForm(symptom, symptomElements, container);
            });

            setupSendButton();
        });

        function setupTooltipDiv(tooltipDiv) {
            tooltipDiv.id = 'tooltipDiv';
            tooltipDiv.style = "position: fixed; bottom: 20px; left: 20px; padding: 10px; " +
                "background-color: rgba(0, 0, 0, 0.75); color: white; border-radius: 5px; display: none;";
            console.log('Tooltip div setup completed.');
        }

        function setupSymptomContainer(symptom, container) {
            container.className = `symptom-instance depth-${symptom.depth}`;
            console.log(`Setup container for symptom: ${symptom.text}`);
        }

        function setupSymptomButton(symptom, button, container) {
            button.textContent = symptom.text;
            button.className = 'symptom-button';
            button.title = symptom.tooltip;
            container.appendChild(button);
            console.log(`Button created for symptom: ${symptom.text}`);
        }

        function setupChildrenContainer(childrenContainer, container) {
            childrenContainer.className = 'sub-symptoms hidden';
            container.appendChild(childrenContainer);
            console.log('Children container setup completed.');
        }

        function setupButtonEvents(button, childrenContainer) {
            button.onclick = () => {
                childrenContainer.classList.toggle('hidden');
                button.classList.toggle('pressed');
                scrollToButton(button);
                console.log(`Visibility toggled for: ${button.textContent}, New state: ${childrenContainer.className}`);
            };
            button.addEventListener('touchstart', () => showTooltip(button, button.title), { passive: true });
            button.addEventListener('touchend', hideTooltip, { passive: true });
        }

        function appendSymptomToForm(symptom, symptomElements, container) {
            if (symptom.parent === 'none') {
                symptomForm.appendChild(container);
            } else {

                var aTags = document.getElementsByTagName("button");
                var searchText = symptom.parent;
                var found;

                for (var i = 0; i < aTags.length; i++) {
                    if (aTags[i].textContent == searchText) {
                        var clonedContainer = container.cloneNode(true);
                        found = aTags[i].nextElementSibling;
                        found.insertBefore(clonedContainer, found.nextElementSibling);
                    }
                }
            }
            console.log(`Symptom ${symptom.text} appended to the form.`);
        }

        function scrollToButton(button) {
            const buttonRect = button.getBoundingClientRect();
            const visibleAreaStart = window.innerHeight / 4;
            const scrollYOffset = buttonRect.top - visibleAreaStart + window.scrollY;
            window.scrollTo({
                top: scrollYOffset,
                behavior: 'smooth'
            });
            console.log(`Scrolled to button: ${button.textContent}`);
        }

        function setupSendButton() {
            const sendButton = document.createElement('button');
            sendButton.textContent = 'Copiaza Selectate';
            sendButton.addEventListener('click', () => {
                const selectedSymptoms = Array.from(document.querySelectorAll('.symptom-button.pressed'))
                    .map(btn => btn.textContent.trim())
                    .join(', ');
                navigator.clipboard.writeText(selectedSymptoms)
                    .then(() => {
                        console.log('Selected symptoms copied to clipboard.');
                        alert('Selected symptoms copied to clipboard.');
                    })
                    .catch(err => {
                        console.error('Error copying to clipboard:', err);
                        alert('Failed to copy symptoms. See console for errors.');
                    });
            });
            document.body.appendChild(sendButton);
            console.log('Send button setup completed.');
        }

        function showTooltip(button, text) {
            const tooltipDiv = document.getElementById('tooltipDiv');
            tooltipDiv.textContent = text;
            tooltipDiv.style.display = 'block';
            console.log(`Tooltip shown for ${button.textContent}: ${text}`);
        }

        function hideTooltip() {
            const tooltipDiv = document.getElementById('tooltipDiv');
            tooltipDiv.style.display = 'none';
            console.log('Tooltip hidden.');
        }


    </script>
</body>

</html>

© www.soinside.com 2019 - 2024. All rights reserved.