简体   繁体   English

如何在WinJS ListView中手动触发oniteminvoked

[英]How to manually trigger oniteminvoked in a WinJS ListView

I've got a WinJS ListView that has its items created using a templating function (the itemTemplate option points to a function). 我有一个WinJS ListView,它的项目是使用模板函数创建的( itemTemplate选项指向一个函数)。 The returned item has a div inside it that has the win-interactive class so that it can accept input. 返回的项内部有一个div,该div中有win-interactive类,因此它可以接受输入。 Specifically, that div needs to be able to scroll to show more content that can fit on the ListView item. 具体来说,该div需要能够滚动以显示更多适合ListView项的内容。

The scrolling works perfectly with the win-interactive class applied to the div. 滚动与应用于div的win-interactive类完美配合。 The problem I'm trying to solve is allowing a normal click (mouse down, mouse up) to still trigger the oniteminvoked event on the ListView, while still allowing the div inside a ListView item to be scrolled. 我要解决的问题是允许正常单击(鼠标向下,鼠标向上)来触发ListView上的oniteminvoked事件,同时仍允许滚动ListView项内的div。

I figured this would be easy: I'd bind a click event listener to the div with the win-interactive class, and simple pass that click event up to another element on the ListView item, ensuring that eventually the oniteminvoked event would be trigger. 我认为这很容易:我将win-interactive类将click事件侦听器绑定到div,然后将click事件简单地传递到ListView项目的另一个元素,以确保最终触发oniteminvoked事件。

I've bound the click listener to the win-interactive div, and it's being triggered as expected. 我已经将点击侦听器绑定到win-interactive div,并且按预期触发了它。 However, and I cannot figure out how to trigger a click/item invocation on another part of the ListView item. 但是,我无法弄清楚如何在ListView项的另一部分触发单击/项调用。 I've tried using properties of the event (currentTarget) to get parent or sibling elements and triggering events on them, but I simply can't figure out how to trigger an event on an element like event.currentTarget . 我尝试使用事件的属性(currentTarget)来获取父元素或同级元素并在其上触发事件,但是我根本无法弄清楚如何在诸如event.currentTarget类的元素上触发事件。

tl;dr: How can I allow scrolling within a ListView item while still allowing a normal click to trigger the item invocation? tl; dr:如何允许在ListView项中滚动,同时仍允许正常单击触发项目调用?

Overall, the ListView just handles clicks by passing them to whatever itemInvoked handler you register for the control. 总的来说,ListView只是通过将点击传递给您为控件注册的itemInvoked处理程序来处理点击。 This means you should be able to just bypass that whole chain and invoke your handler directly with the appropriate item index, which is easy to obtain. 这意味着您应该能够绕开整个链,并使用易于获得的适当项目索引直接调用处理程序。

Within your item's click handler, if you have the ListView object handy, then list.currentItem will be the item with the focus (and obviously the one clicked), and its index property will be what normally gets passed to itemInvoked. 在项目的单击处理程序中,如果您有方便的ListView对象,则list.currentItem将是具有焦点的项目(显然是被单击的项目),其index属性通常是传递给itemInvoked的内容。 With this you can then call your itemInvoked handler directly, building up the appropriate event object, or you can separate your handler's code into another method and call that one instead. 然后,您可以直接调用itemInvoked处理程序,构建适当的事件对象,也可以将处理程序的代码分成另一个方法,然后调用该方法。

As a basic example, starting with a Grid app template project, I added win-interactive to the item-title element (which could by any other like your scrolling region) in pages/groupedItems/groupedItems.html: 作为一个基本示例,从Grid应用程序模板项目开始,我将win-interactive添加到pages / groupedItems / groupedItems.html中的item-title元素(也可能是其他类似滚动区域的元素):

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

In the ready method of pages/groupedItems/groupedItems.js, I attached the ListView's object to the page control for later use: 在pages / groupedItems / groupedItems.js的ready方法中,我将ListView的对象附加到页面控件以供以后使用:

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

And then hooked up click listeners to the item-title elements as below. 然后将单击侦听器连接到item-title元素,如下所示。 I'm doing it this way because the items are created through templates; 我这样做是因为项目是通过模板创建的。 if you have an item rendering function instead, then you can add the listeners in that piece of code directly. 如果您具有项目渲染功能,则可以直接在该代码段中添加侦听器。

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));
        }
    }
});

The implementation of _itemClick in my page control looks like this: 我的页面控件中的_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} })
},

where this._itemInvoked is the same handler that comes with the template. 其中this._itemInvoked是模板随附的同一处理程序。

Note that with win-interactive, you don't get the usual pointerDown/pointerUp behaviors for items that do the little down/up animations, so you might want to include those too if you deem it important (using WinJS.UI.Animation.pointerDown/pointerUp methods to do the effects). 请注意,使用win-interactive,对于执行向下/向上动画的项目,通常不会获得通常的pointerDown / pointerUp行为,因此,如果您认为它很重要,则可能也希望包含这些行为(使用WinJS.UI.Animation。使用pointerDown / pointerUp方法执行效果)。

Finally, it's probably possible to go up the chain from the e.currentTarget element inside _itemClick and simulate a click event on the appropriate parent, but I think that's more trouble than it's worth here having traced through the WinJS code that does all that. 最后,可能可以从_itemClick内的e.currentTarget元素上链并在适当的父对象上模拟click事件,但是我认为这比在WinJS代码中执行所有操作要麻烦得多。 Much more direct to just call your own itemInvoked. 直接调用自己的itemInvoked更为直接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM