Ответ 1
Скорее всего, JQuery вызывает синтетическое событие.
Вот фрагмент JQuery для отправки событий.
dispatch: function( nativeEvent ) {
// Make a writable jQuery.Event from the native event object
var event = jQuery.event.fix( nativeEvent );
var i, j, ret, matched, handleObj, handlerQueue,
args = new Array( arguments.length ),
handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {};
// Use the fix-ed jQuery.Event rather than the (read-only) native event
args[ 0 ] = event;
for ( i = 1; i < arguments.length; i++ ) {
args[ i ] = arguments[ i ];
}
event.delegateTarget = this;
// Call the preDispatch hook for the mapped type, and let it bail if desired
if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
return;
}
// Determine handlers
handlerQueue = jQuery.event.handlers.call( this, event, handlers );
// Run delegates first; they may want to stop propagation beneath us
i = 0;
while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
event.currentTarget = matched.elem;
j = 0;
while ( ( handleObj = matched.handlers[ j++ ] ) &&
!event.isImmediatePropagationStopped() ) {
// If the event is namespaced, then each handler is only invoked if it is
// specially universal or its namespaces are a superset of the event's.
if ( !event.rnamespace || handleObj.namespace === false ||
event.rnamespace.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
event.data = handleObj.data;
ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
handleObj.handler ).apply( matched.elem, args );
if ( ret !== undefined ) {
if ( ( event.result = ret ) === false ) {
event.preventDefault();
event.stopPropagation();
}
}
}
}
}
// Call the postDispatch hook for the mapped type
if ( special.postDispatch ) {
special.postDispatch.call( this, event );
}
return event.result;
}
Чтение спецификации для синтетических и аутентичных событий кликов:
Когда пользовательский агент должен выполнить шаги активации после щелчка для элемента, он должен запустить поведение активации, определенное для этого элемента, если оно есть. Поведение активации может относиться к событию щелчка, которое было вызвано шагами выше, приведшими к этой точке.
Поскольку в JQuery реализован пользовательский диспетчер диспетчеризации для эмуляции событий нажатия, похоже, что они добавили следующее для эмуляции вышеупомянутого собственного жизненного цикла html-события.
if ( special.postDispatch ) {
special.postDispatch.call( this, event );
}
Этот вызов, скорее всего, является подозрительным, что подтверждается, если вы посмотрите на вывод консоли для следующего. Обратите внимание, что вы никогда не увидите console.log Готово, потому что обработчик диспетчеризации никогда не возвращает событие, чтобы завершить его собственный жизненный цикл (бесконечная рекурсия), который, я подозреваю, просто откровенно лучше обрабатывается собственной реализацией html.
Предупреждение о бесконечном цикле
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<body>
<button>Click me</button>
<script>
$(document).ready(function() {
// line 1
$("button").click(function() {
console.log("start");
// line 2
$("button").click();
console.log("Done");
});
});
</script>
</body>