简体   繁体   English

Knockout.js中的preventDefault()`click` 3

[英]preventDefault() `click` in Knockout.js 3

I have a data-bind="click: ..." event in Knockout.js and I'm trying to disable it whenever a disabled class is presence in the element. 我在Knockout.js中有一个data-bind="click: ..."事件,并且每当元素中存在disabled类时,我都试图将其disabled

<span class="disabled" data-bind="click: alerting">Two</span>

I'm trying this without success: 我正在尝试不成功:

$('.disabled').click(function(e){
    e.preventDefault();
});

Reproduction online 在线复制

I prefer to do it by using a classname as this way I can handle both the styling of the element and the interaction with it for multiple elements in the site. 我更喜欢使用类名来完成此操作,因为这样我就可以处理元素的样式以及网站中多个元素的交互。

The issue here is that there's no guarantee as to which click handler is going to run first. 这里的问题是,不能保证首先运行哪个单击处理程序。 In this case, the knockout click binding is executing before the jquery handler. 在这种情况下,敲除单击绑定是在jquery处理程序之前执行的。

Given that you're working with knockout, the "proper" way to do this would be for the viewmodel to handle everything, and not rely on something external, such as jQuery, to prevent the click from happening. 鉴于您正在使用剔除法,执行此操作的“正确”方法是让ViewModel处理所有内容,而不要依赖外部内容(例如jQuery)来防止发生点击。

In your case, the viewmodel might look like this: 在您的情况下,viewmodel可能如下所示:

var viewModel = {
    disabled: ko.observable(false),
    alerting: function(data, e) {
       if (!this.disabled())
           alert("two");
    }
};

You then just update the disabled observable to enable/disable the click handler. 然后,您只需更新disabled可观察对象即可启用/禁用点击处理程序。 You could also make use of this observable to apply different styling to elements that should be disabled, eg adding the disabled style, rather than using the style to control the knockout behaviour. 您也可以利用此观察值对应禁用的元素应用不同的样式,例如添加禁用的样式,而不是使用该样式来控制敲除行为。

There's a few ways I could think of for you to deal with this requirement. 我有几种方法可以帮助您解决此要求。

I've put a few options in this working example for you to look at: http://plnkr.co/edit/t1jG3JmsywxteRyNNKS4?p=preview . 我在这个工作示例中提供了一些选项供您查看: http : //plnkr.co/edit/t1jG3JmsywxteRyNNKS4?p=preview

I've also forked your JSFiddle here http://jsfiddle.net/8pa84cmu/1/ 我也在这里http://jsfiddle.net/8pa84cmu/1/分叉了您的JSFiddle

<p>Option 1 - Applying the disabled class, leave button clickable but check for class in click handler and do nothing</p>
<button class="disabled" data-bind="click: RegisterClick">Click</button>
<hr/>
<p>Option 2 - An enabled button doing what the click handler asks</p>
<button class="enabled" data-bind="click: RegisterClick">Click</button>
<hr/>
<p>Option 3 - A binding using a boolean to apply the class name if required and disabling it if required</p>
<button data-bind="click: RegisterClick, css: { disabled }, disable: disabled">Click</button>
<hr/>
<p>Option 4 - A binding just dealing with enabling / disabling</p>
<button data-bind="click: RegisterClick, enable: IsEnabled">Click</button>
var ViewModel = function() {
  this.RegisterClick = function(model, event) {
    if (event.target.className === "disabled") {
      return;
    }

    console.log("Clicked");
  }

  this.disabled = true;
  this.IsEnabled = false;
}

window.onload = function() {
  ko.applyBindings(new ViewModel());
}

You should use disabled attr to disable the element. 您应该使用disabled attr禁用元素。 You can deal with visual styling using this: 您可以使用以下方法处理视觉样式:

a:disabled {
    color: red;
}

You can also, check the disable class inside knockout's function (not recommend, just an example). 您也可以检查敲除功能中的禁用类(不推荐,仅举一个例子)。 Like this http://jsfiddle.net/mCxjz/81/ 像这样http://jsfiddle.net/mCxjz/81/

Here is how you would control styling of an element, and have a callback take that styling into account. 这是您如何控制元素的样式,并进行回调以考虑该样式的方式。 If you had 20 elements that you wanted to style together, you would use the same observable for each of them. 如果您有20个元素想要一起设置样式,则将对每个元素使用相同的可观察值。 This example makes three clickable spans, and disables them after 2.5 seconds. 本示例制作三个可单击的范围,并在2.5秒后禁用它们。 You can see the styling change. 您可以看到样式更改。

 var viewModel = { isDisabled: ko.observable(false), alerting: function(data, event) { if ($(event.target).hasClass('disabled')) return; alert(event.target.innerHTML); } }; ko.applyBindings(viewModel); setTimeout(function () { viewModel.isDisabled(true); }, 2500); 
 .clickable { border-radius: 5px; padding: 5px; background-color: lightgreen; cursor: pointer; } .disabled { background-color: lightgray; cursor: not-allowed; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <span class="clickable" data-bind="click: alerting, disabled: isDisabled, css: {disabled: isDisabled}">One</span> <span class="clickable" data-bind="click: alerting, disabled: isDisabled, css: {disabled: isDisabled}">Two</span> <span class="clickable" data-bind="click: alerting, disabled: isDisabled, css: {disabled: isDisabled}">Three</span> 

I updated to your code to fit your requirements. 我更新了您的代码以符合您的要求。 What I understand from jQuery is that executing .click only binds more events to the elem. 我从jQuery了解到的是,执行.click仅会将更多事件绑定到elem。 What the following code does is it overrides the exiting click handler. 以下代码的作用是覆盖现有的单击处理程序。

$._data($(elem)[0], 'events').click[0].handler = function() {return;}

Should you want to get back your old function, probably save it in a var and reassign it later. 如果您想找回旧功能,可以将其保存在var中,然后再重新分配。 Hope this helps. 希望这可以帮助。

http://jsfiddle.net/mCxjz/84/ http://jsfiddle.net/mCxjz/84/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM