【问题标题】:How to manually trigger oniteminvoked in a WinJS ListView如何在 WinJS ListView 中手动触发 oniteminvoked
【发布时间】:2014-06-20 07:40:26
【问题描述】:

我有一个 WinJS ListView,它的项目是使用模板函数创建的(itemTemplate 选项指向一个函数)。返回的项目内部有一个 div,其中包含 win-interactive 类,以便它可以接受输入。具体来说,该 div 需要能够滚动以显示更多适合 ListView 项的内容。

滚动与应用于 div 的 win-interactive 类完美配合。我要解决的问题是允许正常单击(鼠标向下,鼠标向上)仍然触发 ListView 上的oniteminvoked 事件,同时仍然允许滚动 ListView 项内的 div。

我认为这很容易:我将单击事件侦听器绑定到具有 win-interactive 类的 div,然后将该单击事件简单地传递到 ListView 项上的另一个元素,确保最终 oniteminvoked事件将被触发。

我已将点击侦听器绑定到win-interactive div,它按预期触发。但是,我无法弄清楚如何在 ListView 项目的另一部分触发单击/项目调用。我尝试使用事件 (currentTarget) 的属性来获取父元素或兄弟元素并在它们上触发事件,但我根本不知道如何在像 event.currentTarget 这样的元素上触发事件。

tl;博士: 如何允许在 ListView 项目内滚动,同时仍允许正常单击来触发项目调用?

【问题讨论】:

    标签: javascript listview windows-store-apps winjs


    【解决方案1】:

    总的来说,ListView 只是通过将点击传递给您为控件注册的任何 itemInvoked 处理程序来处理点击。这意味着您应该能够绕过整个链并直接使用适当的项目索引调用您的处理程序,这很容易获得。

    在您的项目的单击处理程序中,如果您有方便的 ListView 对象,那么 list.currentItem 将是具有焦点的项目(显然是单击的项目),并且它的 index 属性通常会传递给 itemInvoked。这样,您就可以直接调用 itemInvoked 处理程序,构建适当的事件对象,或者您可以将处理程序的代码分离到另一个方法中,然后调用那个方法。

    作为一个基本示例,从一个 Grid 应用程序模板项目开始,我在 pages/groupedItems/groupedItems.html 中的 item-title 元素(可以是任何其他元素,例如您的滚动区域)中添加了 win-interactive:

    <h4 class="item-title win-interactive" data-win-bind="textContent: title"></h4>
    

    在pages/groupedItems/groupedItems.js的ready方法中,我将ListView的对象附加到了页面控件上,以备后用:

    var listElement = element.querySelector(".groupeditemslist");
    var list = listElement.winControl;
    this._list = list;
    

    然后将点击侦听器连接到 item-title 元素,如下所示。我这样做是因为项目是通过模板创建的;如果你有一个项目渲染函数,那么你可以直接在这段代码中添加监听器。

    var that = this;
    
    list.addEventListener("loadingstatechanged", function () {
        if (list.loadingState == "complete") {
            var interactives = element.getElementsByClassName("item-title");
    
            for (var i = 0; i < interactives.length; i++) {
                interactives[i].addEventListener("click", that._itemClick.bind(that));
            }
        }
    });
    

    我的页面控件中 _itemClick 的实现如下所示:

    _itemClick: function (e) {
        var item = this._list.currentItem;
    
        //Can also get the index this way
        var index = this._list.indexOfElement(e.currentTarget);
    
        this._itemInvoked({"detail" : { itemIndex : item.index} })
    },
    

    其中 this._itemInvoked 是模板附带的同一个处理程序。

    请注意,使用 win-interactive 时,您不会为执行小向下/向上动画的项目获得通常的 pointerDown/pointerUp 行为,因此如果您认为这很重要(使用 WinJS.UI .Animation.pointerDown/pointerUp 方法来做效果)。

    最后,有可能从 _itemClick 中的 e.currentTarget 元素沿链上移并在适当的父级上模拟单击事件,但我认为这比在这里跟踪完成所有工作的 WinJS 代码更麻烦那。更直接地调用您自己的 itemInvoked。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 2014-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多