web-dev-qa-db-ja.com

ウィンドウのinnerWidthサイズの変更に関するAngularJSイベント

私は、ウィンドウの内側の幅のサイズの変化を見る方法を探しています。私は次を試してみましたが、うまくいきませんでした:

$scope.$watch('window.innerWidth', function() {
     console.log(window.innerWidth);
});

助言がありますか?

63
Liad Livnat

JQueryでできます:

$(window).resize(function(){
    alert(window.innerWidth);

    $scope.$apply(function(){
       //do something to update current scope based on the new innerWidth and let angular update the view.
    });
});

recreated(ng-repeatスコープ、ディレクティブスコープなど)の可能性があるスコープ内でイベントハンドラーをバインドする場合、バインドを解除する必要があることに注意してくださいスコープが破棄されたときのイベントハンドラー。これを行わないと、スコープが再作成される(コントローラーが再実行される)たびに、さらに1つのハンドラーが追加され、予期しない動作とリークが発生します。

この場合、接続されているハンドラーを識別する必要があります。

  $(window).on("resize.doResize", function (){
      alert(window.innerWidth);

      $scope.$apply(function(){
          //do something to update current scope based on the new innerWidth and let angular update the view.
      });
  });

  $scope.$on("$destroy",function (){
      $(window).off("resize.doResize"); //remove the handler added earlier
  });

この例では、jQueryの event namespace を使用しています。要件に応じて異なる方法で実行できます。

改善:イベントハンドラーの処理に少し時間がかかる場合、ユーザーがウィンドウのサイズを変更し続け、イベントハンドラーが何回も実行される場合、throttling関数を考慮することができます。 アンダースコア を使用する場合、次を試すことができます。

$(window).on("resize.doResize", _.throttle(function (){
    alert(window.innerWidth);

    $scope.$apply(function(){
        //do something to update current scope based on the new innerWidth and let angular update the view.
    });
},100));

または関数のデバウンス

$(window).on("resize.doResize", _.debounce(function (){
     alert(window.innerWidth);

     $scope.$apply(function(){
         //do something to update current scope based on the new innerWidth and let angular update the view.
     });
},100));

関数の調整とデバウンスの違い

142
Khanh TO

jQueryの必要はありません!この簡単なスニペットは、私にとってはうまく機能します。 angular.element() を使用して、ウィンドウのサイズ変更イベントをバインドします。

/**
 * Window resize event handling
 */
angular.element($window).on('resize', function () {
    console.log($window.innerWidth);
});    

バインド解除イベント

/**
 * Window resize unbind event      
 */
angular.element($window).off('resize');
40
lin

私はここで役立つかもしれないjfiddleを見つけました: http://jsfiddle.net/jaredwilli/SfJ8c/

これを簡単にするためにコードをリファクタリングしました。

// In your controller
var w = angular.element($window);
$scope.$watch(
  function () {
    return $window.innerWidth;
  },
  function (value) {
    $scope.windowWidth = value;
  },
  true
);

w.bind('resize', function(){
  $scope.$apply();
});

その後、htmlからwindowWidthを参照できます

<span ng-bind="windowWidth"></span>
23
chris31389

Khanh TOのソリューションがUIの問題を引き起こした場合(私にとってのように)、$timeoutを使用して、500ミリ秒間変更されない限り属性を更新しないようにしてください。

var oldWidth = window.innerWidth;
$(window).on('resize.doResize', function () {
    var newWidth = window.innerWidth,
        updateStuffTimer;

    if (newWidth !== oldWidth) {
        $timeout.cancel(updateStuffTimer);
    }

    updateStuffTimer = $timeout(function() {
         updateStuff(newWidth); // Update the attribute based on window.innerWidth
    }, 500);
});

$scope.$on('$destroy',function (){
    $(window).off('resize.doResize'); // remove the handler added earlier
});

参照: https://Gist.github.com/tommaitland/7579618

9
rgpass