1

我在 Knockout.js 中有一个事件,只要元素中存在类data-bind="click: ...",我就会尝试禁用它。disabled

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

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

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

在线复制

我更喜欢通过使用类名来实现,因为这样我可以处理元素的样式以及与站点中多个元素的交互。

4

5 回答 5

2

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

鉴于您正在使用淘汰赛,执行此操作的“正确”方法是让视图模型处理所有内容,而不是依赖外部的东西,例如 jQuery,以防止点击发生。

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

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

然后,您只需更新disabledobservable 以启用/禁用点击处理程序。您还可以利用这个 observable 对应该禁用的元素应用不同的样式,例如添加禁用的样式,而不是使用样式来控制淘汰行为。

于 2015-12-17T15:36:26.680 回答
1

我可以想到几种方法来处理这个要求。

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

我还在这里分叉了你的 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());
}
于 2015-12-17T15:50:52.670 回答
0

这是控制元素样式的方法,并让回调将样式考虑在内。如果你有 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>

于 2015-12-17T16:08:30.067 回答
0

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

a:disabled {
    color: red;
}

您还可以检查敲除函数中的禁用类(不推荐,仅作为示例)。像这样http://jsfiddle.net/mCxjz/81/

于 2015-12-17T15:40:30.933 回答
-2

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

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

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

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

于 2015-12-17T15:47:14.387 回答