Как я могу предотвратить дефолт перед запуском прокси-события?

Задача та же, что и в этом сообщении: захватить щелчок по ссылка и предотвратить поведение браузера по умолчанию. Ответ там был такой:

Шаблон:

<a on-click='sayHello' href="#">Activate!</button>

JS:

ractive.on( 'sayHello', function ( event ) {
  event.original.preventDefault();
  alert( 'Hello world!' );
});

Проблема в том, что обработчик события sayHello не должен знать, каким было исходное событие. Весь смысл проксирования в том, что обработчик события не должен заботиться о типе исходного события. Например, меняю ссылку на кнопку, preventDefault больше не нужно.

Итак, мой вопрос заключается в том, как я могу вызвать preventDefault до или после запуска прокси-сервера события.

Хорошим решением было бы запустить несколько прокси событий подряд (если это возможно):

Шаблон:

<a on-click='preventDefault;sayHello' href="#">Activate!</button>

Js:

ractive.on( 'preventDefault', function ( event ) {
  event.original.preventDefault();
});
ractive.on( 'sayHello', function ( event ) {
  alert( 'Hello world!' );
});

Это возможно как-то? Или есть другое красивое решение?


person Bernát    schedule 10.02.2014    source источник


Ответы (3)


Одним из подходов может быть передача аргумента, определяющего, следует ли предотвращать использование по умолчанию:

шаблон:

<a on-click='sayHello:true' href="#">Activate!</a>
<button on-click='sayHello'>Activate!</button>

код:

ractive.on( 'sayHello', function ( event, shouldPreventDefault ) {
  if ( shouldPreventDefault ) {
    event.original.preventDefault();
  }
  alert( 'Hello world!' );
});

Или, если вы хотите избежать логической ловушки вы могли бы сделать...

<a on-click='sayHello:{preventDefault:true}' href="#">Activate!</a>

... и так далее.

Цепочка событий — интересная идея. Я не уверен, что он принадлежит библиотеке, но вы, безусловно, можете сделать что-то вроде

шаблон:

<a on-click='multiple:["preventDefault","sayHello"]' href='#'>Activate!</a>

код:

ractive.on( 'multiple', function ( event, sequence ) {
  var eventName, i, len;

  len = sequence.length;
  for ( i = 0; i < len; i += 1 ) {
    this.fire( sequence[i], event );
  }
});

Этот шаблон можно расширить, включив аргументы, если это необходимо.

person Rich Harris    schedule 21.02.2014
comment
sequence.shift повлияет на фактическую последовательность, указанную в атрибуте, т. е. при втором запуске события последовательность будет пустой. Чтобы избежать этой проблемы, вам нужно перебирать список, не очищая его (например, использовать цикл for) - person tnajdek; 28.04.2014

Я решил это таким образом, но я не полностью удовлетворен.

Шаблон:

<a on-click='pd_and:sayHello' href="#">Activate!</button>

Js:

ractive.on( 'pd_and', function ( event, next ) {
  event.original.preventDefault();
  var i = args.indexOf(':'), arg;
  if (i === -1) {
    type = next;
    arg = undefined;
  } else {
    type = next.substr(0, i);
    arg = next.substr(i + 1);
  }
  return ractive.fire(type, event, arg);

});
person Bernát    schedule 10.02.2014

Если ваша цель состоит в том, чтобы инкапсулировать preventDefault между шаблоном и методом, вы можете свернуть свое собственное прокси-событие:

Ractive.events.clickpd = function ( node, fire ) {
    node.addEventListener('click', click)

    function click(e){
        e.preventDefault()
        fire({ 
           node: node,  //breaks Ractive if not included
           original: e  //optional
        })
    }
    return { 
        teardown: function () {
            node.removeEventListener('click', click)
        } 
    }
}

И используйте его так:

<a on-clickpd='sayGreeting'>{{greeting}}</a>

Полный пример см. на http://jsfiddle.net/ka2Pu/2/.

Документы по пользовательским событиям находятся здесь: http://docs.ractivejs.org/latest/ractive-events< /а>

person martypdx    schedule 11.02.2014