如何在Material Design Lite中将事件附加到表格复选框

4
当您创建MDL表时,其中一个选项是应用'class=mdl-data-table--selectable'类。当MDL渲染表格时,会在指定列的左侧插入一个额外的列,其中包含复选框,允许您选择特定行以执行操作。对于我的应用程序,我需要能够在人员选中或取消选中复选框时处理一些JavaScript。到目前为止,我无法做到这一点。
问题在于您不直接指定复选框控件,它们是在MDL升级整个表格时插入的。对于其他MDL组件,例如按钮,我可以在按钮本身上放置onclick事件,因为我正在使用HTML按钮标记指定它。
尝试将onclick放在用于呈现复选框的各种容器对象和跨度上已经失败。我附加的事件似乎没有触发。我最接近的方法是将事件附加到TR,然后遍历复选框以评估它们的状态。
以下是由MDL为单个复选框单元格生成的标记:
<td>
    <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect mdl-data-table__select mdl-js-ripple-effect--ignore-events is-upgraded" data-upgraded=",MaterialCheckbox">
        <input type="checkbox" class="mdl-checkbox__input">
            <span class="mdl-checkbox__focus-helper"></span>
            <span class="mdl-checkbox__box-outline">
                <span class="mdl-checkbox__tick-outline"></span>
            </span>
            <span class="mdl-checkbox__ripple-container mdl-js-ripple-effect mdl-ripple--center">
                <span class="mdl-ripple"></span>
            </span>
    </label>
</td>

这些标记都不是由我指定的,因此我不能仅仅向标记添加onclick属性。

是否有事件链可以挂钩?我想按照程序员的意图来完成它。

3个回答

4

这不是最好的代码,但MDL也不是最好的库。实际上,它相当丑陋。

那么,现在关于我的代码:该代码将绑定在源自具有类mdl-checkbox的元素的文档根上的单击事件上。

第一个问题:事件会触发两次。为此,我使用了Underscore.js / David Walsh的一段代码,它会在单击时防抖动函数调用(如果函数在250ms间隔内执行多次,则只调用一次)。

第二个问题:点击事件发生在MDL更新选择框的is-checked类之前,但我们可以假设自上次以来单击已更改复选框的状态,因此在大多数情况下,在单击时否定hasClass是确定选中状态的一个很好的方法。

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
}

$(document).on("click", ".mdl-checkbox", debounce(function (e) {
    var isChecked = !$(this).hasClass("is-checked");
    console.log(isChecked);
}, 250, true));

希望它有所帮助 ;)

2
优秀的代码 - krummens
我认为50毫秒是一个不错的猜测,当点击速度快于250毫秒(这是可行的)时,它将无法注册最新状态。使用50毫秒似乎效果更好。 - Riël

1
我们目前没有直接解决这个问题的方法。我们正在考虑添加V1.1事件,可以通过Issue 1210进行订阅。请记住,只需使用右侧栏中的按钮订阅该问题。我们不需要一堆+1和其他无效的评论飞来飞去。
一种方法是将事件绑定到表格本身,监听任何“更改”事件。然后,您可以从事件的目标向上移动链以获取表格行,然后从那里获取所需的数据。

1
你可以将变化事件委托给包含的表单。
例如:
var form = document.querySelector('form');
form.addEventListener('change', function(e) { 
    if (!e.target.tagName === 'input' || 
         e.target.getAttribute('type') !== 'checkbox') { 
       return;
    }
    console.log("checked?" + e.target.checked);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接