问题由来

linkbutton 是 jQuery EasyUI 中常用的一个控件,可以使用它创建按钮。用法很简单,使用 a 标签给一个easyui-linkbutton 的class就可以了。

<a id="btn" class="easyui-linkbutton">这是一个按钮</a>

或者使用代码方式。

$("#btn").linkbutton();

实际使用时,经常会使用 jQuery 添加事件处理函数。例如

   $("#btn").click(function () {
alert("点击事件");
});

在使用过程中可能会需要暂时禁用这个按钮,easyui 已经提供了禁用按钮的方法 disable,使用方法也很简单

$(function(){
$("#btn").linkbutton(“disable”);
})

到这儿问题就来了,再点击一下,提示框照依然弹了出来,disable方法好像并没有什么效果

原因分析:不同的事件处理方式

在 DOM 中,存在着两类不同的事件处理方式,DOM0式和 DOM2 方式。

DOM0通过在HTML中设置属性,或者在JavaScript中设置一个对象的属性(property)的方法注册事件. 例如

var btn = document.getElementById("btn");
btn.onclick = function () {
alert("clicked");
};

取消事件注册,将 onclick 赋予为null 即可

btn.onclick = null;

DOM 2通过addEventListener()方法注册事件

var btn = document.getElementById("btn");
btn.addEventListener("click", function () {
alert("clicked");
}, false);

通过addEventListener添加的事件只能处理程序只能使用removeEventListener来移除,移除时传入的参数与添加处理程序时使用的参数相同,这也意味着通过addEventListener添加的匿名函数将无法移除

问题在于,这两种方式是各自独立处理的,互相并不影响。

由于 easyui 中使用了 DOM0 方式处理按钮的启用和禁用,而 jQuery 则使用 DOM2 方式进行事件的注册,所以之前的禁用失效了。

使用  DOM Level 0 方式,我们可以通过事件名称,方便地取得原来注册的事件处理函数,保存起来,以便以后回复。这正是 linkbutton 现在已经完成的。

解决方法:修复 linkbutton 的启用和禁用

修改的方式就是在原来的基础上,增加对于通过 DOM Level 2 方式注册的事件进行处理。检查是否注册了 jQuery 的 click 事件处理函数,如果有,在数据缓存对象上增加一个名为 savedHandlers 的数组来保存原来的点击事件处理函数,然后,从原来的对象上取消已经注册的事件处理函数。恢复的时候,检查数据对象上是否有保存的事件处理函数数组,如果存在,遍历这个数组,将这些事件处理函数重新注册到元素上。

function setButtonState(domElem, disabled) {                    // 设置按钮状态

    var data = $.data(domElem, "linkbutton");                   // 获取对象的数据
if (disabled) { // 禁用按钮
data.options.disabled = true;
var href = $(domElem).attr("href"); // 获取超级连接
if (href) {
data.href = href; // 保存原来的超级链接
$(domElem).attr("href", "javascript:void(0)"); // 重新设置
}
if (domElem.onclick) { // 是否有点击事件处理
data.onclick = domElem.onclick;
domElem.onclick = null; // 取消掉
}
var eventData = $(domElem).data("events") || $._data(domElem, 'events');
if (eventData && eventData["click"]) {
var clickHandlerObjects = eventData["click"];
data.savedHandlers = [];
for (var i = ; i < clickHandlerObjects.length; i++) {
if (clickHandlerObjects[i].namespace != "menu") {
var handler = clickHandlerObjects[i]["handler"];
$(domElem).unbind('click', handler);
data.savedHandlers.push(handler);
}
}
} $(domElem).addClass("l-btn-disabled"); // 使用样式
} else {
data.options.disabled = false; // 启用按钮
if (data.href) { // 恢复原来的超级链接
$(domElem).attr("href", data.href);
}
if (data.onclick) { // 恢复原来的点击事件处理
domElem.onclick = data.onclick;
}
if (data.savedHandlers) {
for (var i = ; i < data.savedHandlers.length; i++) {
$(domElem).click(data.savedHandlers[i]);
}
} $(domElem).removeClass("l-btn-disabled");
}
}

如果不想修改easyui的源代码,可以使用扩展方法来解决这个问题

/**
* linkbutton方法扩展
* @param {Object} jq
*/
$.extend($.fn.linkbutton.methods, {
/**
* 激活选项(覆盖重写)
* @param {Object} jq
*/
enable: function(jq){
return jq.each(function(){
var state = $.data(this, 'linkbutton');
if ($(this).hasClass('l-btn-disabled')) {
var itemData = state._eventsStore;
//恢复超链接
if (itemData.href) {
$(this).attr("href", itemData.href);
}
//回复点击事件
if (itemData.onclicks) {
for (var j = ; j < itemData.onclicks.length; j++) {
$(this).bind('click', itemData.onclicks[j]);
}
}
//设置target为null,清空存储的事件处理程序
itemData.target = null;
itemData.onclicks = [];
$(this).removeClass('l-btn-disabled');
}
});
},
/**
* 禁用选项(覆盖重写)
* @param {Object} jq
*/
disable: function(jq){
return jq.each(function(){
var state = $.data(this, 'linkbutton');
if (!state._eventsStore)
state._eventsStore = {};
if (!$(this).hasClass('l-btn-disabled')) {
var eventsStore = {};
eventsStore.target = this;
eventsStore.onclicks = [];
//处理超链接
var strHref = $(this).attr("href");
if (strHref) {
eventsStore.href = strHref;
$(this).attr("href", "javascript:void(0)");
}
//处理直接耦合绑定到onclick属性上的事件
var onclickStr = $(this).attr("onclick");
if (onclickStr && onclickStr != "") {
eventsStore.onclicks[eventsStore.onclicks.length] = new Function(onclickStr);
$(this).attr("onclick", "");
}
//处理使用jquery绑定的事件
var eventDatas = $(this).data("events") || $._data(this, 'events');
if (eventDatas["click"]) {
var eventData = eventDatas["click"];
for (var i = ; i < eventData.length; i++) {
if (eventData[i].namespace != "menu") {
eventsStore.onclicks[eventsStore.onclicks.length] = eventData[i]["handler"];
$(this).unbind('click', eventData[i]["handler"]);
i--;
}
}
}
state._eventsStore = eventsStore;
$(this).addClass('l-btn-disabled');
}
});
}
});

