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.

Movimiento rápido del ojo
fuente

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>
dnc253
fuente
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();
}
Universidad angular
fuente
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"
Günter Zöchbauer
fuente
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>
dinigo
fuente
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;
  }
}
Thierry Templier
fuente
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/>
Brahim JDIDOU
fuente
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...
  }
}
BrandonReid
fuente
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)
} 
PatrickW
fuente
3

solía

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

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

Ray Dragon
fuente
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();
}
Dipendu Paul
fuente
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!

Javan R.
fuente
0

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

<a (click)="foo(); false">click with stop propagation</a>
Fabian Rios
fuente
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>

JulianRot
fuente
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']" />
David Alsh
fuente