javascript jquery events this

javascript - ''esto'' no funciona correctamente en otro evento. No tengo idea de por qué



jquery events (3)

Su .click() evento .click() no vincula una función a la que se llamará cuando se haga clic en .figure . Está haciendo una llamada directa a toggleCarousel usando this objeto vigente en ese momento ( window ). .click() proporcionar una función de devolución de llamada a .click() .

Cambio: $(''.figure'').click(toggleCarousel(this)); a:

$(''.figure'').click(function(){ toggleCarousel(this); });

Para que toggleCarousel se invoque utilizando el objeto correcto en el momento del clic. Como su código es ahora, no se ajusta a la firma JQuery para .click() e intenta invocar toggleCarousel inmediatamente usando this objeto que está en control en el momento en que se encuentra el código por primera vez, que es la window .

El enlace de this objeto es volátil en JavaScript ... es decir, no siempre apunta al mismo objeto y su enlace puede cambiar de una línea de código a la siguiente. Cómo invocas el código que contiene la palabra, this determina a qué objeto se unirá.

Aquí hay una lista de verificación que puede seguir para saber a qué se unirá esto ...

Si se invoca el código que contiene this :

  1. Como método o propiedad de una instancia de objeto (a través de una variable de instancia):

    var o = new Object(); // "this" will be bound to the "o" object instance // while "someProperty" and "someMethod" code executes o.someProperty = someValue; o.someMethod();

  2. Mediante una .call() , .apply() , .bind() o Array.prototype.fn :

    // "this" will be bound to the object suppled as the "thisObjectBinding" someFunction.call(thisObjectBinding, arg, arg); someFunction.apply(thisObjectBinding, [arg, arg]); var newFunc = someFunction.bind(thisObjectBinding, arg, arg);

    Nota : Cuando se invoca una función de devolución de llamada (es decir, controlador de eventos), hay una llamada implícita al controlador cuando se activa el evento. En estos casos, el objeto responsable de desencadenar el evento se convierte en el objeto vinculado a this .

    Además, varios métodos Array.prototype permiten que se thisObject un thisObject que alterará el enlace durante la duración de la llamada al método:

    Array.prototype.every( callbackfn [ , thisArg ] ) Array.prototype.some( callbackfn [ , thisArg ] ) Array.prototype.forEach( callbackfn [ , thisArg ] ) Array.prototype.map( callbackfn [ , thisArg ] ) Array.prototype.filter( callbackfn [ , thisArg ] )

  3. Si no se aplica ninguno de los otros escenarios, se produce el enlace predeterminado.

    3a. Con "use strict" en efecto: this undefined está undefined

    3b. Sin "use strict" en efecto: this une al objeto Global

NOTAS

a) this enlace también puede verse afectado mediante el uso de eval() , pero como práctica recomendada general, se debe evitar el uso de eval() .

b) Cuando se utilizan atributos HTML para conectar elementos DOM a controladores de eventos (es decir, onclick , onload , etc.), se crean funciones globales anónimas de envoltura alrededor del valor de la propiedad de manejo de eventos, haciendo así que el objeto Global ( window ) sea this objeto . Esta es una de varias razones para evitar los atributos de eventos HTML en línea.

Esta pregunta ya tiene una respuesta aquí:

En pocas palabras, no sé por qué no funciona, he intentado Console.Log () para descubrir qué es ''esto'' y el evento sigue pasando la ventana. Es un evento de clic que se supone que activa los efectos en una determinada figura en este carrusel, por lo que no puedo buscar individualmente la clase (al menos que yo sepa). ¿Alguna solución de los más inteligentes?

