jQuery plugin with trigger in event click

Asked

Viewed 93 times

0

jQuery plugin:

(function($){

    $.fn.extend({
        meuPlugin: function(){
            $('body').on('click', this, function( e ){
                console.log( $(this).attr('href') );
                return false;
            });
        }
    });

})(jQuery);

Selector in HTML:

<a href="um_link_qualquer.php" id="link_teste">Meu link</a>

Call from the Plugin:

$(document).ready(function(){
    $('#link_teste').meuPlugin();
});

Problem:

$(this).attr('href') is making reference to the body, not to the $('#link_teste') in the plugin call.

• My first attempt was to change:

$('body').on('click', this, function( e ){ for this.on('click', function() {

(function($){

    $.fn.extend({
        meuPlugin: function(){
            //$('body').on('click', this, function( e ){
            this.on('click', function() {
                console.log( $(this).attr('href') );
                return false;
            });
        }
    });

})(jQuery);

PS: It worked, but not 100%. It turns out that if I assign the plugin to an element that will be loaded later via ajax, the click will not call the plugin.

• I also tried with the e.target, the only difference is that instead of returning the body, returns the clicked element, whatever.

• This is another attempt:

// plugin
$.fn.extend({
    meuPlugin: function () {
        console.log( this.attr('href') );
        return false;
    }
});
// chamada do plugin no elemento #link_teste
$(document).ready(function(){
    $('body').on('click', '#link_teste', function ( e ) {
        e.preventDefault();
        $(e.target).meuPlugin();
    });
});

It works exactly as needed, but the call of the plugin was very "dirty". I need something more accurate and clean as already mentioned:

$('#link_teste').meuPlugin();

Goal:

I need the attributes of #link_teste referencing it within the plugin, such as href, action, method, etc and compatible with the ajax:

$('#link_teste').meuPlugin();

Thanks in advance!

1 answer

1


Remember that in the Event Delegation the hierarchy of the elements must be maintained. The parent element delegates the function to its descendants that correspond to the selector.

In that case, the <body> is delegating to the elements <a> with the corresponding ID.

Ex.:

$.fn.extend({
  meuPlugin: function () {
    let id = '#' + $(this).attr('id');
    
    $('body').on('click', id, function () {
      console.log($(this).attr('href'));
    });
  }
});

$(function () {
  $('#link_teste').meuPlugin();
  $('#outro_link').meuPlugin();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<a href="http://www.google.com" id="link_teste">Link qualquer</a>
<br><br>
<a href="http://www.youtube.com" id="outro_link">Outro link qualquer</a>
<br><br>
<button type="button">Clique aqui para testar se irá ativar</button>

(Click "Run" and check the output of console)

  • So the problem is q o this refers to body, so the plugin is called when clicking on any element on the site.

  • I changed the code section, please take a look.

  • 1

    this does not refer to the <body>, refers to the return element(s) of the selector $('a'). Actually the problem that reported occurs yes, but from what I noticed is in the selector $('body').on('click', ...) within the scope of plugin, because this selector will add one Event Handler in the <body> whole.

  • Exactly. I’m going to edit the question with another experiment I did and it worked, but it’s also not exactly what I need.

  • Actually, more specifically, the problem was in the this passed to the method on() here: $('body').on('click', this, ...). I edited the answer, please check if this is the way you are looking. I added the ID instead of the this, because we were passing an object, but the parameter accepts only string: http://api.jquery.com/on/#on-Events-selector-data-Handler

  • It worked perfectly! Just missed preventDefault(), but I add here. Vlw brother! D

  • Quiet, brother! Tamo along!

Show 2 more comments

Browser other questions tagged

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