I'm trying to add new <li>
elements to an existing mobile menu, and this script works, except that the second Object.create(x) overwrites the already-appended first object. I'm very confused why that is. I'm sure I'm missing something stupid.
The script is getting the text and url from two different <a>
tags, i.e., #c_top-nav-link-01
and #c_top-nav-link-02
and trying to make new <li>
tags with that information.
The first if
statement generates a new <li>
object that then appends to the <ul>
I'm targeting, but when the second if
statement runs, rather than appending a second li
element with new properties, it simply replaces the first, already-appended <li>
element.
Thoughts? Anything obvious I'm missing?
;(function ( $ ) {
$( document ).ready( function () {
$( '.lia-slide-out-nav-menu' ).click( function ( e ) {
console.log( 'clicked' );
let mobileNav = $( "ul" ).first();
const newLI = {
newNavItem : $( '<li class="some-icon"></li>' ),
newAnchor : $( '<a class="some-link" href="#" title="#"></a>' ),
newIconItem: $( '<span class="circle-icon-left" role="img" aria-label="Category"></span>' ),
newTextItem: $( '<span class="item-text"></span>' ),
newNavRight: $( '<span class="chevron-icon-right" role="img" aria-label="click to open this category"></span>' )
}
if ( $( "#c_top-nav-link-01" ) ) {
let firstLI = Object.create( newLI );
let link01 = $( "#c_top-nav-link-01" );
link01.text = link01.text();
link01.url = link01.prop( "href" );
console.log( 'link01.text', link01.text );
firstLI.newAnchor.prop( "href", link01.url );
firstLI.newTextItem.text( link01.text );
firstLI.newAnchor.append( [firstLI.newIconItem, firstLI.newTextItem, firstLI.newNavRight] );
firstLI.newNavItem.append( firstLI.newAnchor );
mobileNav.append( firstLI.newNavItem );
}
if ( $( "#c_top-nav-link-02" ) ) {
let secondLI = Object.create( newLI );
let link02 = $( "#c_top-nav-link-02" );
link02.text = link02.text();
link02.url = link02.prop( "href" );
console.log( 'link02.text', link02.text );
secondLI.newAnchor.prop( "href", link02.url );
secondLI.newTextItem.text( link02.text );
secondLI.newAnchor.append( [secondLI.newIconItem, secondLI.newTextItem, secondLI.newNavRight] );
secondLI.newNavItem.append( secondLI.newAnchor );
mobileNav.append( secondLI.newNavItem );
}
} );
} );
})(jQuery );
The target is a dynamically generated unordered list that I do not have the ability to tap into and add these list items to the dynamic generation, i.e.,
<ul>
<li>item one</li>
<li>item two</li>
<li>item three</li>
</ul>
I just want to add the new <li>
items to the list after "item three"
Consider the following.
$(function() {
function newLi(props, target) {
var item = $("<li>", {
class: props.class
});
if (target != undefined) {
item.appendTo(target);
}
$("<a>", props.link).appendTo(item);
$("<span>", props.icon).appendTo($("a", item));
$("<span>", props.text).html(props.text.content).appendTo($("a", item));
return item;
}
$('.lia-slide-out-nav-menu').click(function(e) {
console.log('clicked');
var mobileNav = $("ul").first();
if ($("#c_top-nav-link-01").length) {
newLi({
class: "some-icon",
link: {
class: "some-link",
href: $("#c_top-nav-link-01").attr("href"),
title: "#"
},
icon: {
class: "circle-icon-left",
role: "img",
"aria-label": "Category"
},
text: {
class: "item-text",
content: $("#c_top-nav-link-01").text()
}
}, mobileNav);
}
if ($("#c_top-nav-link-02").length) {
newLi({
class: "some-icon",
link: {
class: "some-link",
href: $("#c_top-nav-link-02").attr("href"),
title: "#"
},
icon: {
class: "circle-icon-left",
role: "img",
"aria-label": "Category"
},
text: {
class: "item-text",
content: $("#c_top-nav-link-02").text()
}
}, mobileNav);
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="lia-slide-out-nav-menu">...</div>
<div class="slide-out-menu-links">
<ul>
<li>item one</li>
<li>item two</li>
<li>item three</li>
</ul>
</div>
<a id="c_top-nav-link-01" href="page1.htm">Link 1</a>
<a id="c_top-nav-link-02" href="page2.htm">Link 2</a>
You can also use .clone()
to clone the a
element like so:
var newLink = $("#c_top-nav-link-01").clone();
You just have to remember to adjust the ID attribute before appending it.
This example performs a similar function, yet it builds out more structure. You could do this with a <template>
too if you wanted. it would give you the HTML Structure and then you could copy it as needed and populate it.
Your if
statements would always be true
the way you were using them. If you want to check if an element with that selector exists, you need to call the length
attribute. This will return 0
if no elements exist or 1
or higher. 0
will equate to false
and 1
or more will equate to true