[js]jQuery EasyUI的linkbutton组件disable方法无法禁用jQuery绑定事件的问题分析的更多相关文章

  1. 第一百九十七节,jQuery EasyUI,LinkButton(按钮)组件

    jQuery EasyUI,LinkButton(按钮)组件 学习要点: 1.加载方式 2.属性列表 3.方法列表 本节课重点了解 EasyUI 中 LinkButton(按钮)组件的使用方法,这个组 ...

  2. jQuery EasyUI,LinkButton(按钮)组件

    转自:https://www.cnblogs.com/adc8868/p/6639570.html jQuery EasyUI,LinkButton(按钮)组件 学习要点: 1.加载方式 2.属性列表 ...

  3. JQuery EasyUI的常用组件

    jQuery EasyUI 是一个基于 jQuery 的框架,集成了各种用户界面插件,该框架提供了创建网页所需的一切,帮助您轻松建立站点. 注:本次介绍的JQuery EasyUI版本为1.5版. 一 ...

  4. jQuery EasyUI 的editor组件使用

    问题:最近在优化一个项目时,前端用到了 easyui这个插件来实现表格,搞了很久,才实现出一部分功能,但是还是有很多地方不熟悉,故记录一下,以后再研究 第一个实例------------------- ...

  5. jQuery delegate方法实现Ajax请求绑定事件不丢失

    给元素绑定click事件后 ,遇到一个问题:当执行一些ajax请求,再次调用此页面,里面的这个click事件就失效了 比如说:我的分页是一个ajax请求 但我点下一页时 后生成的元素a就没有了clic ...

  6. 从零开始学 Web 之 jQuery(五)操作元素其他属性,为元素绑定事件

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  7. 用live()方法给新增节点绑定事件

    jQuery 给所有匹配的元素附加一个事件处理函数,即使这个元素是以后再添加进来的也有效. 这个方法是基本是的 .bind() 方法的一个变体.使用 .bind() 时,选择器匹配的元素会附加一个事件 ...

  8. (Jquery)关于给动态加载的页面元素,绑定事件

    如果使用Jquery给元素绑定事件,一般会用bind,或者类似click函数来直接绑定. 但是对于动态生成的元素,会发现常规绑定无法生效,比如: <div class'div'></ ...

  9. Jquery EasyUI选项卡-Tabs的使用方法

    以下是easyUI的tabs的简单实用介绍. var e =$('#main').tabs('exists','accordion'); if(e==true){  $('#main').tabs(' ...

随机推荐

  1. mongodb集群部署

    一.安装Mongodb(Tarballs) 1.检查依赖文件包: yum install libcurl openssl 2.解压文件到/usr/local/ tar -zxvf mongodb-li ...

  2. java web复习(二)

    三.四种属性范围及应用 setAttribute(String name,Object o)设置属性 getAttribute(String name)根据属性名取得属性 removeAttribut ...

  3. Vsftpd服务重启、暂停命令

    VSFTP是一个基于GPL发布的类Unix系统上使用的FTP服务器软件,它的全称是Very Secure FTP 从此名称可以看出来,编制者的初衷是代码的安全. 在使用Vsftp服务是经常需要启动.停 ...

  4. IAR软件的使用

    STM32标准外设库下载 官网下载链接(需要ST账号登陆): http://www.st.com/content/st_com/en/products/embedded-software/mcus-e ...

  5. Nginx之 try_files 指令

    location / { try_files $uri $uri/ /index.php; } 当用户请求 http://localhost/example 时,这里的 $uri 就是 /exampl ...

  6. [SF] Symfony 在 console 中结合 Workerman

    在web框架的console中,命令不再是直接指定入口文件,如以往 php test.php start,而是类似 php app/console do 的形式. workerman 对命令的解析是 ...

  7. MySQL 8.0 中统计信息直方图的尝试

    直方图是表上某个字段在按照一定百分比和规律采样后的数据分布的一种描述,最重要的作用之一就是根据查询条件,预估符合条件的数据量,为sql执行计划的生成提供重要的依据在MySQL 8.0之前的版本中,My ...

  8. Google开源软负载seesaw

    https://github.com/google/seesaw ------------------------ 在分布式系统中,负载均衡是非常重要的环节,通过负载均衡将请求派发到网络中的一个或多个 ...

  9. Maven模块化开发

    Maven模块化开发 多人协同开发时,特别是规模较大的项目,为方便日后代码维护管理会将每个人的工作细分到具体的功能和模块上.随着项目的不断扩大,模块会越来越多,后续更加难以维护和扩展,为应对这种情况后 ...

  10. pandas,对dataFrame中某一个列的数据进行处理

    背景:dataFrame的数据,想对某一个列做逻辑处理,生成新的列,或覆盖原有列的值   下面例子中的df均为pandas.DataFrame()的数据   1.增加新列,或更改某列的值 df[&qu ...