如何发送触发事件并知道它是否被任何收件人取消/消费?

时间:2014-06-06 08:47:05

标签: javascript jquery

我正在构建一个自定义导航系统,其中锚链接作为data-url =属性存储在父项中。这样整个项目都是可点击的(以及其他功能)。

我需要这些子项的默认行为来正常处理链接(即更改window.location)。

问:我如何向trigger收件人发回消息,消息已被消费,因此不进行“正常处理”或者可能只是你如何得到触发器传递的事件对象?

示例JSFiddle:http://jsfiddle.net/TrueBlueAussie/dXkbW/6/

// Construct the test structure
var $panel = $('.panel');
var $items = $panel.find('li:has(a)');
$items.each(function () {
    var $item = $(this);
    $item.addClass('item');
    var $a = $item.find('a[href]');
    $item.attr('data-url', $a.attr('href')).attr('data-target', $a.attr('target'));
    $a.contents().unwrap();
});

// Test click handler
$panel.on('click', '.item', function(e){
    var $this = $(this);
    //alert($this.attr('data-url'));
    $this.trigger('navigate', [$this.attr('data-url'), $this.attr('data-target')]);

    // Q: How to know if a receiving item consumed the click???
    if ("some test goes here"){
        // Navigate like normal link
        window.location = $this.attr('data-url');
    }
});

// Test parent control click handler
// e.g. only wants events targetted at ".content"
$(document).on('navigate', function(e, url, target){
    alert(" url='" + url + "' target= \'" + target + "'");
    // Process .content targetted links here and not at source
    if (target == '.content'){
        e.preventDefault();   // or something else?
    }
});

示例HTML

<div class="panel">
    <ul>
        <li> <a href="link1.html" target=".content">Link1</a>

        </li>
        <li> <a href="link2.html" target=".other1">Link1</a>

        </li>
    </ul>
</div>
<div class="panel">
    <ul>
        <li> <a href="link3.html" target=".content">Link1</a>

        </li>
        <li> <a href="link4.html" target=".other1">Link1</a>

        </li>
    </ul>
</div>
<div class="content"></div>
<div class="other"></div>

我想使用像e.preventdefault()这样的标准内容,但是如何从trigger调用的地方访问事件对象?

1 个答案:

答案 0 :(得分:0)

文档......唉!

实际上它实际上相当简单,但仅在此页http://api.jquery.com/category/events/event-object/而非trigger参考页面上提及:

&#34;自己创建一个事件对象并将其传递给触发器!&#34; :)

var e = jQuery.Event( "navigate" );
$this.trigger(e, [$this.attr('data-url'), $this.attr('data-target')]);

if (e.isDefaultPrevented()) {
    // Someone prevented the default event!
    alert('Prevented!');
}
else
{
    alert('Navigated!');
    // Navigate like normal link
    //window.location = $this.attr('data-url');
}

改进版本:

您也可以简单地扩展jQuery事件对象(而不是传递参数)。

var e = jQuery.Event( "navigate", {url: $this.attr('data-url'), navtarget: $this.attr('data-target')} );
$this.trigger(e);

并改为引用自定义事件参数:

$(document).on('navigate', function (e) {
    alert(" url='" + e.url + "' target= \'" + e.navtarget + "'");
    // Process .content targetted links here and not at source
    if (e.navtarget == '.content') {
        e.preventDefault(); // or something else?
    }
});

好多了,现在看起来像内置。你只需要避免使用任何现有的属性名称(在我意识到它是现有的,相当重要的属性之前,我使用target作为自定义):)