Javascript 绑定模糊,两者都是“if indexOf”;以及“其他”已演出

发布于 2024-09-29 08:50:27 字数 4365 浏览 7 评论 0原文

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);
                    }
                });
            });
        });
    });

我添加了一些警报来查看此脚本的执行顺序。当我在 input[ 中输入 1234 时name=calendar_add] 并模糊,警报按预期出现。然后,当我继续在 input[name=calendar_remove] 中输入 1234 并模糊时,该脚本会按以下顺序发出警报:Blur、Not Blank、Eval False、模糊、非空白、Eval True - 如果我重复此过程,则每次警报的出现次数都会加倍(添加和删除),但保持相同的顺序(就像在集合中一样)。

我认为问题在于 DOM 中变量 attr_val 的多个值重新声明,但我不太确定如何修改我的脚本来缓解这个问题。

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);
                    }
                });
            });
        });
    });

I've added a few alerts to see the order this script is performing in. When I enter 1234 into input[name=calendar_add] and blur, the alerts come up as expected. Then, when I proceed and enter 1234 into input[name=calendar_remove] and blur, this script throws up alerts in the following order: Blur, Not Blank, Eval False, Blur, Not Blank, Eval True - If I repeat this process, the occurrence of my alerts double every time (both add and remove), however keeping the same order (as if in sets).

I think the issue is multiple value re-declaration of the variable attr_val in the DOM, but I'm not quite sure how to revise my script to alleviate this issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜点 2024-10-06 08:50:27

事实并非如此。那是不可能的。

因此,有一些可能的原因可能会导致这种情况:

  • 实际运行的代码看起来并非如此。它可能是缓存的旧版本,或者您正在查找错误的文件。

  • 代码运行多次,这样两个执行分支都可以运行。 (尽管我在这里看不到任何可能性。)

  • 您误解了结果,无论您看到什么导致两个分支都必须执行的结论,实际上是由其他一些代码引起的。

您可以使用调试器在代码中设置断点。在条件之前设置一个断点,并在每个分支中设置一个断点。然后您将看到代码是否运行两次、一次或根本不运行。

编辑:

您添加到代码中的警报显示该事件实际上被调用了两次,并且第一次的值不是您想象的那样。

添加一些代码来尝试找出事件是从哪里调用的。通过将事件对象添加到函数签名中来捕获事件对象:.blur(function(e) {。然后您可以使用 e.currentTarget 获取触发事件的元素,并显示其中的一些属性(就像它的 id)来识别它。

编辑 2:

我对这一行感到好奇:

$(product_calendar).attr({ value: newRemove_val });

您是否在某处创建了变量 product_calendar ,或者您的意思是:

$('input[name=product_calendar}').attr({ value: newRemove_val });

编辑 3:

查看完整的代码,原因是双重执行很清楚。您甚至在事件处理程序中添加了处理程序,这意味着每次都会添加另一个处理程序。

attr_val 无法正常工作的原因是它是作为其中的局部变量创建的。函数,然后在另一个函数中

添加模糊处理程序,并且它们仅在函数外部声明一次。

一些注意事项:

  • 您可以使用 val 函数而不是访问 。使用 attr 函数的 value 属性
  • $(this) 分配给 product_calendar 时,它是一个 jQuery 对象。您不必使用$(product_calendar)
  • 删除与完整值不匹配,因此您可以添加 122,然后删除 2 并得到 1 和 2

(这是一个虚拟文本,因为列表后面不能有代码块...)

// 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);
    }
  });

});

It doesn't. That is not possible.

So, there are some possible reasons that it might seem so:

  • The code that actually runs doesn't look like that. It might be an older version that is cached, or you are looking in the wrong file.

  • The code runs more than once, that way both execution branches may run. (Although I can't really see any possibility for that here.)

  • You are misinterpreting the result, and whatever you see that leads to the conclusion that both branches have to be executed, is in fact caused by some other code.

You could use a debugger to set breakpoints in the code. Set one breakpoint before the condition, and one in each branch. Then you will see if the code runs twice, once or not at all.

Edit:

The alerts that you added to the code shows that the event is actually called twice, and the first time the values are not what you think that they are.

Add some code to try to find out where the event is invoked from. Catch the event object by adding it to the function signature: .blur(function(e) {. Then you can use e.currentTarget to get the element that triggered the event, and display some attributes from it (like it's id) to identify it.

Edit 2:

I am curios about this line:

$(product_calendar).attr({ value: newRemove_val });

Do you create the variable product_calendar somewhere, or did you mean:

$('input[name=product_calendar}').attr({ value: newRemove_val });

Edit 3:

Seeing the complete code, the cause of the double execution is clear. You are adding even handlers inside an event handler, which means that another handler is added every time.

The reason for attr_val not working properly is because it's created as a local variable in one function, and then unsed in another function.

Add the blur handlers from start instead, and they occur only once. Declare the variable outside the function.

Some notes:

  • You can use the val function instead of accessing the value attribute using the attr function.
  • When you assign $(this) to product_calendar, it's a jQuery object. You don't have to use $(product_calendar).
  • The removal doesn't match complete values, so you can add 12 and 2, then remove 2 and you get 1 and 2 left.

(this is a dummy text, because you can't have a code block following a list...)

// 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);
    }
  });

});
我不在是我 2024-10-06 08:50:27

好吧,我想我现在明白了这个问题。

每次您将焦点放在 product_calendar 元素上时,都会对 #calendar_addRemove 元素执行 fadeIn 操作。每次执行fadeIn时,您都会使用其回调将new模糊处理程序绑定到calendar_addcalendar_remove元素。这意味着随着时间的推移,这些元素将具有多个模糊处理程序(全部执行相同的逻辑)。这不可能是您想要的。

在下面的脚本中,我取出了嵌套处理程序,以便它们仅与每个元素绑定一次。请注意:

  • product_calendar 在匿名函数的顶部声明(为 null),然后由 product_calendar 上的焦点处理程序进行更新代码> 元素。我认为这会导致正确的行为。

  • attr_val 在两个模糊处理程序中本地声明和分配。同样,我认为这会导致正确的行为:如果您要在模糊处理程序外部声明它(如声明product_calendar),那么您在访问它时可能会意外地使用旧值。

我仍然不确定这段代码到底应该如何运行,但这个脚本以我认为“合理”的方式执行。

(顺便说一句,生产代码可能应该允许输入字符串的开头和结尾有空格。)

    $(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);
        });
    });

OK, I think I understand the issue now.

Every time you do a focus on the product_calendar elements, you do a fadeIn on the #calendar_addRemove element. Every time you do that fadeIn, you use its callback to bind new blur handlers to the calendar_add and calendar_remove elements. That means that over time, those elements will have multiple blur handlers (all executing the same logic.) That can't be what you want.

In the script below, I've pulled out the nested handlers so that they're only bound once to each element. Note that:

  • product_calendar is declared (as null) at the top of the anonymous function, and then updated by the focus handler on the product_calendar element. I think this results in correct behavior.

  • attr_val is declared and assigned locally in both of the blur handlers. Again, I think this results in the correct behavior: If you were to declare it outside of the blur handlers (as product_calendar is declared), then you might accidentally use old values when you access it.

I'm still not sure exactly how this code is supposed to function, but this script performs in a way that I'd consider "reasonable".

(By the way, production code should probably allow for whitespace at the beginning and end of the input strings.)

    $(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);
        });
    });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文