簡體   English   中英

處理偵聽並觸發事件的元素/對象的最佳方法是什么?

[英]What is the best way to deal with elements/objects that listen AND trigger events?

昨天我問過類似的問題,但是經過一天的研究,我發現它過於復雜且不夠精確,因此我刪除了它。

因此,我在這里創建了另一個小提琴,該小提琴在大多數情況下應該是自我描述的。

在下面,您可以找到其中的HTML和JavaScript部分:

<select name="country">
    <option value="spain">Spain</option>
    <option value="sweden">Sweden</option>
    <option value="russia">Russia</option>
    <option value="canada">Canada</option>
</select>

<ul class="another-selector">
    <li data-value="spain">Spain</li>
    <li data-value="sweden">Sweden</li>
    <li data-value="russia">Russia</li>
    <li data-value="canada">Canda</li>
</ul>

承諾的Javascript在這里:

// Following function is called when 'country_changed' event is triggered
var country_changed = function(event, data) {
    $another_selector_items = $('.another-selector')
        .children();

    $another_selector_items
        .removeClass('selected');

    $another_selector_items.each(function(index, element) {
        var $element = $(element);
        if ($element.data('value') == data.country)
            $element.addClass('selected');
    });

    var $select = $('select[name=country]');
    $select
        .children()
        .removeAttr('selected')
        .prop('selected', false)
        .filter('[value=' + data.country + ']')
        .attr('selected', 'selected')
        .prop('selected', true);

    // ----------------------------------------
    // Uncomment this to get infinite recursion:
    // ----------------------------------------
    //$select.trigger('change');
};

// Register event bound to the document
// (so not attached to any particular element)
$(document)
    .on("country_changed", country_changed);


// Bind changing the
$('select[name=country]').on('change', function(event) {
    $.event.trigger('country_changed', {
        country: $(this).val()
    });
});

// Bind clicking on the LI to triggering the event 
$('.another-selector').on('click', 'li', function(event) {
    $.event.trigger('country_changed', {
        country: $(this).data('value')
    });
});

// Separate 'change' event binding --- required for 'pretty select' plugin
$('select[name=country]').on('change', function(event, data) {
    // ...
});

事實是,當元素同時是:事件的偵聽器和觸發相同事件的能力時,我不知道對這種情況最好的方法是什么。 因此,例如,從本地SELECT元素中選擇一個選項會導致事件觸發,並在其他列表上選擇適當的LI元素。 但是,由於該事件還必須處理相反的情況,因此它還會嘗試再次更新SELECT ,這是無用的,更糟糕​​的是,這會導致無限遞歸(希望被智能瀏覽器停止)。

嘗試在我的小提琴中取消注釋JavaScript代碼的#46行,以了解我在說什么。

因此,我正在尋找一種檢測事件從何處來,然后將其來源從可能的回調列表中排除的好方法。

或者-也許我正在嘗試使用錯誤的方法來解決問題? 也許我已經花了兩天沒有讀足夠的東西? ;)

如果可以,請你幫助我。

我將UI生成的事件與代碼觸發的事件分開。 另外,不需要自定義事件和SELECT上的2個change處理程序。 此外,也無需從您的自定義事件中重新觸發change事件。

我對您的問題的建議是:

$('select[name=country]').on('change', function(event) {
    var country = ... /* obtain country */

    selectContry(country);
});

$('.another-selector').on('click', 'li', function(event) {
    var country = ... /* obtain country */

    selectContry(country);
});

function selectContry(country) {
    // update view, e.g. SELECT and UL
    // ...

    // process new selection
    // ...
}

簡而言之:保持UI事件處理程序簡短(標識上下文,即與事件相關的數據)。 然后,處理程序應調用實用程序方法(如果需要,通過自定義事件),以更新視圖(如果需要)並處理數據。

如果需要更多事件,則不要(重新)觸發與現在新的情況相同的事件,程序狀態已更改,並且不同的事件(例如after_x )更合適。

如果漂亮的精選插件困擾您,請在更新視圖時執行以下任一操作:

  1. 調用:prettyselect插件的update方法: $('select[name=country]').prettyselect('update')
  2. select上觸發change.ps事件: $('select[name=country]').trigger('change.ps')

看一下源代碼 ,看看它們如何工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM