JavaScript se liga ao Blur, tanto 'se indexof' e 'else' executados
-
26-09-2019 - |
Pergunta
Html
<!-- Contents of div #1 -->
<form id="6hgj3y537y2biacb">
<label for="product_calendar" class="entry_label">Calendar</label>
<input type="text" name="product_calendar" class="entry" value="" />
</form>
<form id="pyc2w1fs47mbojez">
<label for="product_calendar" class="entry_label">Calendar</label>
<input type="text" name="product_calendar" class="entry" value="" />
</form>
<form id="kcmyeng53wvv29pa">
<label for="product_calendar" class="entry_label">Calendar</label>
<input type="text" name="product_calendar" class="entry" value="" />
</form>
<!-- Contents of div #2 -->
<div id="calendar_addRemove"> <!-- CSS >> display: none; -->
<div id="calendar_add">
<label for="calendar_add" class="calendar_addLabel">Add Occurrence</label>
<input type="text" name="calendar_add" class="calendar_addInput" value=""/>
</div>
<div id="calendar_remove">
<label for="calendar_remove" class="calendar_removeLabel">Remove Occurrence</label>
<input type="text" name="calendar_remove" class="calendar_removeInput" value=""/>
</div>
</div>
JavaScript
// Complete behavioral script
$(function() {
$('input[name=product_calendar]').css({ 'color': '#5fd27d', 'cursor': 'pointer' }).attr({ 'readonly': 'readonly' }); // Additional formatting for specified fields
$('input[name=product_calendar]').focus(function() { // Focus on any 'input[name=product_calendar]' executes function
var product_calendar = $(this); // Explicit declaration
var attr_val = $(product_calendar).attr('value');
$('#calendar_addRemove input').attr({ 'value': '' }); // Clear input fields
$('#calendar_addRemove').fadeIn(500, function() { // Display input fields
$('input[name=calendar_add]').blur(function() { // After value entered, action occurs on blur
alert('Blur'); // Added for testing
var add_val = $('input[name=calendar_add]').attr('value');
if (add_val != '') {
alert('Not Blank'); // Added for testing
var newAdd_val = attr_val + ' ' + add_val;
$(product_calendar).attr({ 'value': newAdd_val });
$('#calendar_addRemove').fadeOut(500);
}
else {
alert('Blank'); // Added for testing
$('#calendar_addRemove').fadeOut(500);
}
});
$('input[name=calendar_remove]').blur(function() { // After value entered, action occurs on blur
alert('Blur'); // Added for testing
var remove_val = $(this).attr('value');
if (remove_val != '') {
alert('Not Blank'); // Added for testing
if (attr_val.indexOf(remove_val) != -1) {
alert('Eval True'); // Added for testing
var newRemove_val = attr_val.replace(remove_val, '');
$(product_calendar).attr({ 'value': newRemove_val });
$('#calendar_addRemove').fadeOut(500);
}
else {
alert('Eval False'); // Added for testing
$('#calendar_remove').append('<p class="error">Occurrence Not Found</p>');
$('.error').fadeOut(1500, function() { $(this).remove(); });
}
}
else {
alert('Blank'); // Added for testing
$('#calendar_addRemove').fadeOut(500);
}
});
});
});
});
Eu adicionei alguns alertas para ver a ordem em que este script está se saindo. Quando eu entro 1234
em input[name=calendar_add]
E Blur, os alertas surgem como esperado. Então, quando eu prossegui e entro 1234
em input[name=calendar_remove]
e borrão, este script lança alertas na seguinte ordem: Blur, não em branco, avaliar false, borrão, não em branco, avaliar verdadeiro - se eu repetir esse processo, a ocorrência dos meus alertas dobrar a cada vez (adicionar e remover), No entanto, mantendo a mesma ordem (como se nos conjuntos).
Eu acho que o problema é uma re-descrição de valor múltiplo da variável attr_val
No DOM, mas não tenho certeza de como revisar meu script para aliviar esse problema.
Solução
Não. Isso não é possível.
Então, existem algumas razões possíveis que podem parecer assim:
O código que realmente executa não se parece assim. Pode ser uma versão mais antiga em cache ou você está procurando no arquivo errado.
O código é executado mais de uma vez, para que as duas filiais de execução possam ser executadas. (Embora eu não possa realmente ver nenhuma possibilidade para isso aqui.)
Você está interpretando mal o resultado, e o que você vê que leva à conclusão de que ambas as filiais precisam ser executadas, é de fato causado por algum outro código.
Você pode usar um depurador para definir pontos de interrupção no código. Defina um ponto de interrupção antes da condição e outro em cada ramo. Então você verá se o código é executado duas vezes, uma vez ou não.
Editar:
Os alertas que você adicionou ao código mostram que o evento é realmente chamado duas vezes, e a primeira vez que os valores não são o que você acha que são.
Adicione algum código para tentar descobrir de onde o evento é invocado. Pegue o objeto de evento adicionando -o à assinatura da função: .blur(function(e) {
. Em seguida, você pode usar o E.CurrentTarget para obter o elemento que acionou o evento e exibir alguns atributos dele (como se fosse ID) para identificá -lo.
Editar 2:
Eu sou curioso sobre esta linha:
$(product_calendar).attr({ value: newRemove_val });
Você cria a variável product_calendar
Em algum lugar, ou você quis dizer:
$('input[name=product_calendar}').attr({ value: newRemove_val });
Editar 3:
Vendo o código completo, a causa da execução dupla é clara. Você está adicionando até manipuladores até um manipulador de eventos, o que significa que outro manipulador é adicionado sempre.
A razão para attr_val
Não funcionar corretamente é porque é criado como uma variável local em uma função e depois não superou em outra função.
Adicione os manipuladores do Blur do início, e eles ocorrem apenas uma vez. Declare a variável fora da função.
Algumas notas:
- Você pode usar o
val
função em vez de acessar ovalue
atributo usando oattr
função. - Quando você atribui
$(this)
paraproduct_calendar
, é um objeto jQuery. Você não tem que usar$(product_calendar)
. - A remoção não corresponde aos valores completos, então você pode adicionar
12
e2
, depois remova2
e você entendeu1
e2
deixei.
(Este é um texto fictício, porque você não pode ter um bloco de código após uma lista ...)
// Complete behavioral script
$(function() {
// declare variables in outer scope
var attr_val;
var product_calendar;
$('input[name=product_calendar]')
.css({ 'color': '#5fd27d', 'cursor': 'pointer' })
.attr('readonly', 'readonly') // Additional formatting for specified fields
.focus(function() { // Focus on any 'input[name=product_calendar]' executes function
product_calendar = $(this); // Explicit declaration
attr_val = product_calendar.val();
$('#calendar_addRemove input').val(''); // Clear input fields
$('#calendar_addRemove').fadeIn(500); // Display input fields
});
$('input[name=calendar_add]').blur(function() { // After value entered, action occurs on blur
var add_val = $(this).val();
if (add_val != '') {
product_calendar.val(attr_val + ' ' + add_val);
}
$('#calendar_addRemove').fadeOut(500);
});
$('input[name=calendar_remove]').blur(function() { // After value entered, action occurs on blur
var remove_val = $(this).val();
if (remove_val != '') {
if (attr_val.indexOf(remove_val) != -1) {
product_calendar.val(attr_val.replace(remove_val, ''));
$('#calendar_addRemove').fadeOut(500);
} else {
$('#calendar_remove').append('<p class="error">Occurrence Not Found</p>');
$('.error').fadeOut(1500, function() { $(this).remove(); });
}
} else {
$('#calendar_addRemove').fadeOut(500);
}
});
});
Outras dicas
OK, acho que entendo o problema agora.
Toda vez que você focar no product_calendar
elementos, você faz um fadeIn
no #calendar_addRemove
elemento. Cada vez que você faz isso fadeIn
, você usa o retorno de chamada para vincular novo manipuladores de desfoque para o calendar_add
e calendar_remove
elementos. Isso significa que com o tempo, esses elementos terão múltiplo Manipuladores Blur (todos executando a mesma lógica.) Isso não pode ser o que você deseja.
No script abaixo, retirei os manipuladores aninhados para que eles estejam vinculados apenas uma vez a cada elemento. Observe que:
product_calendar
é declarado (comonull
) no topo da função anônima e depois atualizado pelo manipulador de foco noproduct_calendar
elemento. EU acho Isso resulta em comportamento correto.attr_val
é declarado e atribuído localmente nos dois manipuladores do Blur. De novo eu acho Isso resulta no comportamento correto: se você declarar fora dos manipuladores do Blur (comoproduct_calendar
é declarado), então você pode acidentalmente usar valores antigos quando o acessar.
Ainda não tenho certeza de como esse código deve funcionar, mas esse script executa de uma maneira que eu consideraria "razoável".
(A propósito, o código de produção provavelmente deve permitir espaço em branco no início e no final das seqüências de entrada.)
$(function() {
var product_calendar = null;
$('input[name=product_calendar]').css({ 'color': '#5fd27d', 'cursor': 'pointer' }).attr({ 'readonly': 'readonly' }); // Additional formatting for specified fields
$('input[name=calendar_add]').blur(function() { // After value entered, action occurs on blur
alert('Blur'); // Added for testing
var add_val = $('input[name=calendar_add]').attr('value');
if (add_val != '') {
alert('Not Blank'); // Added for testing
var attr_val = $(product_calendar).attr('value');
var newAdd_val = attr_val + ' ' + add_val;
$(product_calendar).attr({ 'value': newAdd_val });
$('#calendar_addRemove').fadeOut(500);
}
else {
alert('Blank'); // Added for testing
$('#calendar_addRemove').fadeOut(500);
}
});
$('input[name=calendar_remove]').blur(function() { // After value entered, action occurs on blur
alert('Blur'); // Added for testing
var remove_val = $(this).attr('value');
if (remove_val != '') {
alert('Not Blank'); // Added for testing
var attr_val = $(product_calendar).attr('value');
if (attr_val.indexOf(remove_val) != -1) {
alert('Eval True'); // Added for testing
var newRemove_val = attr_val.replace(remove_val, '');
$(product_calendar).attr({ 'value': newRemove_val });
$('#calendar_addRemove').fadeOut(500);
}
else {
alert('Eval False'); // Added for testing
$('#calendar_remove').after('<p class="error">Occurrence Not Found</p>');
$('.error').fadeOut(1500, function() { $(this).remove(); });
}
}
else {
alert('Blank'); // Added for testing
$('#calendar_addRemove').fadeOut(500);
}
});
$('input[name=product_calendar]').focus(function() { // Focus on any 'input[name=product_calendar]' executes function
product_calendar = $(this);
$('#calendar_addRemove input').attr({ 'value': '' }); // Clear input fields
$('#calendar_addRemove').fadeIn(500);
});
});