knockoutjs单击和双击

bde*_*dev 15 jquery knockout.js

我希望能够将单击和双击事件绑定到一个文本范围.我知道我可以使用

data-bind ="event: { dblclick: doSomething }
Run Code Online (Sandbox Code Playgroud)

双击,但我还需要能够单击执行不同的功能.有什么建议?

mad*_*kay 24

<div data-bind="singleClick: clicked, event : { dblclick: double }">
    Click Me
</div>
Run Code Online (Sandbox Code Playgroud)

这将过滤掉也是双击的单击.

ko.bindingHandlers.singleClick= {
    init: function(element, valueAccessor) {
        var handler = valueAccessor(),
            delay = 200,
            clickTimeout = false;

        $(element).click(function() {
            if(clickTimeout !== false) {
                clearTimeout(clickTimeout);
                clickTimeout = false;
            } else {        
                clickTimeout = setTimeout(function() {
                    clickTimeout = false;
                    handler();
                }, delay);
            }
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

是一个演示.


小智 12

上面的答案非常有用,但没有给出我认为OP之后的确切解决方案:一个简单的Knockout绑定,允许独占的单击和双击事件.我知道这篇文章是一年前发布的,但我今天在找同样的事情时发现了这篇文章,所以如果这个答案对其他人有用的话我会发帖.

以下示例似乎符合OP的要求,可能会节省一些时间(免责声明:有限的跨浏览器测试).JSFiddle:http://jsfiddle.net/UxRNy/

此外,还有一些问题,你是否应该首先使用它(移动浏览器,减慢页面,可访问性等) - 但这是另一篇文章(例如https://ux.stackexchange.com/questions/7400 /应-双击-避式的Web应用程序)

示例视图用法:

<div data-bind="singleOrDoubleClick: { click: singleClick, dblclick: doubleClick }">
    Click or double click me...
</div>
Run Code Online (Sandbox Code Playgroud)

捆绑:

ko.bindingHandlers.singleOrDoubleClick= {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var singleHandler   = valueAccessor().click,
            doubleHandler   = valueAccessor().dblclick,
            delay           = valueAccessor().delay || 200,
            clicks          = 0;

        $(element).click(function(event) {
            clicks++;
            if (clicks === 1) {
                setTimeout(function() {
                    if( clicks === 1 ) {
                        // Call the single click handler - passing viewModel as this 'this' object
                        // you may want to pass 'this' explicitly
                        if (singleHandler !== undefined) { 
                            singleHandler.call(viewModel, bindingContext.$data, event); 
                        }
                    } else {
                        // Call the double click handler - passing viewModel as this 'this' object
                        // you may want to pass 'this' explicitly
                        if (doubleHandler !== undefined) { 
                            doubleHandler.call(viewModel, bindingContext.$data, event); 
                        }
                    }
                    clicks = 0;
                }, delay);
            }
        });
    }
};
Run Code Online (Sandbox Code Playgroud)

上面的例子和上面的例子组合在一起:https://gist.github.com/ncr/399624 - 我刚刚合并了两个解决方案.


Mor*_*rio 5

@madcapnmckay提供了一个很好的答案,下面是一个使用相同想法提供双击的修改版本.通过使用最新版本的knockout,vm作为上下文传递给处理程序.这可以通过单击同时工作.

<div data-bind="doubleClick: clicked">
    Double click Me
</div>
Run Code Online (Sandbox Code Playgroud)

-

ko.bindingHandlers.doubleClick= {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var handler = valueAccessor(),
            delay = 200,
            clickTimeout = false;

        $(element).click(function() {
            if(clickTimeout !== false) {
                handler.call(viewModel);
                clickTimeout = false;
            } else {        
                clickTimeout = setTimeout(function() {
                    clickTimeout = false;
                }, delay);
            }
        });
    }
};
Run Code Online (Sandbox Code Playgroud)


And*_*кин 4

click首先,我根本不建议绑定。相反,您应该使用jQuery 中的"click"和处理程序:"dblclick"

$(someParentElement).on('click', 'your span selector', function (event) {
    var myViewModelFragment = ko.dataFor(this);
    // your code here
});

$(someParentElement).on('dblclick', 'your span selector', function (event) {
    var myViewModelFragment = ko.dataFor(this);
    // your code here
});
Run Code Online (Sandbox Code Playgroud)

编辑:另请参阅Niko关于支持单击和双击的建议。基本上,您应该手动计算点击次数并相应地调用不同的函数。我以为 jQuery 会为你处理这个问题,但不幸的是,它没有。

  • @Andrew - 我不会说史蒂夫推荐这个。他为你提供了两方面的工具。然而,他不鼓励使用内联函数类型。我接受你所说的关于处理程序数量的内容。然而,您的技术的缺点是它破坏了视图模型和视图之间的关注点分离。我会提出第三种方式。当项目是单数时使用 click 并编写可以放置在父 dom 元素上的自定义 **委托** 绑定。这样我们就能两全其美并保持分离。 (8认同)
  • 你为什么不推荐呢? (3认同)
  • 我不投反对票的唯一原因是它是基于旧版本的淘汰赛。如果 jquery 可用,较新的版本实际上默认使用 jquery 事件。还有一个设置可以将系统切换到本机事件。 (2认同)