Script conflict in my html file

Asked

Viewed 89 times

0

I am creating a web application where the main page is a Timeline, and this Timeline should update your content automatically. I’m using Jquery’s setTimeOut function to update Timeline every x seconds.

But I also have another Javascript code that serves to show hidden elements of such item by clicking on the div.

Both codes work perfectly on their own, except when I try to use both on the page. The error is as follows After Timeline is updated by setTimeOut, the second code (from clicking on the div to show/hide elements) no longer works. I tried to solve in several ways and could not and also not found by solutions. Someone knows what can be? I also accept tips on how to improve my Timeline update, for example update only when there are new entries of items, instead of every x seconds.

setTimeout("my_function();", 9000);
    function my_function() {
      $('#timeline').load(location.href + ' #timeline')
    }
    
$(document).ready(function () {
      var itemsDivs = document.querySelectorAll('.timeline-item');
      itemsDivs.forEach(function (itemsDiv) {

        itemsDiv.addEventListener('click', function () {
          var itemId = this.getAttribute('item-id')
          var display = document.getElementById('comment-form-' + itemId).style.display
          if (display == 'none')
            document.getElementById('comment-form-' + itemId).style.display = 'block'
          else
            document.getElementById('comment-form-' + itemId).style.display = 'none'
        })
      })
    })
<div class="container-fluid">
    <div class="row example-basic">
      <div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2">
        <ul class="timeline" id="timeline">
          {% for item in items %}
          <li item-id={{item.id}} class="timeline-item">
            <div class="timeline-info">
              <span>{{item.data.strftime('%c')}}</span>
            </div>
            <div class="timeline-marker"></div>
            <div class="timeline-content">
              <h3 class="timeline-title">{{item.analista}} recomenda {{item.ativo}} a R${{item.preco}}.</h3>
              <p>Fonte:{{item.fonte}}</p>
            </div>
            <div id="comment-form-{{ item.id }}" style="display: none;">
              {{item.coments}} <br><span id='dataalvo'>Data Alvo: {{item.dataalvo}}</span>
            </div>
          </li>
          {% endfor %}
          <li class="timeline-item period">
            <div class="timeline-info"></div>
            <div class="timeline-marker"></div>
          </li>
        </ul>
      </div>
    </div>

OBS: I have a unique page for the registration of new items to the database, Timeline returns the existing items in the BD.

  • It’s really ruining the code. Mixing jQuery with pure JS. Since you use jQuery, use it throughout the code.

  • I don’t understand why you’re carrying your own page inside a div: $('#timeline').load(location.href + ' #timeline')

  • 1

    This is a common error, it happens pq the Listener is added to the element at the beginning of the execution and dynamically loaded elements do not burst it. To solve you must add the Istener in another fixed element and observe for it the event: $('body').on('.elemento', 'click', function(){})

  • $('.elemento').live('click', function(){}) tbm works, in newer jQuery versions

  • @edsonalves Live was removed from version 1.9 (see documentation)

  • @Sam, we swore it was the other way around. Thanks!

  • @Sam this way I got the result I wanted, is it wrong? How should I have done this . load?

  • I think I’m wrong, because you’re loading the full page into the div. You should pull the load from a source that only returns the HTML you want.

Show 3 more comments

1 answer

0

The reason for the behavior is because you make the Binding of EventListener only in page loading... so elements that were added later do not receive this assignment, you can highlight those new elements that did not receive them or simply remove and add again to all of them at each upload.

setTimeout(() => {
  $('#timeline').load(location.href + ' #timeline', () => {
    updateBindings();
  });
}, 9000);

let updateBindings = function() {
  var itemsDivs = document.querySelectorAll('.timeline-item');
  itemsDivs.forEach(function(itemsDiv) {

    itemsDiv.addEventListener('click', function() {
      var itemId = this.getAttribute('item-id')
      var display = document.getElementById('comment-form-' + itemId).style.display
      if (display == 'none')
        document.getElementById('comment-form-' + itemId).style.display = 'block'
      else
        document.getElementById('comment-form-' + itemId).style.display = 'none'
    })
  })
};


$(document).ready(function() {
  updateBindings();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container-fluid">
  <div class="row example-basic">
    <div class="col-xs-10 col-xs-offset-1 col-sm-8 col-sm-offset-2">
      <ul class="timeline" id="timeline">
        {% for item in items %}
        <li item-id={{item.id}} class="timeline-item">
          <div class="timeline-info">
            <span>{{item.data.strftime('%c')}}</span>
          </div>
          <div class="timeline-marker"></div>
          <div class="timeline-content">
            <h3 class="timeline-title">{{item.analista}} recomenda {{item.ativo}} a R${{item.preco}}.</h3>
            <p>Fonte:{{item.fonte}}</p>
          </div>
          <div id="comment-form-{{ item.id }}" style="display: none;">
            {{item.coments}} <br><span id='dataalvo'>Data Alvo: {{item.dataalvo}}</span>
          </div>
        </li>
        {% endfor %}
        <li class="timeline-item period">
          <div class="timeline-info"></div>
          <div class="timeline-marker"></div>
        </li>
      </ul>
    </div>
  </div>

Also, as mentioned in the comments, another point of attention is the content you are loading in the method load()... if your backend is not prepared to return only the items you would be loading the content again from the full page of <ul id="timeline">.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.