最近遇到的一个 Web 项目,页面上需要用类似 toggle 的开关。由于整个前端是用 bootstrap 搭建起来的,我选择了用 bootstrap-switch 做这个开关。
样子大概如上图所示。
想要的功能呢,就是当它在 on 的时候,就把对应的设置项打开,当它在 off 的时候,就把对应的设置项关闭。
所以,每次前端改变了这个 switch 的值,就得向服务器发送 Ajax 请求,做相应的事情,如果成功,则开关切换是正确的;如果失败,则开关切换是错误的,要回滚。
由于 bootstrap-switch 的一些示例页面是 https 的,但又引入了 http 的静态资源(css/js/img),所以网上很多示例页面没法直接查看,只能下载下来在本地查看。我后来找到了一个能看的方法:
把它的代码 clone 到本地,浏览器打开 doc 目录
以下是在 stackoverflow 找到的可以把 Ajax 加进去的代码:
$("input.switch-input").on('change.bootstrapSwitch', function(e){
if($(this).is(':checked'))
alert('checked');
else
alert('not checked');
//code..
$.ajax({
//code..
success: function(result) {
if(result['done'] == true) {
alert('Status changed successfully.');
} else {
alert('Error:'+result['message']);
if(stopchange === false){
stopchange = true;
$(this).bootstrapSwitch('toggleState');
stopchange = false;
}
}
},
error: function(result) {
alert('Error! Unable to update progress.');
if(stopchange === false){
stopchange = true;
$(this).bootstrapSwitch('toggleState');
stopchange = false;
}
}
});
});
但它其实有一个问题,当它回滚的时候,使用了 $(this).bootstrapSwitch('toggleState')
,满足 on('change.bootstrapSwitch')
会触发它自身逻辑,进入死循环。
根据它的文档,应该使用 setState
设置状态,并且传入第三个参数为 true
,这样不会触发 change.bootstrapSwitch
。
尝试此法,报错。继续寻找,终于又在 stackoverflow 找到了一个写法
$('#myswitch').bootstrapSwitch('state', !data, true);
使用的是 state
而不是 setState
。
另外,如果遇到了 Uncaught TypeError: Cannot read property 'ownerDocument' of undefined
这个错误,可能是 ES6 里面的箭头函数(例如 bootstrap 库里面)写法与 $ 符号有冲突,可以在一开始写个
_this = $(this)
在后面都用 _this 就好。
现在妥了。