Part of your problems and understanding some things in your code, the first one I see is your understanding of the this
.
The this
is the object of execution context, its use is a little complicated to understand even, but once you understand its use it becomes very useful, so I will try to explain you below using comments in the code:
/// ; neste momento o `this` === `window`
console.log( 'this é igual a window ? ', this === window );
var elTimerInicial = document.getElementById("TimerInicial");
let Inicial = {
seletorTimer: elTimerInicial,
letrasRegex: /[A-Z]+/,
maximo: 59,
/// ; Neste momento o this ainda é `window` e nele não existe
/// ; a propriedade `selectorTime`, você esta pensando que nesse
/// ; momento o `this` era o objeto `Inicial` e por isso estava chamando
/// ; `this.seletorTimer`.
/// ; Outra coisa que acontece é que neste momento o objeto
/// ; `Inicial` ainda não foi criado, ou seja, você também não
/// ; conseguiria acessar usando `Inicial.selectorTime`
SemLetras: elTimerInicial.addEventListener('keyup', function(){
/// ; Agora complica um pouco, note que eu troquei seu
/// ; `Arrow Function` por um `Function normal`.
/// ; Quando esse evento é disparado o `this` aqui vai ser o
/// ; elemento que disparou o evento ou seja, nesse caso o `elTimerInicial`
console.log( 'Function Normal, this é igual a window ? ', this === window, this );
}),
numeroLimite: elTimerInicial.addEventListener('keyup', () => {
/// ; Aqui eu mantive o `Arrow Function` para você ver a diferença
/// ; ele NÃO cria contexto, então aqui dentro
/// ; o `this` é o mesmo que era fora dele quando ele
/// ; foi criado, ou seja, o `window`.
/// ; Esse é um dos motivos que levaram ao desenvolvedores
/// ; a criar esse novo tipo de função, veja um
/// ; exemplo prático na sessão 'alguns problemas comuns com this'.
console.log( 'Arrow Function, this é igual a window ? ', this === window );
}),
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Guessing game</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" media="screen" href="style.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
</head>
<body>
<h1>PROJETO TIMER</h1>
<div id="TimerInicial">
<input type="number" placeholder="HH" > :
<input type="number" placeholder="MM" > :
<input type="number" placeholder="SS" >
</div>
</body>
</html>
Another problem is that in your code you’re trying to catch value
of the element #TimerInicial
which is a <div>
and not the <input>
you’re getting the value.
So in the code below we will try to use the this
and change your object.
var elTimerInicial = document.getElementById("TimerInicial");
/// ; ao invés de criar um objeto vamos usar o próprio `elTimerInicial`
elTimerInicial.letrasRegex = /[A-Z]+/;
elTimerInicial.maximo = 59;
elTimerInicial.semLetras = function( input ){
/// ; Quando você chamar essa função desta forma `elTimerInicial.semLetras( )`
/// ; `this` aqui sera o próprio `elTimerInicial`
console.log( '2- semLetras - this:' , this, ' input:' , input );
if( input.value.match(this.letrasRegex) ){
input.value = "";
}
};
elTimerInicial.numeroLimite = function( input ){
console.log( '3- numeroLimite - this:' , this, ' input:' , input );
if ( input.value > this.maximo ) {
input.value = 59;
}
};
/// ; Como só os `input`s são filhos do `elTimerInicial` vamos usar a propriedade
/// ; `children` do `elTimerInicial` para pegar seu filhos e adicionar o evento neles
/// ; depois vamos usar o `this` novamente dentro da função:
for( var i = 0, max = 3; i < max ; i++ )
{
elTimerInicial.children[ i ].addEventListener('keyup', function(){
/// ; Quando essa funcao for chamada o `this` aqui dentro sera o `input`
/// ; que disparou o evento.
/// ; vamos usar o `parentNode` para pegar o pai desse `input` nesse caso o
/// ; `elTimerInicial` e vamos usar as funções que
/// ; adicionamos a esse elemento `elTimerInicial`
console.log( '1- keyup this:' , this, 'this.parentNode', this.parentNode );
this.parentNode.semLetras( this );
this.parentNode.numeroLimite( this );
/// ; ^ ^ ^ this === input
/// ; | função que adicionamos ao `elTimerInicial`
/// ; elTimerInicial
});
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Guessing game</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" media="screen" href="style.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
</head>
<body>
<h1>PROJETO TIMER</h1>
<div id="TimerInicial">
<input type="number" placeholder="HH" > :
<input type="number" placeholder="MM" > :
<input type="number" placeholder="SS" >
</div>
</body>
</html>
Some common problems with the this
Fact is, when you’re wearing this
how you call a function can change its context.
Imagine I have an object with the name mObject
and in that object there is the method minhafuncao
using the this
hoping he’ll be the mObject
.
Imagine that for some reason instead of calling mObject.minhafuncao()
thus, namely of direct form, you need to call this function within a setTimeout
, pass her off as a callback
or associate this function to a variable to save time by typing etc... as in the example below:
var mObject = {
minhafuncao:function(){
console.log( 'this é:', this===window ? 'window' : this );
}
};
/// ; Exemplo callback
function chamaCallback( callback ){
callback();
}
chamaCallback( mObject.minhafuncao );
/// ; Exemplo associar a função a uma variável
var func = mObject.minhafuncao;
func();
/// ; Exemplo setTimeout
setTimeout( mObject.minhafuncao, 1 );
If this occurs you will realize that the this
that this within the function nay will be the mObject
he will be the window
or some other unexpected context, now you may have noticed that this occurred because the context of the call has changed.
This can be easily solved with the use of apply
, call
, bind
to manipulate the context or in the case of the example of setTimeout
a simple function
already solve, see the code below:
var mObject = {
minhafuncao:function(){
console.log( 'this é:', this===window ? 'window' : this );
}
};
/// ; Exemplo associar a função a uma variável
var func = mObject.minhafuncao;
func.call( mObject );
/// ; func.call( mObject, parametro1, parametro2, ... );
/// ; ^ ^ os parâmetros da função começa aki
/// ; contexto, isso sera o `this` dentro da função
/// ; Exemplo setTimeout
setTimeout( function(){
mObject.minhafuncao();
/// ; o contexto dessa chamada voltou a ser o `mObject`
}, 1 );
/// ; Exemplos com o `bind`
var novaFunc = mObject.minhafuncao.bind( mObject );
/// ; bind retorna a função com o contexto sendo o parâmetro
/// ; Agora quando eu chamar a função `novaFunc` ela vai manter o contexto
/// ; Então essa chamada o `this` sera o `mObject`
novaFunc();
/// ; Chamando pela callback
function chamaCallback( callback ){
callback();
}
chamaCallback( novaFunc );
/// ; O mesmo ocorre com o `setTimeout` o contexto da função vai ser mantido
/// ; por causa do `bind` então o `this` sera o `mObject`
setTimeout( novaFunc, 1 );
/// ; Ou seja com `bind`, `call`, `apply` você vai conseguir manipular o
/// ; contexto e modificar como quiser veja esse outro exemplo:
novaFunc = mObject.minhafuncao.bind( {name:"### Mudei o contexto totalmente ###"} );
setTimeout( novaFunc, 10 );
Another example, imagine that you have a <div>
in which you placed an event onClick
, and you will use the this
within the event to change the style
, className
, etc... of that <div>
and after x
time will return to normal, ie using a setTimeout
within the event.
/// ; criar a div
var div = document.createElement('DIV');
/// ; adicionar ele ao body da pagina
document.body.appendChild( div );
/// ; colocar o texto e mudar style `bgcolor`
div.innerHTML = 'MEU TESTE';
div.style['backgroundColor'] = 'red';
/// ; adicionar o evento de onclick
div.onclick = function(){
/// ; `this` quando esse evento for disparado sera a `<div>`
this.style['backgroundColor'] = 'green';
this.innerHTML = "eu cliquei aki";
/// ; agora dentro da função do setTimeout o `this` será a `window`
/// ; para solucionar esse problema alem das soluções já mostradas
/// ; podemos associar o `this` a uma variável local dentro do
/// ; evento e utilizar essa variável dentro do `setTimeout` veja abaixo
var self = this;
setTimeout( function(){
console.log( 'settimeout this é:', this === window ? 'window':'outra coisa');
self.style['backgroundColor'] = 'red';
}, 600 );
/// ; Outra solução seria o uso do `Arrow function`
/// ; isso porque como eu já disse antes um dos
/// ; objetivos dele é de NÃO criar contexto, então
/// ; o `this` dentro dele será o mesmo que era fora dele
setTimeout( ()=>{
console.log( 'arrow function this é:', this === window ? 'window': this);
this.innerHTML = "MEU TESTE";
}, 600);
}
Other links that may help
Links Sopt:
"this" a reliable reference?
What’s the difference between $(this) and $this and this?
What’s the THIS parameter for?
External Links:
codigosimples.net - Learn more about the "this" used javascript
Mozilla Developer Docs References:
Arrow functions, this
, children
, apply
, call
, bind
Ola @Daniel, you could improve your question ( I couldn’t understand it -- [Ask] ), it is only worth you to put the error that appeared on the console, it can help the community to solve their doubt. = P -- don’t forget to take a look at our [Tour] =D
– Icaro Martins
@Icaromartins I’m not in the habit of asking in the Stack, I tried to give a fancy in the question, I hope it is more readable kkk
– Daniel Kenzi
Also add your code here as text and not as image or link
– Costamilam
Truth thank you @Costamilam!
– Daniel Kenzi
@Danielkenzi, I’ve changed the title of your question, because I believe that way you can help other people. If you feel that I have changed the meaning of your original question please access this link (revisions) and click on reverse in the version you think best. = D
– Icaro Martins
@Icaromartins is excellent hahaha. After the explanation you gave really makes more sense, Rigadão!
– Daniel Kenzi