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
:
-
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();
-
Mediante una
.call()
,.apply()
,.bind()
oArray.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 sethisObject
unthisObject
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 ] )
-
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 deeval()
, pero como práctica recomendada general, se debe evitar el uso deeval()
.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
) seathis
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.