【问题标题】:JQuery UI; Stop propagation of selectable eventsjQuery 用户界面;停止可选事件的传播
【发布时间】:2009-11-12 22:51:13
【问题描述】:

基本上我在ul 上使用jQuery ui's selectable 功能,但是 ul 经常会有一个滚动条,并且这个滚动条在 Webkit 浏览器中变得无法使用,因为当您尝试单击它来抓取它时,套索用于可选功能被绘制在顶部。

我制定了一个解决方案,其中包括检查光标的位置相对于 ul 的位置和宽度,以查看光标是否在滚动条上,如果是,则停止传播可选择的“开始”事件, 但是尽管条件在应该满足的时候得到满足,但返回 false 或停止事件的传播似乎都不会阻止 jQuery 处理可选事件。

这是我为 jQuery .selectable start 事件准备的:

start: function(event, ui) {
    var t = event.target;
    var cutoff  = t.scrollWidth + t.offsetLeft
    if (event.clientX > cutoff)
    {
        console.log('NO!');
        console.log(event.type);

        //overkill
        event.stopPropagation();
        event.stopImmediatePropagation();

        if (event.stopPropagation) {
          event.stopPropagation();
        } else {
          event.cancelBubble = true;
        }

        return false;
    }
}

感谢所有建议/解决方案。

【问题讨论】:

  • 当您说“可选功能的套索被绘制在上方”时,您指的是什么套索?可以截图吗?

标签: javascript jquery jquery-ui jquery-events jquery-ui-selectable


【解决方案1】:

start 事件是一个狡猾的假事件。您需要做的是将取消事件冒泡的代码直接附加到ul 本身的mousedown 事件,并确保首先执行您的事件处理程序。

您将在event.stopPropagation 的 jQuery 文档中看到这条小线:

请注意,这不会阻止其他 同一元素上的处理程序 正在运行。

因此,虽然event.stopPropagation 将阻止事件在DOM 中进一步冒泡,但它不会阻止附加到被调用的ul 的其他事件处理程序。为此,您需要 event.stopImmediatePropagation 来停止调用 selectable 事件处理程序。

根据selectable demo page,这段代码sn -p成功取消了气泡:

$(function() {
    $("#selectable").mousedown(function (evt) {
        evt.stopImmediatePropagation();
        return false;
    });        
    $("#selectable").selectable();
});

请注意,您必须在执行.selectable() 设置函数之前将您的事件处理程序添加到ul 对象,以便首先潜入并弹出事件气泡。

【讨论】:

  • 很好的分析。注意return false 语句也将封装evt.stopPropagation()。 IOW 你不一定需要两者都做。
  • 非常感谢您的解决方案,现在您已经向我解释了 .selectable 事件结构的性质以及 stopProgation 和 stopImmediatePropagation 的正确用法,它非常有用!再次感谢!
  • 我已将此提交给 jQuery 错误跟踪器:dev.jqueryui.com/ticket/4441 希望他们会修复它。
  • 这有助于我在单击 n 拖动 jquery-ui 可调整大小的元素时阻止单击事件打开模式。谢谢!
【解决方案2】:

以下是 Sam C 的解决方案的一个细微变化,对我来说效果更好(只有在使用滚动条在元素上触发 mousedown 事件时才取消它):

$(function() {
    $("#selectable").mousedown(function (evt) {
        if ($(evt.originalEvent.target).hasClass('ui-dialog'))  // <--- variation
        {
            evt.stopImmediatePropagation();
            return false;
        }
        return true;
    });        
    $("#selectable").selectable();
});

【讨论】:

  • 您的意思可能是if ($(evt.originalEvent.target).hasClass('ui-selectable'))。这就是使用 tbody 作为容器对我有用的方法(tr 是被选中的对象)。
【解决方案3】:

Sam C 的回答对我不起作用,可能是因为我定位 #selectable 的方式。这是我用的:

$('#selectable')
  .mousedown(function (evt) {
    if (event.pageX > $(this).offset().left + $(this).width() - $.getScrollbarWidth())
    {
       evt.stopImmediatePropagation();
       return false;
    }
  })
  .selectable({filter: 'div'});

$.getScrollbarWidth() 来自here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多