Как да добавите множество дъщерни елементи в DOM и да ги покажете, като използвате ванилен javascript?

Опитвам се да вмъкна някои SVG икони в dom, но SVG (родителски възел) винаги се заменя от употреба (дъщерен възел). Някой да ми помогне да разбера?

Изображение на изходния код тук

Codepen тук

const icons = [
    "html5" ,
    "css3" ,
    "javascript" ,
    "bootstrap" ,
    "sass" ,
    "node" ,
    "mongodb" ,
    "d3" ,
    "react" ,
    "webpack" ,
    "wordpress"
];

const tech_icons = document.querySelector( "#techs__icons" );

icons.forEach( icon=> {

    const svg = document.createElement( "svg" );
    const use = document.createElement( "use" );

        svg.setAttribute( "class" , `techs__icon icon icon-${icon}` );
    use.setAttribute( "href" , `./src/images/sprites.svg#icon-${icon}` );

    tech_icons.appendChild( use ).appendChild( use );

} );

Мога успешно да ги регистрирам в конзолата, но изглежда не се показват в документа.

Вече го добавих към родителския възел (techs_icons), но не мога да го разбера на този етап!

АКТУАЛИЗИРАН КОД

icons.forEach( icon=> {

    const tech_icons = document.querySelector( "#techs__icons" );

    const svg = document.createElement( "svg" );
    svg.setAttribute( "class" , `techs__icon icon icon-${icon}` );
    const use = document.createElement( "use" );
    use.setAttribute( "href" , `./src/images/sprites.svg#icon-${icon}` );

    svg.appendChild( use );

    tech_icons.appendChild( svg );

} );

Тази моментна снимка изглежда работи тук

Все още няма да се показва в DOM. Всъщност те се добавят, защото когато ги насоча към инспектора, те са там, но не се виждат.

ВТОРА АКТУАЛИЗАЦИЯ НА КОДА

Изглежда, че трябва да създадете някакъв вид "фалшив" елемент в моя svg>use>"fake element", като shadowRoot, който всъщност не разбирам защо браузърът създава такъв елемент, когато импортира SVG файлове!

Разбрах го, когато проверявах елемента и видях, че браузърът всъщност автоматично създава тази сянка.

SVG

<symbol id="icon-html5">
   <path d="M2 0h28l-2.547 28.751-11.484 3.249-11.419-3.251-2.551-28.749zM11.375 13l-0.309-3.624 13.412 0.004 0.307-3.496-17.568-0.004 0.931 10.68h12.168l-0.435 4.568-3.88 1.072-3.94-1.080-0.251-2.813h-3.479l0.44 5.561 7.229 1.933 7.172-1.924 0.992-10.876h-12.789z"/>
 </symbol> 

Проверен код, показващ автоматично създадения елемент на сянка

const tech_icons = document.querySelector( "#techs__icons" );
const fragment = document.createDocumentFragment();

icons.forEach( icon => {

    const svg = document.createElement( "svg" );
    const use = document.createElement( "use" );
    let shadow = use.attachShadow( { mode : open } );

    svg.setAttribute( "class" , `techs__icon icon icon-${icon}` );
    use.setAttribute( "href" , `./src/images/sprites.svg#icon-${icon}` );
    shadow.appendChild( "I am a: child element inside shadowroot (svg>use>shadowroot>ME)" );

   svg.appendChild( use );

   fragment.appendChild( svg );

});

tech_icons.appendChild( fragment );

Така че в този момент да обобщим:

  1. Добавих резултата за цикъла forEach() към фрагмент на документ и след като този цикъл приключи, добавих този фрагмент като дете към истинския DOM елемент (.techs_info)
  2. Създаде сянка и също я добави като дете към елемента use

Проблемът все още съществува, докато при добавяне на сянката към елемента use нито DOM, нито конзолата всъщност не показват нищо!