var carFigure = null; //----------The Events $(''.figure'').click(toggleCarousel(this)); //$(''.figure'').mouseover(stopCarousel(this)); //$(''.figure'').mouseleave(startCarousel(carFigure)); //------------Switcharoo function function toggleCarousel(event) { var bool = false; console.log(event) if (bool) { stopCarousel(event); bool = false; } else { startCarousel(event); bool = true; } } //----------The action functions function stopCarousel(e) { if (carFigure != null) { document.getElementById(''carousel'').style.animationPlayState = "paused"; var p = e.parentElement; var a = p.getElementsByTagName(''DIV'')[2]; if (a.getElementsByTagName(''IMG'')[0].style.transform = "none") { a.getElementsByTagName(''IMG'')[0].style.transform = "scale(1.2, 1.2) translateY(-25%)"; a.getElementsByTagName(''IMG'')[0].style.borderRadius = "100%"; a.getElementsByTagName(''H5'')[0].style.color = "rgba(255,255,255, 0)"; this.getElementsByClassName(''links'')[0].style.transform = "translateY(-250%)"; this.getElementsByClassName(''links'')[0].style.opacity = "1"; carFigure = null; } } }; function startCarousel(e) { if (e != null) { carFigure = e; document.getElementById(''carousel'').style.animationPlayState = "running"; var p = e.parentElement; var a = p.getElementsByTagName(''DIV'')[2]; a.getElementsByTagName(''IMG'')[0].style.transform = "none"; a.getElementsByTagName(''IMG'')[0].style.borderRadius = "0"; a.getElementsByTagName(''H5'')[0].style.color = "rgba(255,255,255, 1)"; this.getElementsByClassName(''links'')[0].style.transform = "none"; this.getElementsByClassName(''links'')[0].style.opacity = "0"; } };

--HTML Version (Snippet) <div class="carcontainer"> <div id="carousel"> <figure> <div class="figure"> <div class="links"> <a><img src="~/Content/images/LinkedInIco.png" /></a> <a href="http://www.example.com"><img src="~/Content/images/WebsiteIco.png" /></a> </div> </div> <div> <h5>Person Name</h5> <img src="~/Content/images/Name.jpg" alt="" /> </div> </figure> <figure> <div class="figure"> <div class="links"> <a><img src="~/Content/images/LinkedInIco.png" /></a> <a href="http://www.example.com"><img src="~/Content/images/WebsiteIco.png" /></a> </div> </div> <div> <h5>Person Name</h5> <img src="~/Content/images/Name.jpg" alt="" /> </div> </figure> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


No está adjuntando el controlador de eventos correctamente. Esta línea:

$(''.figure'').click(toggleCarousel(this));

... llama a toggleCarousel con this inmediato (eso es lo que harán los padres). Lo que realmente quieres es pasar el objeto de función a .click() :

$(''.figure'').click(toggleCarousel);

Actualización :

Como señaló @FelixKling, también querrá pasar el objetivo del evento a las funciones posteriores; parece que esperan un elemento , no el evento . Además, bool se restablecerá a false cada llamada, que no es lo que desea; deberías ponerlo en el cierre:

var flag = false; // "bool" is a reserved word, changed the name function toggleCarousel(event) { var element = event.target; if (flag) { stopCarousel(element); } else { startCarousel(element); } flag = !flag; }


Puede que esta no sea la mejor respuesta o la más directa, pero espero que esto lo ayude a comprender lo que se ha perdido.

En javaScript, this objeto se establece durante una llamada a la función, en efecto. (aunque tome nota de la respuesta extendida aquí que detalla cómo se define / vincula esto). Considera esto:

function this_test () { console.log( this ); } this_test(); // prints nothing var x = {f:this_test}; // note, references to functions are not the same as function calls x.f(); // prints {f:[function]} ie this==x inside the call this_test.call( x ); // identical in effect to above.

Con eso en mente, considere esta línea que escribió:

$(''.figure'').click(toggleCarousel(this));

Lo que esto hace es establecer una función de controlador de eventos que es el resultado de llamar a toggleCarousel(this) . Debido a que este es (supongo) código de nivel superior en un archivo js o en una etiqueta de script, en este contexto this === window porque no está dentro de una función.

Lo que deberías estar haciendo es esto:

$(''.figure'').click( toggleCarousel );

Finalmente, dado que está usando jQuery, debe usar los métodos de jQuery para buscar y modificar DOM, ya que es mucho más fácil (y compatible con varios navegadores). Por lo tanto, esta expresión a veces se ve en el código de evento jQuery:

function event_handler () { var $this = $(this); }

Lectura altamente recomendada - jQuery Click Event - la mayoría de los otros controladores de eventos funcionan de manera similar.