如何使这个jquery函数更有效?

wil*_*fun 1 jquery

我有一个我正在玩的结账,每个项目的数量输入旁边都有一些向上和向下箭头.

我有一些重复的代码,它似乎没有效率.希望你能提供帮助.

每个项目看起来像这样(请原谅我现在的非标准符合item_id属性)

<div class="qty_ctrl_wrap">
  <input class="bag_qty" type="text" value="4" item_id="532" name="product_quantity">
  <div class="arrows">
    <div class="more"></div>
    <div class="less"></div>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

这是完整的jquery函数:

$('#checkout .arrows div').live('click',function(){

    var item_id = $(this).parent().prev('input').attr('item_id');
    var current_qty = $(this).parent().prev('input').val();

    if($(this).attr('class') == 'more') {

        var new_qty = parseInt(current_qty) + 1;

    } else {

        var new_qty = parseInt(current_qty) - 1;

    }

    // change the input on screen for visual reasons...
    $(this).parent().prev('input').val(new_qty);


    // submit the changes
        $.ajax({
        type: 'POST',
        url: '/backend/product_purchase_items.php',
        data: 'qty='+new_qty+'&item_id='+item_id,
        cache: false,
        success: function(data) {
          $('#product_purchase_items').html(data);
        }
        });     

});
Run Code Online (Sandbox Code Playgroud)

如你所见,我重复以下3次:

$(this).parent().prev('input')
Run Code Online (Sandbox Code Playgroud)

我一直在努力弄清楚如何把它放在变量中,所以我不必重复那段代码.

但除此之外,它的工作方式是,如果你按箭头3次,它会做3个单独的ajax帖子.理想情况下,在发送帖子之前会有一点暂停.

如何在提交帖子之前暂停300毫秒以查看箭头是否还有其他点击?

Fel*_*ing 5

您可以setTimeout用来去除事件:

$('#checkout .arrows div').live('click',function(){
    var $this = $(this),
        data = $this.data(),
        $item = $(this).parent().prev('input');


    if(data['debounce_timer']) {
        clearTimeout(data['debounce_timer']);
    }

    $item.val(function(i, value) {
        return +value + $this.hasClass('more') ? 1 : -1;
    });

    // Maybe you have to store a reference to the quantity (value) here. 
    // Otherwise you might get strange results when the arrow was just 
    // clicked again when the callback is executed.

    var timer = setTimeout(function() {
        $.ajax({
            type: 'POST',
            url: '/backend/product_purchase_items.php',
            data: {qty: $item.val(), item_id: $item.attr('item_id')}
            cache: false,
            success: function(data) {
              $('#product_purchase_items').html(data);
            }
        });    
    }, 150); // <-- try different times

    data['debounce_timer'] = timer;
});
Run Code Online (Sandbox Code Playgroud)

改变/应该考虑的事情:

  • $(this).parent().prev('input')在变量中缓存以便每次都不遍历DOM以再次找到相同的元素.

  • 将函数传递给.val() [docs]并一次更新值".

  • 使用一元+将字符串转换为数字,而不是parseInt.如果使用parseInt,则必须将基数作为第二个参数(在您的情况下10)传递,以防止JS 将带有前导零的数字解释为八进制数.

  • 使用.hasClass() [docs]而不是比较class属性.如果元素有多个类,则比较将失败.

  • 对象设置为data选项的值而不是字符串.这可确保数据正确编码.

  • 你真的应该使用HTML5数据属性而不是自定义属性(item_id).即使浏览器不支持HTML5(尚未),这也是更安全的方式.使用jQuery,您甚至可以通过该.data()方法访问它们.

  • 使用setTimeout [MDN]延迟Ajax调用并在.data() [docs]中存储对计时器ID的引用.快速执行处理程序时,将使用clearTimeout [MDN]取消先前的计时器,以防止过多的Ajax请求.