person Evan    schedule 17.04.2019    source източник
comment
Защо добавяте два пъти?   -  person El.    schedule 17.04.2019
comment
Може би искате да използвате ` appendChild(svg)`?   -  person Jonas Wilms    schedule 17.04.2019
comment
Не можете да манипулирате DOM на iframe по този начин. Вашият код се изпълнява в iframe всеки път, когато използвате Codepen.   -  person FirstIndex    schedule 17.04.2019
comment
Проблемът не се случва само в кодовата писалка.   -  person Evan    schedule 17.04.2019
comment
@Ел. просто добавям детето за използване към родителя на svg и след това добавям детето за използване, което е родителят на детето за използване, към родителя techs_icons. така че малко прилича на това techs_icons › svg › use   -  person Evan    schedule 17.04.2019
comment
Не, никога не добавяте svg никъде? пример за минимално възпроизвеждане!   -  person Jonas Wilms    schedule 17.04.2019
comment
1. премахване на остарял код. 2. използвайте createElementNS()   -  person Supersharp    schedule 19.04.2019
comment
@Supersharp какво имаш предвид остарял код приятелю? :Д   -  person Evan    schedule 19.04.2019
comment
@Evan, първата част е грешна и ти я коригира чрез актуализация =› премахнете я   -  person Supersharp    schedule 19.04.2019


Отговори (3)


SVG елементите не са стандартен HTML, така че ще трябва да посочите пространството от имена на SVG в метода createElementNS():

const svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' )
const use = document.createElementNS( 'http://www.w3.org/2000/svg', 'use' )

Също така в изходния файл на SVG трябва да посочите пространството от имена в атрибута xmlns:

<svg xmlns="http://www.w3.org/2000/svg">
<symbol id="icon-html5">
   <path d="M2 0h28l-2.547 28.751-11.484 3.249-11.419-3.251-2.551-28.749zM11.375 13l-0.309-3.624 13.412 0.004 0.307-3.496-17.568-0.004 0.931 10.68h12.168l-0.435 4.568-3.88 1.072-3.94-1.080-0.251-2.813h-3.479l0.44 5.561 7.229 1.933 7.172-1.924 0.992-10.876h-12.789z"/>
 </symbol> 
</svg>
person Supersharp    schedule 19.04.2019

Поиграх си с вашия Codepen, използвайки този коригиран код:


const icons = [
    "html5" ,
    "css3" ,
    "javascript" ,
    "bootstrap" ,
    "sass" ,
    "node" ,
    "mongodb" ,
    "d3" ,
    "react" ,
    "webpack" ,
    "wordpress"
];

icons.forEach( icon=> {
    const tech_icons = document.getElementById( "techs__icons" );

    const svg = document .createElementNS("http://www.w3.org/2000/svg", "svg");
    svg.setAttribute( "class" , `techs__icon icon icon-${icon}` );

    const use = document .createElementNS("http://www.w3.org/2000/svg", "use");
    use.setAttribute( "xlink:href" , `./src/images/sprites.svg#icon-${icon}` );

    svg.appendChild( use );

    tech_icons.appendChild( svg );

  console.log(tech_icons);
} );

При проверка в конзолата SVG елементите се създават и заемат място в DIV в документа, но изглеждат празни или невидими. Така че обвинявам файла sprites.svg.

person igreka    schedule 17.04.2019
comment
Проблемът, приятелю, е, че вече тествах спрайтовете и работят добре! Искам да кажа, че преди това съм кодирал всички икони и сега се опитвам да ги добавя динамично към DOM. - person Evan; 17.04.2019
comment
Къде мога да получа достъп до .svg файла във вашия Codepen? Не успях да го намеря. Може би бих могъл да проуча малко повече с него в ръцете си. - person igreka; 17.04.2019
comment
Хей, @igreka, току-що актуализирах публикацията. Той включва и изходния код на svg. - person Evan; 18.04.2019

person    schedule
comment
също използваш tech_icons.appendChild( използвай).appendChild( използвай);// използвай два пъти, мисля, че трябва да използваш svg и да използваш - person vishnu prasath; 17.04.2019
comment
Това има синтактични грешки и не отговаря на въпроса? - person Jonas Wilms; 17.04.2019
comment
Може би искате да използвате ` appendChild(svg)`? това имах предвид с коментара, както ти каза по-рано @jonas wilms - person vishnu prasath; 17.04.2019
comment
Да, това е правописна грешка. Въпросът трябва да бъде затворен като такъв. Няма дългосрочна стойност от този въпрос. - person Jonas Wilms; 17.04.2019