Home > front end >  Creating new jQuery object.create(newobj) 2x overwrites initial object
Creating new jQuery object.create(newobj) 2x overwrites initial object

Time:02-10

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-02and 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 ></li>' ),
                newAnchor  : $( '<a  href="#" title="#"></a>' ),
                newIconItem: $( '<span  role="img" aria-label="Category"></span>' ),
                newTextItem: $( '<span ></span>' ),
                newNavRight: $( '<span  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"

CodePudding user response:

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 >...</div>
<div >
  <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

  •  Tags:  
  • Related