Home > Net >  how to create a <a></a> inside <li></li> all of the are inside <ul><
how to create a <a></a> inside <li></li> all of the are inside <ul><

Time:12-12

I have this ul which is made by HTML and I want to create elements inside with JS

HTML code:

<ul id="navbar__list">
    
</ul>

and JS code:

var ul = document.getElementById("navbar__list");
var link1 = document.createElement("a");
var Li1 = document.createElement("li").appendChild(document.createElement("a"));
var sec1 = ul.appendChild(Li1)
link1.innerHTML = "Section 1"
link1.href ="#section1"

all I got was without text and as a beginner, I do not know what is wrong

CodePudding user response:

Use this:

var ul = document.getElementById("navbar__list");

var li = document.createElement("li");
ul.appendChild(li);

var link = document.createElement("a");
link.setAttribute('href', '#section1');
link.innerHTML = "Section 1";

li.appendChild(link);

CodePudding user response:

You need to pass link1 into your appendChild call. Right now your code is calling createElement("a") twice and passing the second uninitialized <a> into appendChild, which is not what you want.

You'll want this:

  • Use const for locals that shouldn't be reassigned.
  • Be defensive: because JavaScript doesn't offer compile-time type-safety or other guarantees it's a good idea to always check your assumptions and to throw new Error when those assumptions are invalidated. This greatly aids debugging in JavaScript ("fail fast").
  • When building-up DOM element trees in JS, I find it helpful to put each element in its own anonymous-scope ({ }) which mirrors the DOM's structure.
    • This also helps prevent bugs where elements aren't parented correctly.
const ul = document.getElementById("navbar__list");
if( !ul ) throw new Error( "Couldn't find navbar__list" );

{
    const li = document.createElement("li");
    ul.appendChild( li );

    {
        const aLink = document.createElement("a");
        aLink.textContent = "Section 1";
        aLink.href        = "#section1";

        li.appendChild( aLink );
    }
}

Somewhat surprisingly, the DOM API is kinda verbose: there's no succinct way to create elements with their attributes and inner-content set, instead we need explicit calls to createElement and appendChild. Some alternatives have been proposed that use compile-time techniques, like JSX, as a more lightweight alternative you could use a helper-function like this:

/**
    @param {string} tagName
    @param {[string, string][]} attributes - Array of 2-tuples
    @param {HTMLElement | HTMLElement[] | string} content - Either: one-or-many HTML elements, or string textContent
*/
function create( tagName, attributes, content ) {
    
    const e = document.createElement( tagName );
    
    for( let i = 0; i < attributes.length; i   ) {
        const pair = attributes[i];
        
        e.setAttribute( pair[0], pair[1] );
    }

    if( typeof content === 'string' ) {
        e.textContent = content;
    }
    else if( Array.isArray( content ) ) {
        for( const child of content ) {
            e.appendChild( child );
        }
    }
    else if( typeof content === 'object' && content !== null ) {
        e.appendChild( content );
    }

    return e;
}

Used like so:

const ul = document.getElementById("navbar__list");
if( !ul ) throw new Error( "Couldn't find navbar__list" );

{
    ul.appendChild(
        create( "li", [], create( "a", [ [ "href", "#section1" ] ], "Section 1" ) )
    );
}
  • Related