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

preventDefault() `click` in Knockout.js 3

我在 Knockout.js 中有一个 data-bind="click: ..." 事件,我试图在元素中存在 disabled class 时禁用它。

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

我正在尝试这个但没有成功:

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

Reproduction online

我更喜欢使用 classname 来实现,因为这样我可以处理元素的样式以及网站中多个元素与它的交互。

这里的问题是无法保证哪个点击处理程序会先 运行。在这种情况下,敲除点击绑定在 jquery 处理程序之前执行。

鉴于您正在使用敲除,"proper" 方法是让视图模型处理所有事情,而不是依赖外部的东西,例如 jQuery,以防止发生点击。

在您的情况下,视图模型可能如下所示:

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

然后您只需将 disabled observable 更新为 enable/disable 点击处理程序。您还可以利用此可观察对象将不同的样式应用于应禁用的元素,例如添加禁用样式,而不是使用样式来控制淘汰行为。

您应该使用 disabled attr 来禁用该元素。您可以使用以下方法处理视觉样式:

a:disabled {
    color: red;
}

也可以,勾选knockout函数里面的disable class(不推荐,举个例子)。像这样http://jsfiddle.net/mCxjz/81/

我更新了您的代码以满足您的要求。我从 jQuery 中了解到,执行 .click 只会将更多事件绑定到 elem。以下代码的作用是覆盖现有的点击处理程序。

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

如果您想取回旧功能,可以将其保存在 var 中,稍后重新分配。希望这有帮助。

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

我可以为您想出几种方法来满足您的需求。

我在这个工作示例中添加了一些选项供您查看:http://plnkr.co/edit/t1jG3JmsywxteRyNNKS4?p=preview

我也在这里 fork 你的 JSFiddle http://jsfiddle.net/8pa84cmu/1/

<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());
}

以下是您如何控制元素的样式,并让回调考虑该样式。如果你有 20 个元素想要一起设置样式,你将为每个元素使用相同的 observable。这个例子制作了三个可点击的 span,并在 2.5 秒后禁用它们。您可以看到样式更改。

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>