0

This might be a newbie question. What I want to do iswatch if a particular element has custom scrollbar I want to change the width of its parent.This works perfectly if I wrap in setInterval as it will be checking all the time for changes, but I am concerned about performance. How this could be implemented more elegantly in jQuery or even Angularjs?

(function($) {
  $.fn.hasScrollBar = function() {
    return this.get(0).scrollHeight > this.height();
  }
})(jQuery);
   if ($('#tab-content-3').hasScrollBar()) {
      $('#basics md-content').css('width', '95%');
   } else {
      $('#basics md-content').css('width', '100%');
   }
AT82
  • 71,416
  • 24
  • 140
  • 167
funguy
  • 2,072
  • 7
  • 30
  • 41
  • Using percentage-based width to account for a scroll-bar is not going to be a very robust, even without considering the fact you're using `setInterval()` – Patrick Roberts Jun 08 '17 at 05:09
  • What events can cause this scrollbar to appear ? Is the element resizable ? editable ? something else ? Are you just looking for when the user zooms the page (thus causing content to take more place) ? For this later you can listen for the `resize` event. For the formers, it will depend on how is implemented the trigger, but every event should be more or less listenable. – Kaiido Jun 08 '17 at 05:25

1 Answers1

0

You can make use of MutationObserver. This is supported is most of the modern browsers and there is a fallback for old browsers.

Have a look at below example and various configuration supported by MutationObserver. I would suggest using MutationObserver with attributes change configuration so that performance impact will be minimal.

MDN MutationObserver

Example Tutorial by Google

Similar Stackoverflow Answer

Underscore.js's throttle

You can use it along with underscore.js's throttle method to increase performance.

Community
  • 1
  • 1
Sivasankar
  • 753
  • 8
  • 22
  • 4
    This answer could be improved with a basic example of usage. As it is now, it only serves to answer how to find the answer. – Patrick Roberts Jun 08 '17 at 05:14
  • MutationObserver has performance impact. Using throttle might not help much as it is an inbuilt function – Rajesh Jun 08 '17 at 05:18
  • 2
    @Rajesh MutationObserver has *much* less performance impact than `setInterval()`. Using the options object to refine what types of mutations it responds to improves its performance even moreso, but in general, having an event-based approach is much preferable to a polling-based approach. – Patrick Roberts Jun 08 '17 at 05:21
  • I'm curious as to how you'll find that a scrollbar appeared with MutationObserver. This is not an DOM change. – Kaiido Jun 08 '17 at 05:22
  • @Rajesh @Kaiido Yes, but `MutationObserver` also supports different configurations. So in this case, using only `attributes` change wouldn't be a problem I think. – Sivasankar Jun 08 '17 at 05:22
  • @Kaiido I think listening to attribute changes and content changes would be sufficient, as that would encompass all CSS and content-length changes that would determine whether a scrollbar appears or not. – Patrick Roberts Jun 08 '17 at 05:23
  • @PatrickRoberts I just didn't want to add duplicate code. So I added links to examples. Thanks :) – Sivasankar Jun 08 '17 at 05:23
  • @PatrickRoberts I never knew `setInterval` has performance impact. Can you share any reference links please? I'll look myself meanwhile – Rajesh Jun 08 '17 at 05:24
  • @PatrickRoberts, I don't think it would no... Resizing an element won't change any of its attributes, except if you do it through its `style` attribute, but then, just catch the line of js who did it and trigger your check at this moment. – Kaiido Jun 08 '17 at 05:27
  • @Rajesh polling-based approaches are just poor in general. Because the causality of updates is not directly linked to when the scrollbar appears or disappears, there is typically a small flicker that results as a side-effect, and depending on how often you poll (whether every 30 milliseconds or every second), you're trading off between CPU time and therefore battery life on mobile devices, and responsiveness. But using an event-based approach is better because you're not sacrificing unnecessary CPU time to run the function when not needed, and you'll avoid the flicker artifact as well. – Patrick Roberts Jun 08 '17 at 05:27
  • @PatrickRoberts just FYI, I'm not promoting pooling based approach. MutationObserver is the correct method, but since OP is looking not to loose performance, we should also highlight few techniques that would help in reducing impact, like you suggested using *options object*. – Rajesh Jun 08 '17 at 05:29