web-dev-qa-db-fra.com

comment obtenir un élément source d'événement JavaScript?

Existe-t-il un moyen de récupérer l'élément source d'un appel javaScript en ligne?

J'ai un bouton comme ça:

<button onclick="doSomething('param')" id="id_button">action</button>

Remarque:

  • le bouton est généré à partir du serveur
  • Je ne peux pas modifier le processus de génération
  • plusieurs boutons sont générés sur la page, je n'ai le contrôle que du côté client.

Ce que j'ai essayé

function doSomething(param){
    var source = event.target || event.srcElement;
    console.log(source);
}

Sur firebug je reçois l'événement n'est pas défini

Edit: Après quelques réponses, un remplacement de la gestion des événements à l'aide de jQuery est très acceptable. Mon problème est de savoir comment appeler la fonction onClick d’origine avec ses paramètres d’origine et sans connaître le nom de la fonction.

code:

<button onclick="doSomething('param')" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>
.
.
and so on..

Donc, la dérogation serait:

$(document).on('click', 'button', function(e) {
  e.preventDefault();
  var action = $(this).attr('onclick');
  /**
   * What to do here to call
   * - doSomething(this, 'param'); if button1 is clicked
   * - doAnotherSomething(this, 'param1', 'param2'); if button2 is clicked
   * - doDifferentThing(this); if button3 is clicked
   * there are many buttons with many functions..
   */
});
31
ilyes kooli

Vous devez modifier le code HTML généré pour ne pas utiliser de javascript en ligne et utiliser plutôt addEventListener.

Si vous ne pouvez pas modifier le code HTML de quelque manière que ce soit, vous pouvez obtenir les attributs onclick, les fonctions et les arguments utilisés et les "convertir" en javascript non intrusif à la place en supprimant les gestionnaires onclick et en utilisant les écouteurs d'événement.

Nous commençons par obtenir les valeurs des attributs

$('button').each(function(i, el) {
    var funcs = [];

	$(el).attr('onclick').split(';').map(function(item) {
    	var fn     = item.split('(').shift(),
        	params = item.match(/\(([^)]+)\)/), 
            args;
            
        if (params && params.length) {
        	args = params[1].split(',');
            if (args && args.length) {
                args = args.map(function(par) {
            		return par.trim().replace(/('")/g,"");
            	});
            }
        }
        funcs.Push([fn, args||[]]);
    });
  
    $(el).data('args', funcs); // store in jQuery's $.data
  
    console.log( $(el).data('args') );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="doSomething('param')" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>

Cela nous donne un tableau de toutes les méthodes globales appelées par l'attribut onclick et des arguments passés, afin que nous puissions le répliquer.

Nous supprimerions alors tous les gestionnaires javascript en ligne

$('button').removeAttr('onclick')

et attacher nos propres gestionnaires

$('button').on('click', function() {...}

À l'intérieur de ces gestionnaires, nous obtenions les appels de fonction d'origine stockés et leurs arguments, et les appelions.
Comme nous savons que toutes les fonctions appelées par le javascript intégré sont globales, nous pouvons les appeler avec window[functionName].apply(this-value, argumentsArray), donc

$('button').on('click', function() {
    var element = this;
    $.each(($(this).data('args') || []), function(_,fn) {
        if (fn[0] in window) window[fn[0]].apply(element, fn[1]);
    });
});

Et à l'intérieur de ce gestionnaire de clics, nous pouvons ajouter tout ce que nous voulons avant ou après l'appel des fonctions d'origine.

Un exemple de travail

$('button').each(function(i, el) {
    var funcs = [];

	$(el).attr('onclick').split(';').map(function(item) {
    	var fn     = item.split('(').shift(),
        	params = item.match(/\(([^)]+)\)/), 
            args;
            
        if (params && params.length) {
        	args = params[1].split(',');
            if (args && args.length) {
                args = args.map(function(par) {
            		return par.trim().replace(/('")/g,"");
            	});
            }
        }
        funcs.Push([fn, args||[]]);
    });
    $(el).data('args', funcs);
}).removeAttr('onclick').on('click', function() {
	console.log('click handler for : ' + this.id);
  
	var element = this;
	$.each(($(this).data('args') || []), function(_,fn) {
    	if (fn[0] in window) window[fn[0]].apply(element, fn[1]);
    });
  
    console.log('after function call --------');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button onclick="doSomething('param');" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button2">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>

<script>
	function doSomething(arg) { console.log('doSomething', arg) }
    function doAnotherSomething(arg1, arg2) { console.log('doAnotherSomething', arg1, arg2) }
    function doDifferentThing() { console.log('doDifferentThing','no arguments') }
</script>

10
adeneo

Votre HTML devrait être comme ça: 

<button onclick="doSomething" id="id_button">action</button>

Et renommer votre paramètre d'entrée en événement comme celui-ci 

function doSomething(event){
    var source = event.target || event.srcElement;
    console.log(source);
}

résoudrait votre problème.

En remarque, je vous suggère de jeter un coup d'œil à jQuery et à JavaScript

27
slipset

Essayez quelque chose comme ça:

<html>
  <body>

    <script type="text/javascript">
        function doSomething(event) {
          var source = event.target || event.srcElement;
          console.log(source);
          alert('test');
          if(window.event) {
            // IE8 and earlier
            // doSomething
           } else if(e.which) {
            // IE9/Firefox/Chrome/Opera/Safari
            // doSomething
           }
        }
     </script>

    <button onclick="doSomething('param')" id="id_button">
      action
    </button>

  </body>      
</html>
2
srini

Je pense que la solution de @ slipset était correcte, mais n'était pas compatible avec tous les navigateurs.

Selon Javascript.info , les événements (lorsqu'ils sont référencés en dehors des événements de balisage) sont prêts pour plusieurs navigateurs dès que vous vous assurez qu'ils sont définis avec cette simple ligne: event = event || window.event.

Ainsi, la fonction complète compatible avec tous les navigateurs ressemblerait à ceci:

function doSomething(param){
  event = event || window.event;
  var source = event.target || event.srcElement;
  console.log(source);
}
0
DavidTaubmann

Vous pouvez passer this lorsque vous appelez la fonction

<button onclick="doSomething('param',this)" id="id_button">action</button>

<script>
    function doSomething(param,me){

    var source = me
    console.log(source);
}
</script>
0
Sethunath