Angular 2 how to keep event from triggering digest loop/detection cycle?

You can detach the change detector to prevent change detection to be invoked for a component

constructor(private cdRef:ChangeDetectorRef) {}
foo() {

1) One interesting solution might be overriding EventManager


import { Injectable, Inject, NgZone  } from '@angular/core';
import { EVENT_MANAGER_PLUGINS, EventManager } from '@angular/platform-browser';

export class CustomEventManager extends EventManager {
  constructor(@Inject(EVENT_MANAGER_PLUGINS) plugins: any[], private zone: NgZone) {
    super(plugins, zone); 

  addEventListener(element: HTMLElement, eventName: string, handler: Function): Function {
    if(eventName.endsWith('out-zone')) {
      eventName = eventName.split('.')[0];
      return => 
          super.addEventListener(element, eventName, handler));

    return super.addEventListener(element, eventName, handler);


  providers: [
    { provide: EventManager, useClass: CustomEventManager }
export class AppModule {


<h1 (click.out-zone)="test()">Click outside ng zone</h1>

<div (dragover.out-zone)="onDragOver($event)">

Plunker Example

So with solution above you can use one of these options to prevent default behavior and run event outside angular zone:


2) One more solution provided by Rob Wormald is using blacklist for Zonejs


/// <reference types='zone.js/dist/zone.js' />

const BLACKLISTED_ZONE_EVENTS: string[] = [

export const blacklistZone = Zone.current.fork({
  name: 'blacklist',
  onScheduleTask: (delegate: ZoneDelegate, current: Zone, target: Zone,
                   task: Task): Task => {

    // Blacklist scroll, mouse, and request animation frame events.
    if (task.type === 'eventTask' &&
            (name) => task.source.indexOf(name) > -1)) {

      // Schedule task in root zone, note Zone.root != target,
      // "target" Zone is Angular. Scheduling a task within Zone.root will
      // prevent the infinite digest cycle from appearing.
      return Zone.root.scheduleTask(task);
    } else {
      return delegate.scheduleTask(target, task);


import {blacklistZone} from './blacklist' => {

Plunker with blacklist


5.0.0-beta.7 (2017-09-13)

fix(platform-browser): run BLACK_LISTED_EVENTS outside of ngZone





Update 2

Angular cli includes template for disabling parts of macroTask/DomEvents patch.

Just open


You can find there the following code

 * By default, zone.js will patch all possible macroTask and DomEvents
 * user can disable parts of macroTask/DomEvents patch by setting following flags

 // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
 // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
 // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
 * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
 * with the following flag, it will bypass `zone.js` patch for IE/Edge
// (window as any).__Zone_enable_cross_context_check = true;

See also: