SP Widget window.onscroll

xiaix
Tera Guru

Can't seem to get window.onscroll to work in my Service Portal widget.

HTML:

<div style="display:none;" ng-init="setScrollListener()"></div>

Client:

$scope.setScrollListener = function() { window.onscroll = function() { console.info("scrolled"); }; };

Any ideas?

1 ACCEPTED SOLUTION

xiaix
Tera Guru

*UPDATED CODE* - June 28th, 2019

Figured it out.   Since it's a widget doing the work on a SP Page, "window" won't work.   <section> was the key.

Here's the working code:

HTML:

<div ng-init="setScrollListener()" id="{{version}}" class="scroll-top-wrapper" ng-click="topFunction()">
  <span class="scroll-top-inner">
    <i class="fa fa-2x fa-arrow-circle-up"></i>
  </span>
</div>

CLIENT:

function($scope, $timeout) {
	$scope.version = "scrollToTopBtn3";
	$scope.scrollFunction = function(e)	{
		if (e.scrollTop > 20 || document.documentElement.scrollTop > 20) {
			try{
				document.getElementById($scope.version).classList.add('show');
				$scope.$emit("ta_scrolling",e);
			}catch(e1){console.warn("595:" + e1.message);}
		} else {
			try{
				document.getElementById($scope.version).classList.remove('show');
			}catch(e2){console.warn("600:" + e2.message);}
		}
	};
	$scope.setScrollListener = function() {
		var section = document.getElementsByTagName('section')[0];
		if (section) {
			section.onscroll = function() {
				$scope.scrollFunction(section);
			};
		} else {console.warn("No section found from $scope.setScrollListener function");}
	};
	$scope.topFunction = function() {
		var section = document.getElementsByTagName('section')[0];
		if (section) {
			section.scrollTop = 0;
		} else {console.warn("No section found from $scope.topFunction function");}
	};
}

CSS:

.scroll-top-wrapper {
  opacity:0;
  width:50px;
  right:30px;
  height:50px;
  bottom:30px;
  color:#eee;
  padding-top:2px;
  z-index:99999999;
  line-height:48px;
  visibility:hidden;
  background-color:#777;
  transition:all .5s ease-in-out;
  -o-transition:all .5s ease-in-out;
  -ms-transition:all .5s ease-in-out;
  -moz-transition:all .5s ease-in-out;
  -webkit-transition:all .5s ease-in-out;
  border-radius:5px
}
.scroll-top-wrapper:hover {
  background-color:#888
}
.scroll-top-wrapper.show {
  visibility:visible;
  cursor:pointer;
  opacity:1
}
.scroll-top-wrapper i.fa {
  line-height:inherit
}
.cc_container,
.scroll-top-wrapper {
  position:fixed;
  overflow:hidden;
  text-align:center
}

View solution in original post

7 REPLIES 7

Rushit Patel2
Tera Guru

Hi David,



couple of things,



1)for this to work, make sure element on which you are triggering code as a scroll, if you want to observe main window scroll then do it on body tag.



2) do all DOM kind of code in link function of widget. its safe and best practise.



see below widget



find_real_file.png



(please mark helpful/like/correct if it helps)


xiaix
Tera Guru

*UPDATED CODE* - June 28th, 2019

Figured it out.   Since it's a widget doing the work on a SP Page, "window" won't work.   <section> was the key.

Here's the working code:

HTML:

<div ng-init="setScrollListener()" id="{{version}}" class="scroll-top-wrapper" ng-click="topFunction()">
  <span class="scroll-top-inner">
    <i class="fa fa-2x fa-arrow-circle-up"></i>
  </span>
</div>

CLIENT:

function($scope, $timeout) {
	$scope.version = "scrollToTopBtn3";
	$scope.scrollFunction = function(e)	{
		if (e.scrollTop > 20 || document.documentElement.scrollTop > 20) {
			try{
				document.getElementById($scope.version).classList.add('show');
				$scope.$emit("ta_scrolling",e);
			}catch(e1){console.warn("595:" + e1.message);}
		} else {
			try{
				document.getElementById($scope.version).classList.remove('show');
			}catch(e2){console.warn("600:" + e2.message);}
		}
	};
	$scope.setScrollListener = function() {
		var section = document.getElementsByTagName('section')[0];
		if (section) {
			section.onscroll = function() {
				$scope.scrollFunction(section);
			};
		} else {console.warn("No section found from $scope.setScrollListener function");}
	};
	$scope.topFunction = function() {
		var section = document.getElementsByTagName('section')[0];
		if (section) {
			section.scrollTop = 0;
		} else {console.warn("No section found from $scope.topFunction function");}
	};
}

CSS:

.scroll-top-wrapper {
  opacity:0;
  width:50px;
  right:30px;
  height:50px;
  bottom:30px;
  color:#eee;
  padding-top:2px;
  z-index:99999999;
  line-height:48px;
  visibility:hidden;
  background-color:#777;
  transition:all .5s ease-in-out;
  -o-transition:all .5s ease-in-out;
  -ms-transition:all .5s ease-in-out;
  -moz-transition:all .5s ease-in-out;
  -webkit-transition:all .5s ease-in-out;
  border-radius:5px
}
.scroll-top-wrapper:hover {
  background-color:#888
}
.scroll-top-wrapper.show {
  visibility:visible;
  cursor:pointer;
  opacity:1
}
.scroll-top-wrapper i.fa {
  line-height:inherit
}
.cc_container,
.scroll-top-wrapper {
  position:fixed;
  overflow:hidden;
  text-align:center
}

Trying to borrow your code here and unable to get it to work.  I'm trying to have the widget know when the window has been scrolled to the bottom.  Any idea what I'm missing?

 

This is at the top of my HTML:

<div class="hug-bottom" ng-init="setScrollListener()">

 

Client Script:

 

function ($http, $window, $scope, $document, spUtil) {	 
	var c = this;	
  $http.get(c.options.queue_url).then(function (response) {		
    if (response.data.result && response.data.result.length)
      angular.extend(c.data, response.data.result[0]);
    else
      angular.extend(c.data, response.data.result);
		
  })	
  c.open = function () {		
		console.log(spUtil.format(c.options.window.url, {sys_id: c.data.sys_id}), c.options.window.target, c.options.window.options)
    $window.open(spUtil.format(c.options.window.url, {sys_id: c.data.sys_id}), c.options.window.target, c.options.window.options);
  };

	$scope.setScrollListener = function()
       {
               var section = document.getElementsByTagName('section')[0];
               if (section)
               {
                      section.onscroll = function() {
                               $scope.scrollFunction(section);
                     };
               }
       };
       $scope.scrollFunction = function(e)
       {
              if (window.innerHeight + window.scrollY > e.body.clientHeight) {
            alert('bottom');
								//e.getElementById('hug-bottom').style.display='none';
        }

}
	
}

I think my IF statement is the issue:

 

       $scope.scrollFunction = function(e)
       {
              if (window.innerHeight + window.scrollY > e.body.clientHeight) {
            alert('bottom');
								//e.getElementById('hug-bottom').style.display='none';
        }