@@ -475,6 +475,9 @@ export class MatSlider extends _MatSliderMixinBase
475
475
return ( this . _dir && this . _dir . value == 'rtl' ) ? 'rtl' : 'ltr' ;
476
476
}
477
477
478
+ /** Keeps track of the last pointer event that was captured by the slider. */
479
+ private _lastPointerEvent : MouseEvent | TouchEvent | null ;
480
+
478
481
constructor ( elementRef : ElementRef ,
479
482
private _focusMonitor : FocusMonitor ,
480
483
private _changeDetectorRef : ChangeDetectorRef ,
@@ -513,6 +516,7 @@ export class MatSlider extends _MatSliderMixinBase
513
516
const element = this . _elementRef . nativeElement ;
514
517
element . removeEventListener ( 'mousedown' , this . _pointerDown , activeEventOptions ) ;
515
518
element . removeEventListener ( 'touchstart' , this . _pointerDown , activeEventOptions ) ;
519
+ this . _lastPointerEvent = null ;
516
520
this . _removeGlobalEvents ( ) ;
517
521
this . _focusMonitor . stopMonitoring ( this . _elementRef ) ;
518
522
this . _dirChangeSubscription . unsubscribe ( ) ;
@@ -611,6 +615,7 @@ export class MatSlider extends _MatSliderMixinBase
611
615
const oldValue = this . value ;
612
616
const pointerPosition = getPointerPositionOnPage ( event ) ;
613
617
this . _isSliding = true ;
618
+ this . _lastPointerEvent = event ;
614
619
event . preventDefault ( ) ;
615
620
this . _focusHostElement ( ) ;
616
621
this . _onMouseenter ( ) ; // Simulate mouseenter in case this is a mobile device.
@@ -637,6 +642,7 @@ export class MatSlider extends _MatSliderMixinBase
637
642
// Prevent the slide from selecting anything else.
638
643
event . preventDefault ( ) ;
639
644
const oldValue = this . value ;
645
+ this . _lastPointerEvent = event ;
640
646
this . _updateValueFromPosition ( getPointerPositionOnPage ( event ) ) ;
641
647
642
648
// Native range elements always emit `input` events when the value changed while sliding.
@@ -654,7 +660,7 @@ export class MatSlider extends _MatSliderMixinBase
654
660
655
661
event . preventDefault ( ) ;
656
662
this . _removeGlobalEvents ( ) ;
657
- this . _valueOnSlideStart = this . _pointerPositionOnStart = null ;
663
+ this . _valueOnSlideStart = this . _pointerPositionOnStart = this . _lastPointerEvent = null ;
658
664
this . _isSliding = false ;
659
665
660
666
if ( this . _valueOnSlideStart != this . value && ! this . disabled &&
@@ -665,6 +671,15 @@ export class MatSlider extends _MatSliderMixinBase
665
671
}
666
672
}
667
673
674
+ /** Called when the window has lost focus. */
675
+ private _windowBlur = ( ) => {
676
+ // If the window is blurred while dragging we need to stop dragging because the
677
+ // browser won't dispatch the `mouseup` and `touchend` events anymore.
678
+ if ( this . _lastPointerEvent ) {
679
+ this . _pointerUp ( this . _lastPointerEvent ) ;
680
+ }
681
+ }
682
+
668
683
/**
669
684
* Binds our global move and end events. They're bound at the document level and only while
670
685
* dragging so that the user doesn't have to keep their pointer exactly over the slider
@@ -683,6 +698,9 @@ export class MatSlider extends _MatSliderMixinBase
683
698
body . addEventListener ( 'touchcancel' , this . _pointerUp , activeEventOptions ) ;
684
699
}
685
700
}
701
+ if ( typeof window !== 'undefined' && window ) {
702
+ window . addEventListener ( 'blur' , this . _windowBlur ) ;
703
+ }
686
704
}
687
705
688
706
/** Removes any global event listeners that we may have added. */
@@ -695,6 +713,9 @@ export class MatSlider extends _MatSliderMixinBase
695
713
body . removeEventListener ( 'touchend' , this . _pointerUp , activeEventOptions ) ;
696
714
body . removeEventListener ( 'touchcancel' , this . _pointerUp , activeEventOptions ) ;
697
715
}
716
+ if ( typeof window !== 'undefined' && window ) {
717
+ window . removeEventListener ( 'blur' , this . _windowBlur ) ;
718
+ }
698
719
}
699
720
700
721
/** Increments the slider by the given number of steps (negative number decrements). */
0 commit comments