2

In the example below, the "I'm Yellow" <li> turns yellow on hover, but when you enter something into the input and click "Generate Text," the dynamically appended <li> doesn't behave the same on hover.

I've tried selecting the appended li's through class and it still doesn't work. There seems to be something about appended elements that I'm not getting. To spare you some time reading the code I'm pretty sure you only need to look at the .hover function.

    <body>
        <a href="" class="buttn btn btn-secondary">
            <div class="" style="background-color: rgb(0, 0, 0); display: inline;"> Hello</div>
        </a>
        <a href="" class="buttn2">
            <div class="btn" style="background-color: aqua; display: inline;"> Bye</div>
        </a>
        <form class="form-disable">
            <br>
            <input type="text" id="message2">
            <br>
             <button id="myButton" type="submit" disabled>Generate Text</button> 
        </form>
    
        
    
        <script src="https://code.jquery.com/jquery-3.6.0.js"
            integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
        <script src="jQueryDrills.js"></script>
    </body>

<script>    
$(".form-disable").after("<ul class='the-list'><li><h2>Im Yellow</h2></li></ul>");
    
    $("#myButton").click(function(event) {
        let theH2 = document.createElement('h2');
        let theLI = document.createElement('li');
        let $alert = $('#message2').val();
        $(theH2).text($alert);
        $(theLI).append(theH2)
        $(".the-list").append(theLI);
        event.preventDefault();
      })
    
      $(".the-list > li").hover(function(){
        $(this).css("background-color", "yellow");
      },function(){
        $(this).css("background-color", "white");
      }
    
      )
    
    $("#message2").click(function(){
        $("#myButton").removeAttr("disabled");
        // event.preventDefault();
    })
</script>
Spectric
  • 30,714
  • 6
  • 20
  • 43
Wayne
  • 660
  • 6
  • 16
  • 3
    Out of curiosity, why not use pure css for the hover? – ray May 05 '21 at 02:31
  • I need to practice Jquery as much as possible – Wayne May 05 '21 at 03:01
  • @Wayne practice web development the right way ;) Using jQuery and its `.hover()` method to change colors on hover is not one. Well, unless you need to apply later some tricky JS logic on `.hover()` - which is not your case. – Roko C. Buljan May 05 '21 at 03:01
  • Ok, got it to thank you for the direction; I appreciate it. – Wayne May 05 '21 at 03:05
  • Instead of using `let theH2 = document.createElement('h2');` etc etc... use simply `$("

    ", {text: "Hello world", appendTo: $myLI})` - and it's good practice to prefix with `$` only those variables which are actually jQuery Objects - not arbitrary Strings. 99.9% of developers as soon as they see `$text` will know its most likely a jQuery wrapper for some DOM Element, perhaps with ID or class "text". Instead, without the prefix - `text` they will know immediately that's a simple String value - by just reading your code.

    – Roko C. Buljan May 05 '21 at 03:05

2 Answers2

1

When you first add the event listener, there was only 1 <li> element, so it only added the event listener to the first <li> element.

Instead, add the event listener to the element specifically after creating it like so:

<body>
  <a href="" class="buttn btn btn-secondary">
    <div class="" style="background-color: rgb(0, 0, 0); display: inline;"> Hello</div>
  </a>
  <a href="" class="buttn2">
    <div class="btn" style="background-color: aqua; display: inline;"> Bye</div>
  </a>
  <form class="form-disable">
    <br>
    <input type="text" id="message2">
    <br>
    <button id="myButton" type="submit" disabled>Generate Text</button>
  </form>



  <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
  <script src="jQueryDrills.js"></script>
</body>

<script>
  $(".form-disable").after("<ul class='the-list'><li><h2>Im Yellow</h2></li></ul>");

  $("#myButton").click(function(event) {
    let theH2 = document.createElement('h2');
    let theLI = document.createElement('li');
    let $alert = $('#message2').val();
    $(theH2).text($alert);
    $(theLI).append(theH2)
    $(".the-list").append(theLI);
    $(theLI).hover(function() {
        $(this).css("background-color", "yellow");
      }, function() {
        $(this).css("background-color", "white");
      }

    )
    event.preventDefault();
  })

  $(".the-list > li").hover(function() {
      $(this).css("background-color", "yellow");
    }, function() {
      $(this).css("background-color", "white");
    }

  )

  $("#message2").click(function() {
    $("#myButton").removeAttr("disabled");
    // event.preventDefault();
  })
