-3

I just started to learn js and need a little help: I have the following function:

   //SET CHAT BEHAVIOR
   function chatSettings() {

        console.log('ChatSettings called')         

        function BtnAndScrollBar(texteditor) {     
            console.log('BTNAndScrollBar called');    
            const sendBtn = $('.cl.active').find('.sendBtn');
            const attachBtn = $('.cl.active').find('.attachBtn');
            console.log(sendBtn)          
        }

        function sendAndDeleteMessage(send) {
            console.log(send);
        }   

        var sendBtn = $('.cl.active').find('.sendBtn');
        sendBtn.mousedown(function () {      
            sendAndDeleteMessage(this);
        });               

        var textEditor1 = $('.cl.active').find('.chatTextarea');                  
        textEditor1.on('focus change mousedown mouseout keyup mouseup', function (){
            console.log(this);
            BtnAndScrollBar(this)
        });
   }       

      $('document').ready(function () {
          console.log('hello');
          $('.tabs').tabs();
          chatSettings();        
      });

I prepared a js.fiddle - As you can see from console.log when clicking into the textarea, the eventListener always listens to #cl1, even if .cl.active switches along with the according TAB.

The events in the textarea are just relevant, if .cl is active. My target is to wrap all three eventListener into one and apply the event to the textarea in the active stream, but all I tried went wrong... Can anyone help? #Dontrepeatyourself #DRY

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
Nixen85
  • 1,253
  • 8
  • 24
  • Ids must be unique within a given page. https://stackoverflow.com/questions/9454645/does-id-have-to-be-unique-in-the-whole-page `chatTextarea` is being repeated – Taplar Jun 25 '18 at 19:30
  • 2
    Rather than selecting each one individually, why not select them all with their shared `cl` class? – Taplar Jun 25 '18 at 19:31
  • Thanks. This was a copy paste error... Your suggestion creates a problem - I tried to use $('.cl.active'), but it did just work for the first element and after the second element got active, it didn´t work. Maybe because it is just initiated once onload. – Nixen85 Jun 25 '18 at 19:35
  • You only want the function to happen for the active element? That wasn't expressed in the question. – Taplar Jun 25 '18 at 19:35
  • Possible duplicate of [Event binding on dynamically created elements?](https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements) – Taplar Jun 25 '18 at 19:36
  • Please see the duplicate question about delegate event handlers. You can uses one to work with your use case of swapping around the active class on the elements. – Taplar Jun 25 '18 at 19:37
  • It's quite unclear what you are trying to do. My answer works with your original question as well as the current question title. You wanted to wrap three event listeners into one. `$(".cl textarea").on('focus change mousedown mouseout keyup mouseup', function () { greatFunction(this)});` – Don't Know Jun 27 '18 at 01:02

4 Answers4

1
$(".chatTextarea").on(
'focus change mousedown mouseout keyup mouseup', 
function (this) {
//this.id can contain the unique id
greatFunction(this);
}); 

This will bind event individually with unique id found with this keyword and also wraps all event listener into one function but this is better when you want to process each event with same functionality

please let me know if this helps.

Peace

Rahul
  • 74
  • 8
  • Please Nixen85 have look at the solution I worked upon https://jsfiddle.net/9oyoh67x/123/ let me know if this is helpful for you. – Rahul Jun 26 '18 at 13:47
  • This was very helpful: `$('.cl').find('.chatTextarea').each(function(){ $(this).on('focus change mousedown mouseout keyup mouseup', function (){ console.log($(this).val()); BtnAndScrollBar(this) });` – Nixen85 Jul 06 '18 at 13:13
0
$(".cl textarea").on('focus change mousedown mouseout keyup mouseup', function () {
    greatFunction(this)
});   

Tada!

P.S. Is there a reason greatFunction is defined inside window.onload?

Don't Know
  • 121
  • 2
  • 12
0

Try using $(document).ready function to load code when the page loads. Also use $('textarea #cl1').on to get the textarea with the #cl1 or whichever id you want to use and then call the function after using the .on. Hope this helps! Let me know if it works!

     $(document).ready(function () {

  function greatFunction(elem) {     
//do stuff
}    
      $('textarea').on('focus change mousedown mouseout keyup mouseup', function () {
            greatFunction(this)
        });  

}
  • I have updated my answer to have only 1 jquery function by using textarea which selects all textareas on the page –  Jun 25 '18 at 19:46
0

First off, I changed the onload to bind with jQuery, so all your logic is doing jQuery bindings, rather than swapping back and forth between jQuery and vanilla javascript. Also, doing an actual binding removes an inline binding.

Next, the binding has been condensed into a single delegate event listener. Since you eluded in your comments that it wasn't working for the active element after the active was moved or added, this reflected that you were dealing with dynamic elements. Delegate event listeners are one way to handle such things.

Delegate event listeners bind on a parent element of the elements that will change, or be created. It then waits for an event to happen on one of it's children. When it gets an event it is listening for, it then checks to see if the element that it originated from matches the child selector (second argument) for the listener. If it does match, it will then process the event for the child element.

Lastly, I added some buttons to swap around the active class, so you could see in the snippet that the event handler will start working for any element that you make active, regardless of it starting out that way.

$(window).on('load', function () {
  function greatFunction (elem) {
    console.log(elem.value);
  }
  
  $(document.body).on(
      'focus change mousedown mouseout keyup mouseup',
      '.cl.active .chatTextarea',
      function () {
          greatFunction(this);
      }
  );
  
  $('.makeActive').on('click', function () {
    $('.active').removeClass('active');
    $(this).closest('div').addClass('active');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="cl1" class="cl active"><textarea class="chatTextarea">aa</textarea><button class="makeActive">Make Active</button></div>
<div id="cl2" class="cl"><textarea class="chatTextarea">bb</textarea><button class="makeActive">Make Active</button></div>
<div id="cl3" class="cl"><textarea class="chatTextarea">cc</textarea><button class="makeActive">Make Active</button></div>
Taplar
  • 24,788
  • 4
  • 22
  • 35