在Knockout.js中使用preventDefault()`click` 3

时间:2022-12-12 18:59:25

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:...”事件,并且每当禁用的类存在于元素中时我都会尝试禁用它。

<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.

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

5 个解决方案

#1


2  

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. 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.

然后,您只需更新已禁用的observable以启用/禁用单击处理程序。您还可以使用此observable将不同的样式应用于应禁用的元素,例如添加禁用样式,而不是使用样式来控制挖空行为。

#2


1  

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/

我也在这里分叉你的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());
}

#3


0  

You should use disabled attr to disable the element. You can deal with visual styling using this:

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

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/

你也可以检查一下knockout功能中的禁用类(不推荐,只是一个例子)。喜欢这个http://jsfiddle.net/mCxjz/81/

#4


0  

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. This example makes three clickable spans, and disables them after 2.5 seconds. You can see the styling change.

以下是控制元素样式的方法,并将回调考虑到样式。如果您想要将20个元素组合在一起,则可以为每个元素使用相同的observable。此示例生成三个可单击的跨度,并在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>

#5


-2  

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. What the following code does is it overrides the exiting click handler.

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

$._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. Hope this helps.

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

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

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

#1


2  

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. 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.

然后,您只需更新已禁用的observable以启用/禁用单击处理程序。您还可以使用此observable将不同的样式应用于应禁用的元素,例如添加禁用样式,而不是使用样式来控制挖空行为。

#2


1  

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/

我也在这里分叉你的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());
}

#3


0  

You should use disabled attr to disable the element. You can deal with visual styling using this:

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

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/

你也可以检查一下knockout功能中的禁用类(不推荐,只是一个例子)。喜欢这个http://jsfiddle.net/mCxjz/81/

#4


0  

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. This example makes three clickable spans, and disables them after 2.5 seconds. You can see the styling change.

以下是控制元素样式的方法,并将回调考虑到样式。如果您想要将20个元素组合在一起,则可以为每个元素使用相同的observable。此示例生成三个可单击的跨度,并在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>

#5


-2  

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. What the following code does is it overrides the exiting click handler.

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

$._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. Hope this helps.

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

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

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