</script>

With CSS it gets so much easier:

li:hover{
  background-color:yellow;
}
<body>
  <a href="" class="buttn btn btn-secondary">
    <div class="" style="background-color: rgb(0, 0, 0); display: inline;"> Hello</div>
  </a>
  <a href="" class="buttn2">
    <div class="btn" style="background-color: aqua; display: inline;"> Bye</div>
  </a>
  <form class="form-disable">
    <br>
    <input type="text" id="message2">
    <br>
    <button id="myButton" type="submit" disabled>Generate Text</button>
  </form>



  <script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
  <script src="jQueryDrills.js"></script>
</body>

<script>
  $(".form-disable").after("<ul class='the-list'><li><h2>Im Yellow</h2></li></ul>");

  $("#myButton").click(function(event) {
    let theH2 = document.createElement('h2');
    let theLI = document.createElement('li');
    let $alert = $('#message2').val();
    $(theH2).text($alert);
    $(theLI).append(theH2)
    $(".the-list").append(theLI);
    event.preventDefault();
  })


  $("#message2").click(function() {
    $("#myButton").removeAttr("disabled");
    // event.preventDefault();
  })
</script>
Spectric
  • 30,714
  • 6
  • 20
  • 43
  • 2
    There's not a single valid argument for using JS to change **styles on hover**. **CSS** is used for styling and it already provides the `:hover` handler. – Roko C. Buljan May 05 '21 at 02:52
  • 1
    It's absolutely bad practice to assign event handlers repeatedly (without control) inside another event handler function. Also `const` should be always prioritized over the use of `let`. Don't just use `let` as a *lazy* replacer for `var`. – Roko C. Buljan May 05 '21 at 02:54
  • I still strongly feel this should be handled with css, but if you must use jQuery, consider using [delegated handlers](https://api.jquery.com/on/) so you don't have to keep adding and removing the functions. – ray May 05 '21 at 03:20
  • @rayhatfield you can't use delegated events for `hover` as it's not actually an event - you *can* use it with `mouseenter`/`mouseleave` which would be a better option that duplicating code as suggested here. – freedomn-m May 05 '21 at 07:49
  • [Don't repeat yourself](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) – freedomn-m May 05 '21 at 07:52
  • @freedomn-m Thanks. I haven't used jQuery in a _very_ long time and because I was preoccupied with whether I should even comment it didn't occur to me that hover isn't an event. Derp. – ray May 05 '21 at 14:19
-1

The $(".the-list > li") elector looks for elements that are already on the page. If you are looking to target dynamically created elements then you you need to break it up by first targeting an element that you know is on the page and then target the dynamically generated element and attach the event type using the JQuery on method.

$(".the-list").on("click", "li", function(){

// do whatever here.

})
andre mcgruder
  • 1,120
  • 1
  • 9
  • 12
  • This was already answered a [multiple dozens times](https://stackoverflow.com/questions/6658752/click-event-doesnt-work-on-dynamically-generated-elements) ("Click event on dynamically generated elements"). If you think that it's a duplicate question (for that matter) it should me marked as such. – Roko C. Buljan May 05 '21 at 02:58
  • Also, a "click on `LI`" has nothing to do with the question. – Roko C. Buljan May 05 '21 at 03:01
  • How do I mark it as a duplicate question? – Wayne May 05 '21 at 03:04
  • You simply leave a comment under the Question with a link. Than admins or users with higher reputation will close as such if they assume your comment holds true. - Which BTW is not a duplicate - since your answer had a wrong presumption. – Roko C. Buljan May 05 '21 at 03:11
  • Also note that you can't use `.on` with `hover` as it's not a "real" event. – freedomn-m May 05 '21 at 07:50
  • @Wayne You can't mark a duplicate *answer* - only a duplicate *question*. – freedomn-m May 05 '21 at 07:51