jquery - 如何让这个jquery函数更加高效?

标签 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>

这是完整的 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);
        }
        });     

});

如您所见,我将以下内容重复了 3 次:

$(this).parent().prev('input')

我一直在尝试找出如何将其放入变量中,这样我就不必重复该代码。

但除此之外,它的工作原理是,如果您点击箭头 3 次,它就会3 个单独的 ajax 帖子。理想情况下,在发送帖子之前会有轻微的停顿。

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

最佳答案

您可以使用 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;
});

已更改/应考虑的事项:

  • $(this).parent().prev('input') 缓存在变量中,以免每次都遍历 DOM 来查找相同元素再次

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

  • 使用一元 + 将字符串转换为数字,而不是 parseInt。如果您使用 parseInt,您必须将基数作为第二个参数传递(在您的情况下为 10),以防止 JS interpreting numbers with leading zeroes as octal numbers .

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

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

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

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

关于jquery - 如何让这个jquery函数更加高效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7169404/

相关文章:

jquery - SmartStore 风格的下拉列表

javascript - 如何在异步加载 Twitter 关注按钮时禁用屏幕名称

JQuery SerialScroll Tabs 底部边框问题

javascript - WordPress子菜单的子菜单下拉问题

javascript - 如何在 IE 兼容模式下居中 jquery 对话框?

Javascript查看另一个网站的html源代码

javascript - 在 Elixir 或 jQuery 中循环输入

javascript - 计数器在 jQuery 中不起作用

javascript - 如何在加载时检查数字或选中的复选框?

php - 电子邮件未从表单插入 mysql 数据库