Detener la propagación de eventos del mouse


239

¿Cuál es la forma más fácil de detener la propagación de eventos del mouse en Angular 2? ¿Debo pasar un $eventobjeto especial y llamarme a stopPropagation()mí mismo o hay alguna otra manera? Por ejemplo, en Meteor, simplemente puedo regresar falsedel controlador de eventos.

Respuestas:


235

Si desea poder agregar esto a cualquier elemento sin tener que copiar / pegar el mismo código una y otra vez, puede hacer una directiva para hacerlo. Es tan simple como a continuación:

import {Directive, HostListener} from "@angular/core";

@Directive({
    selector: "[click-stop-propagation]"
})
export class ClickStopPropagation
{
    @HostListener("click", ["$event"])
    public onClick(event: any): void
    {
        event.stopPropagation();
    }
}

Luego solo agrégalo al elemento en el que lo quieres:

<div click-stop-propagation>Stop Propagation</div>

55
A mi no me funciona. El evento de clic no se detiene :(
Diallo

99
no funciona para mí, si tengo el otro clic ... <button click-stop-propagation (click) = "test ($ event)"> test </button>
Bibby Chung

Trabajó para mi. Usando Angular 5.2.9
yarz-tech

1
Es posible que deba escuchar un evento de mouse diferente (es decir, mousedown, mouseup).
yohosuff

1
@yohosuff hace un buen punto. Agregue este método a la directiva: @HostListener("mousedown", ["$event"]) public onMousedown(event: any): void { event.stopPropagation(); }
andreisrob

253

Lo más simple es llamar a detener la propagación en un controlador de eventos. $eventfunciona igual en Angular 2, y contiene el evento en curso (mediante un clic del mouse, evento del mouse, etc.):

(click)="onEvent($event)"

en el controlador de eventos, podemos detener la propagación:

onEvent(event) {
   event.stopPropagation();
}

2
En mi directiva personalizada, no funciona. <button confirmMessage="are you sure?" (click)="delete()">Delete</button>, y en mi directiva: (click)="confirmAction($event)entonces confirmAction(event) { event.stopPropagation(); };
Saeed Neamati

44
Intenta volver falso también
Joshua Michael Waggoner

parece que para cuando manejas eventla función de controlador stopPropogation()no está disponible. Tuve que hacerlo bien en el marcado: `(click) =" foo (); $ event.stopPropogation () "
inorganik

Esto no funciona, al menos no cuando se coloca en el elemento de anclaje. La respuesta es incorrecta.
Shadow Wizard es Ear For You

143

Llamar stopPropagational evento evita la propagación: 

(event)="doSomething($event); $event.stopPropagation()"

Por preventDefaultsolo regresarfalse

(event)="doSomething($event); false"

No lo he probado, pero github.com/angular/angular/issues/4782 y github.com/angular/angular/pull/5892/files indican que debería funcionar. Sin ;embargo , no tienen el final. Voy a cambiar eso
Günter Zöchbauer

1
Están hablando de prevenir la acción predeterminada, no de pasar el evento a través de elementos primarios de lo que se trata stopPropagation.
Rem

Oh, ese es mi mal. Lo siento.
Günter Zöchbauer

2
volver false<3
Pawel Gorczynski

Es sorprendente cómo las respuestas incorrectas obtienen votos automáticos. El código simplemente no funciona.
Shadow Wizard es Ear For You

35

Agregando a la respuesta de @AndroidUniversity. En una sola línea puedes escribirlo así:

<component (click)="$event.stopPropagation()"></component>

No debería cambiar tanto de una versión a otra, ya que intentan mantener el estándar de plantillas html :)
dinigo

Funciona perfectamente con angular 5 también.
imans77

10

Si está en un método vinculado a un evento, simplemente devuelva falso:

@Component({
  (...)
  template: `
    <a href="https://stackoverflow.com/test.html" (click)="doSomething()">Test</a>
  `
})
export class MyComp {
  doSomething() {
    (...)
    return false;
  }
}

1
Se hace el trabajo para los eventos de clic. Al menos en la última versión de Angular2.
Jon

66
Devolver falsellamadas preventDefaultno stopPropagation.
Günter Zöchbauer

Llamar a return false detiene la propagación en el DOM. Verifique sus hechos @ GünterZöchbauer Se menciona en el ng-book.
moeabdol

3
@moeabdol un enlace al menos podría demostrar lo que reclamas, pero en realidad preventDefaultse llama. github.com/angular/angular/blob/… , github.com/angular/angular/blob/…
Günter Zöchbauer

1
¡Correcto! @ GünterZöchbauer Gracias por aclarar esto. Desearía poder compartir un enlace. Seguí el consejo de Nate Murray en su libro "ng-book The Complete Book on Angular 4" de regresar falso; al final de una función para detener la propagación de eventos en el DOM. Lo describe exactamente de la manera que mencionaste. Perdón por el malentendido.
moeabdol

8

Esto funcionó para mí:

mycomponent.component.ts:

action(event): void {
  event.stopPropagation();
}

mycomponent.component.html:

<button mat-icon-button (click)="action($event);false">Click me !<button/>

Esta solución funcionó para mí en angular 5 .. Gracias.
inbha

5

Tenía que hacerlo stopPropigationy preventDefaultpara evitar que un botón expandiera un elemento de acordeón sobre el que se encontraba.

Entonces...

@Component({
  template: `
    <button (click)="doSomething($event); false">Test</button>
  `
})
export class MyComponent {
  doSomething(e) {
    e.stopPropagation();
    // do other stuff...
  }
}

3

Nada funcionó para IE (Internet Explorer). Mis probadores pudieron romper mi modal haciendo clic en la ventana emergente en los botones detrás de él. Entonces, escuché un clic en mi div de pantalla modal y forcé a reenfocar un botón emergente.

<div class="modal-backscreen" (click)="modalOutsideClick($event)">
</div>


modalOutsideClick(event: any) {
   event.preventDefault()
   // handle IE click-through modal bug
   event.stopPropagation()
   setTimeout(() => {
      this.renderer.invokeElementMethod(this.myModal.nativeElement, 'focus')
   }, 100)
} 

3

solía

<... (click)="..;..; ..someOtherFunctions(mybesomevalue); $event.stopPropagation();" ...>...

en resumen, separe otras cosas / llamadas a funciones con ';' y agregue $ event.stopPropagation ()


2

Acabo de registrar una aplicación Angular 6, event.stopPropagation () funciona en un controlador de eventos sin siquiera pasar $ event

(click)="doSomething()"  // does not require to pass $event


doSomething(){
   // write any code here

   event.stopPropagation();
}

1

Deshabilitar enlace href con JavaScript

<a href="#" onclick="return yes_js_login();">link</a>

yes_js_login = function() {
     // Your code here
     return false;
}

Cómo debería funcionar también en TypeScript con Angular (Mi versión: 4.1.2)

Modelo
<a class="list-group-item list-group-item-action" (click)="employeesService.selectEmployeeFromList($event); false" [routerLinkActive]="['active']" [routerLink]="['/employees', 1]">
    RouterLink
</a>
Mecanografiado
public selectEmployeeFromList(e) {

    e.stopPropagation();
    e.preventDefault();

    console.log("This onClick method should prevent routerLink from executing.");

    return false;
}

¡Pero no deshabilita la ejecución de routerLink!


0

Agregar falso después de la función detendrá la propagación de eventos

<a (click)="foo(); false">click with stop propagation</a>

0

Esto resolvió mi problema, evitando que un evento sea disparado por un niño:

doSmth(){
  // what ever
}
        <div (click)="doSmth()">
            <div (click)="$event.stopPropagation()">
                <my-component></my-component>
            </div>
        </div>


0

Prueba esta directiva

@Directive({
    selector: '[stopPropagation]'
})
export class StopPropagationDirective implements OnInit, OnDestroy {
    @Input()
    private stopPropagation: string | string[];

    get element(): HTMLElement {
        return this.elementRef.nativeElement;
    }

    get events(): string[] {
        if (typeof this.stopPropagation === 'string') {
            return [this.stopPropagation];
        }
        return this.stopPropagation;
    }

    constructor(
        private elementRef: ElementRef
    ) { }

    onEvent = (event: Event) => {
        event.stopPropagation();
    }

    ngOnInit() {
        for (const event of this.events) {
            this.element.addEventListener(event, this.onEvent);
        }
    }

    ngOnDestroy() {
        for (const event of this.events) {
            this.element.removeEventListener(event, this.onEvent);
        }
    }
}

Uso

<input 
    type="text" 
    stopPropagation="input" />

<input 
    type="text" 
    [stopPropagation]="['input', 'click']" />
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.