Investr gives a company personalized weighted SCORE based on company's last 3 years' and last 5 quarters' fundamental performance. It also highlights, with green and blue bands, companies that are trading at attractive valuations. Investr also reports whether or not a company's top-line and bottom-line growth is consistent and if a company is trading above or below its 30 day moving average. All this information is supported via beautiful and intuitive charts.
InvestR was created to answer the following 3 questions:
- Is a particular company, fundamentally better than another?
- How are the current valuations of that company?
- Can we trust the company's growth consistency and buy the company at current market price?
Investr helps you "narrow your focus" so that you can focus on few good companies for a further detailed investigation.
Why should you use it?
We all differ from each other when it comes to deciding which fundamental parameter is more important than others. Some people prefer stocks with high growth and high PE while others prefer stocks with low PE and high dividend yield. Investr lets you assign weightages to the parameters of your choice so that you can discover "your type" of companies.
Investr comes with 3 pre-defined settings: "Growth", "Value" and "Fixed Income". Users who want full control can use "Advanced Options".
Not just valuation setting, every aspect of InvestR is customizable. Users can set the range parameters for the green and blue bands, tolerance limits for the various searches and more by changes the values in the Settings page ().
Investr tracks more than 600 companies that account for 97% of total Indian market capitalization. Apart from getting names of the companies with highest (and lowest) scores, you can search Investr to find the ratings and valuations of your favorite company. You can sort companies by their PE (Price to Earning ratio), PEG (PE to Growth ratio) and Div Yield (Dividend Yield). Searching for companies on Investr is ridiculously fast. You can search for companies by their name, NSE ticker, sector or sub-sector. You can create a "Watchlist" of your favorite companies and search for them. You can also filter in the highlighted companies by searching for "/green", "/blue" or "/all" (without quotes but / included).
The tab labeled "Optimized" with a next to it, scores companies using optimized weights. If you want to have a look at fundamentally strong companies without setting your personal weight preferences, then we suggest that you use the optimized weights. We use optimized weights tab 90% of the time.
We have added lots of tooltips across InvestR to provide quick help. These help tooltips can be disabled in the settings page ().
How is the score calculated?
The scores are calculated in 3 steps. In the first step YoY, QoQ and TTM growth in fundamental parameters like total income, net profit, earnings per share, profit margin and dividend yield is plotted on a bell curve and given points.
In the second step, points given in the first step are weighed based on the weights given by the user for each fundamental parameter. And in the third and final step, a percentage score is calculated based on the total weighted points and maximum weighted points that are possible.
Optimized scores use predefined weights.
Sign In
Signing in will give users access to 690+ companies. After signing in you can also access your setting customization and watchlist across devices making your customization portable. Signed in users can also opt in to receive an email when stocks in their watchlist trade below their 30 day moving average. Signed in users will also be able to click on the and make it beat! When a user clicks on the heart we feel loved for the effort that we have put in creating this tool! NOTE: We hate spam just as much as you do, so you will not receive any email from InvestR unless you opt in for it.
How frequently is the data updated?
Data on Investr is updated multiple times a day. The name of the latest quarter that is included in the calculations is mentioned besides the company's name. (Note: Stock prices on Investr are NOT live.)
We understand that accurate data is extremely important for making decisions in equity investing. We take great care in making sure that the data on Investr is accurate. At the same time, it is difficult for a single individual to verify all the details of more than 600 companies. Please bring any data anomalies that you find to my notice.
Note: If a company has reduced its face value and split its shares in the middle of the financial year, then it might lead to inconsistent dividend yield calculation.
Disclaimer
This is the part where we say, information provided on this site is purely to draw your attention towards companies that need further detailed personal investigation and this site does not give "tips" for buying and selling stocks.
Donate
If InvestR has helped you in making a buy or sell decision or more importantly if InvestR has helped you in making money then you can always show your support by sending an Amazon Gift Card to yourmailid@yourmailprovider.com!


Types:
Copper-bearing IUD
-
Most effective
-
copper = toxic to ovum and spurm
-
effective immediately after insertion
-
works primarily by inhibiting fertilisation
-
fitted within first 5 days (120hrs) following first UPSI or within 5 days of earliest estimated date of ovulation
-
no evidence for LNG-IUS
-
failure \<1%
-
side effects
- pain
-
contraindications
-
same as cuIUD
-
NOT
-
risk STI
-
previous ectopic pregnancy
-
age
-
nulliparity
-
-
Levonorgestrel
-
unclear MOA
-
inhibition of ovulation
-
prevent follicle rupture or luteal dysfunction
-
can inhibit ovulation for 5-7 days
- sperm degenerated
-
closer to ovulation LNG given then less effective
-
not effective once fertilisation occured
-
pregnancies not affected by LNG failure
-
-
1.5mg single oral dose
-
licensed for use wihtin 72hrs
- may be effective up to 96hrs
-
failure = \~2%
-
obese women using LNG greater risk of pregnancy
- ?double dose
-
Concommitant use of liver enzyme can reduce efficacy
- double dose
-
quickstart contraceptive
-
7 day rule
-
pregnancy test in ≤3/52
-
side effects
-
headache
-
nausea
-
\<20%
-
if vomits \<2hrs after taking should take another dose ASAP
-
-
altered bleeding patterns
- expect bleeding within 7/7 of expected time
Contraindications
-
nil
- including breast feeding
Use >1 in cycle
-
repeated doses may be effective
-
further UPSI may be indication
Drug interactions
-
inducers: decrease contraceptive efficacy of LNG
- up to 28d after use
-
CuIUD
-
single 3mg dose amy be administered (outside product licence)
- no evidence to support this
Ulipristal acetate
-
Progesterone receptor hormone
-
inhibition or delay of ovulation
-
licensed for use 120hrs
When indicated
-
luteal phase (ovulation -> menstruation) = 14d (fairly constant)
-
follicular phase more variable
COC
-
if pills missed Wk 1 and UPSI or barrier failure in W1 or pill-free interval
-
if pill free interval emergency IUD considered up to 15d after taking 21st pill in last packet
POP
-
late or missed pill
-
UPSI before efficacy re-established (48hours)
-
IUD only up to 5d after UPSI
Depot
- Late injectio (>14w)
IUD
-
removal without immediate replacement
-
in 5 days prior to removal, perforation, partial or complete expulsion


Amnesty™ Hypercube is also available as a free downloadable application: a complete desktop platform solution for running web widgets outside of your browser. And if you're a Sidebar or Dashboard user, you can push your web widgets into those environments with one click.
We'll be rolling out a new version soon that fully integrates with your Hypercube widgets in OpenSocial: when you add a widget here, you'll be able to open it on your desktop automatically (and web widgets you add to your desktop will be accessible here in OpenSocial).
If you download a copy of the Amnesty Hypercube public alpha, please keep in touch with your comments, suggestions and bug reports. Thanks!
Hypercube for WindowsDownload Now |
Hypercube for OS XDownload Now |
|
|---|---|---|
|
|
|
|


{
className : "os-theme-dark",
resize : "none",
sizeAutoCapable : true,
clipAlways : true,
normalizeRTL : true,
paddingAbsolute : false,
autoUpdate : null,
autoUpdateInterval : 33,
updateOnLoad : ["img"],
nativeScrollbarsOverlaid : {
showNativeScrollbars : false,
initialize : true
},
overflowBehavior : {
x : "scroll",
y : "scroll"
},
scrollbars : {
visibility : "auto",
autoHide : "never",
autoHideDelay : 800,
dragScrolling : true,
clickScrolling : false,
touchSupport : true,
snapHandle : false
},
textarea : {
dynWidth : false,
dynHeight : false,
inheritedAttrs : ["style", "class"]
},
callbacks : {
onInitialized : null,
onInitializationWithdrawn : null,
onDestroyed : null,
onScrollStart : null,
onScroll : null,
onScrollStop : null,
onOverflowChanged : null,
onOverflowAmountChanged : null,
onDirectionChanged : null,
onContentSizeChanged : null,
onHostSizeChanged : null,
onUpdated : null
}
}
| Option Name | Type(s) | Valid values | Default Value |
| className | string / null | - | "os-theme-dark" |
|
The class name which shall be added to the host element. You can add multiple class names if you separate them by spaces.
This option is intended for styling / theming purposes. If this option is null, then the class .os-theme-none gets added automatically to the host element. This class ensures that the scrollbars won't have any appearance. |
|||
| resize | string |
shorthand: |
"none" |
|
The resize behavior of the host element. This option works exactly like the CSS3 resize property.
This option is ignored if the target-element is the body element. The window itself can be resized and thus this option isn't needed.
"none"
The host element is not resizable.
"both"
The host element is resizable in the horizontal and vertical direction.
"horizontal"
The host element is resizable in the horizontal direction.
"vertical"
The host element is resizable in the vertical direction.
|
|||
| sizeAutoCapable | boolean | - | true |
|
Indicates whether the host element is capable of "auto" sizes such as:
width: auto and height: auto .
If set to false and the property width or height is "auto", the rendered width or height of the content will be zero.If you are applying OverlayScrollbars to a flexbox-element set this option to false to ensure correct functionality. This option is ignored if the target-element is the body element, because in this case the size must be 100% (on both axis) to simulate the viewport correctly. |
|||
| clipAlways | boolean | - | true |
|
Indicates whether the content shall be clipped always.
If false the content gets only clipped if an overflow on the bottom or right edge exists. - Use the capabilities demo, set the host-element height dropdown value to "Auto" and play with the "Clip Always" checkbox to understand this option. |
|||
| normalizeRTL | boolean | - | true |
|
Indicates whether RTL scrolling shall be normalized.
Every browser handles RTL scrolling differently. With this option set to true, every call to the scroll method will be normalized to guarantee the same functionality on every browser. |
|||
| paddingAbsolute | boolean | - | false |
|
Indicates whether the padding for the content shall be absolute.
Absolute padding means that the content will always have the defined spacing to the edge, regardless of the scroll-offset. Every browser handles normal padding on scrolled content differently. This options gives you also the possibility to handle padding the same way in every browser. |
|||
| autoUpdate | boolean / null | - | null |
|
Indicates whether the plugin instance shall be updated continuously within a update loop.
true
The instance is using the update loop.
On every iteration of the loop the DOM / instance is checked for changes. Only if there are any changes the DOM / instance will be updated. If the browser supports modern change detection mechanisms, they get turned off.
false
The instance isn't using the update loop.
If the browser supports modern change detection mechanisms, they gets turned on and the instance is using them.
null
The plugin chooses. - It checks if the browser supports modern change detection mechanisms. If yes, then the plugin will use these for updating (alike false), else it will fallback to the update loop (alike true).
This option is highly recommended to guarantee best performance and browser compatibility.
- Note: To ensure maximum efficiency there is only ONE update loop across ALL instances. The loop is only running if at least one instance is using it. The loop interval is the value of the smallest "autoUpdateInterval" option across all instances which are using the loop. |
|||
| autoUpdateInterval | number | - | 33 |
|
The interval in milliseconds in which an auto update shall be performed for this instance.
|
|||
| updateOnLoad | string / array / null | - | ["img"] |
added in v1.12.0 Selectors of which the elements load event shall be handled by the plugin. Thats means OverlayScrollbars will trigger a automatic update if a element with a matching selector emits a load event.Per default OverlayScrollbars will update automatically if a img element loads.
|
nativeScrollbarsOverlaid : {
These options are only respected if the native scrollbars are overlaid.
| Option Name | Type(s) | Valid values | Default Value |
| showNativeScrollbars | boolean | - | false |
|
Indicates whether the native overlaid scrollbars shall be visible.
true Shows the native scrollbars and hides the custom scrollbars, but still initializes the plugin and dispatches all callbacks.false Hides the native scrollbars and acts like if they were non-overlay-scrollbars. |
|||
| initialize | boolean | - | true |
|
Indicates whether the plugin shall be initialized even if the native scrollbars are overlaid.
true Initializes the plugin normally.false Stops the plugin from initializing and fires the'onInitializationWithdrawn' callback.- Use false if you want prevent the plugin to initialize for example on mobile browsers. If you initialize the plugin on the body element, I highly recommend to set this option to false. |
}
overflowBehavior : {
Defines how the overflow should be handled for each axis, e.g. if scrolling shall be possible or not.
| Option Name | Type(s) | Valid values | Default Value |
| x | string |
shorthand: |
"scroll" |
|
The overflow behavior for the x (horizontal) axis.
"hidden"
If the x-axis has an overflow, the viewport becomes
overflow-x: hidden .In short: Horizontal scrolling is NOT possible and the content is clipped.
"scroll"
If the x-axis has an overflow, the viewport becomes
overflow-x: scroll .In short: Horizontal scrolling is possible and the content is clipped.
"visible-hidden"
If the x-axis has an overflow, the viewport becomes
overflow-x: visible .
If the y-axis has an overflow and the overflow behavior of the y-axis is "hidden" or "scroll", the viewport becomes overflow-x: hidden .In short: The content is not clipped, but if the y-axis has an overflow the content is clipped and horizontal scrolling is NOT possible.
"visible-scroll"
If the x-axis has an overflow, the viewport becomes
overflow-x: visible .
If the y-axis has an overflow and the overflow behavior of the y-axis is "hidden" or "scroll", the viewport becomes overflow-x: scroll .In short: The content is not clipped, but if the y-axis has an overflow the content is clipped and horizontal scrolling is possible. |
|||
| y | string |
shorthand: |
"scroll" |
|
The overflow behavior for the y (vertical) axis.
"hidden"
If the y-axis has an overflow, the viewport becomes
overflow-y: hidden .In short: Vertical scrolling is NOT possible and the content is clipped.
"scroll"
If the y-axis has an overflow, the viewport becomes
overflow-y: scroll .In short: Vertical scrolling is possible and the content is clipped.
"visible-hidden"
If the y-axis has an overflow, the viewport becomes
overflow-y: visible .
If the x-axis has an overflow and the overflow behavior of the x-axis is "hidden" or "scroll", the viewport becomes overflow-y: hidden .In short: The content is not clipped, but if the x-axis has a overflow the content is clipped and vertical scrolling is NOT possible.
"visible-scroll"
If the y-axis has an overflow, the viewport becomes
overflow-y: visible .
If the x-axis has an overflow and the overflow behavior of the x-axis is "hidden" or "scroll", the viewport becomes overflow-y: scroll .In short: The content is not clipped, but if the x-axis has an overflow the content is clipped and vertical scrolling is possible. |
}
scrollbars : {
Defines the behavior of the custom scrollbars.
| Option Name | Type(s) | Valid values | Default Value |
| visibility | string |
shorthand: |
"auto" |
|
The basic visibility of the scrollbars.
"visible"
The scrollbars are always visible, regardless of whether the appropriate axis has an overflow.
"hidden"
The scrollbars are never visible, regardless of whether the appropriate axis has an overflow.
"auto"
The scrollbars are only visible if the appropriate axis has an overflow.
|
|||
| autoHide | string |
shorthand: |
"never" |
|
The possibility to hide visible scrollbars automatically after a certain action.
"never"
The scrollbars never get hidden automatically.
"scroll"
The scrollbars get hidden automatically after a scroll.
"leave"
The scrollbars get hidden automatically after the mouse has left the host-element.
"move"
The scrollbars get hidden automatically after a scroll and after the mouse has stopped moving.
added in v1.4.0
|
|||
| autoHideDelay | number | - | 800 |
|
The delay in milliseconds before the scrollbars get hidden automatically.
|
|||
| dragScrolling | boolean | - | true |
|
Defines whether the scrollbar-handle supports drag scrolling.
If set to true, it's possible to drag the scrollbar-handle to change the scroll-offset. |
|||
| clickScrolling | boolean | - | false |
|
Defines whether the scrollbar-track supports click scrolling.
If set to true, it's possible to click on the scrollbar-track to change the scroll-offset. |
|||
| touchSupport | boolean | - | true |
|
Indicates whether the scrollbar reacts to touch events.
|
|||
| snapHandle | boolean | - | false |
added in v1.7.0 Indicates whether the scrollbar handle-offset shall be snapped or not. This option is only interesting if you use CSS Scroll snapping. Some browsers, like Google Chrome, will snap the scrollbar handle to the next possible position. By default the unsnapped (normal) handleOffset will be used, but you can change this behavior with this option. |
}
textarea : {
Defines special behavior of textarea elements.
| Option Name | Type(s) | Valid values | Default Value |
| dynWidth | boolean | - | false |
|
Indiactes whether the textarea width will be dynamic (content dependent).
This effect will only take place if the sizeAutoCapable option is true and the textarea has the HTML attribute wrap="off" applied.Also the host-elements CSS must be width: auto in combination with float: left or float: right .
|
|||
| dynHeight | boolean | - | false |
|
Indiactes whether the textarea height will be dynamic (content dependent).
This effect will only take place if the sizeAutoCapable option is true and the host-element has the CSS rule height: auto applied.
|
|||
| inheritedAttrs | string / array / null | - | ["style", "class"] |
added in v1.6.0 You can pass a array of strings which represents attribute names: ["style", "class"] or a string where you separate multiple attributes with a whitespace: "style class" or null which represents a empty array, a empty string or simply no attributes.During initialization: Attributes which the generated host-element shall inherit from from the target textarea-element. During destruction: Attributes which the target textarea-element shall inherit from from the generated host-element. This option was created to increase the control over the styling of textarea instances, but you can use it for any kind of attributes. Let's say you initialize the plugin to: <textarea class="foo bar" style="background: red;"></textarea>
and the inheritedAttrs are ["style", "class"] . Then the resulting generated DOM structure will look like this:
If the inheritedAttrs would be null then the host-element wouldn't have the style and the class attributes of the textarea element.
This was the default behavior before this option was introduced.
|
}
callbacks : {
Callbacks for specific events.
The "this" context of every callback is the current instance of the plugin.
| Option Name | Type(s) | Valid values | Default Value |
| onInitialized | function / null | - | null |
|
Gets fired after the plugin was initialized. It takes no arguments.
onInitialized : function() { }
|
|||
| onInitializationWithdrawn | function / null | - | null |
|
Gets fired after the initialization of the plugin was aborted due to the option:
nativeScrollbarsOverlaid : { initialize : false } . It takes no arguments.
onInitializationWithdrawn : function() { }
|
|||
| onDestroyed | function / null | - | null |
|
Gets fired after the plugin was destryoed. It takes no arguments.
onDestroyed : function() { }
|
|||
| onScrollStart | function / null | - | null |
|
Gets fired after the user starts scrolling. It takes one argument.
onScrollStart : function(eventArgs) { }
The passed argument is the scroll argument which gets also passed to the "native" scroll callback. Read more about it |
|||
| onScroll | function / null | - | null |
|
Gets fired after every scroll. It takes one argument.
onScroll : function(eventArgs) { }
The passed argument is the scroll argument which gets also passed to the "native" scroll callback. Read more about it |
|||
| onScrollStop | function / null | - | null |
|
Gets fired after the user stops scrolling. It takes one argument.
onScrollStop : function(eventArgs) { }
The passed argument is the scroll argument which gets also passed to the "native" scroll callback. Read more about it |
|||
| onOverflowChanged | function / null | - | null |
|
Gets fired after the overflow has changed.
Example: the content gets smaller and thus the overflow disappears. It takes one argument. onOverflowChanged : function(eventArgs) { }
eventArgs documentaton:
Structure:
Description:
x
Indicates whether the x-axis has an overflow. This overflow must not be scrollable.
y
Indicates whether the y-axis has an overflow. This overflow must not be scrollable.
xScrollable
Indicates whether the x-axis is scrollable.
(To be scrollable the axis needs to have an overflow and a "scroll" / "visible-scroll" overflow behavior.)
yScrollable
Indicates whether the y-axis is scrollable.
(To be scrollable the axis needs to have an overflow and a "scroll" / "visible-scroll" overflow behavior.)
clipped
Indicates whether the content is clipped due to an overflow.
(Thus it can be false even if contentClipAlways : true is set. |
|||
| onOverflowAmountChanged | function / null | - | null |
|
Gets fired after the overflow amount has changed.
Example: the content gets a bit larger and thus the overflow amount is now higher. It takes one argument. onOverflowAmountChanged : function(eventArgs) { }
eventArgs documentaton:
Structure:
Description:
x
The overflow amount on the x-axis in pixels.
y
The overflow amount on the y-axis in pixels.
|
|||
| onDirectionChanged | function / null | - | null |
|
Gets fired after the direction has changed. It takes one argument.
onDirectionChanged : function(eventArgs) { }
eventArgs documentaton:
Structure:
Description:
isRTL
Indicates if the new direction is RTL.
dir
The new direction as string. ("ltr" or "rtl")
|
|||
| onContentSizeChanged | function / null | - | null |
|
Gets fired after the content size has changed. It takes one argument.
onContentSizeChanged : function(eventArgs) { }
eventArgs documentaton:
Structure:
Description:
width
The content width in pixels.
height
The content height in pixels.
|
|||
| onHostSizeChanged | function / null | - | null |
|
Gets fired after the host size or host padding has changed. It takes one argument.
onHostSizeChanged : function(eventArgs) { }
eventArgs documentaton:
Structure:
Description:
width
The host-element width in pixels.
height
The host-element height in pixels.
|
|||
| onUpdated | function / null | - | null |
|
Gets fired after the host size has changed. It takes one argument.
onUpdated : function(eventArgs) { }
eventArgs documentaton:
Structure:
Description:
forced
Indicates whether the update was forced due to the "force" parameter in the update method.
|
}
display : inline
elements does not support scrolling at all. If you initialize the plugin to a inline element, the plugin will not work crrectly, and the element dimensions will be wrong aswell.
After you changed the display property to something else, it will work correctly again.
display : block;
display : inline-block;
Since you can wrap any element which has one of those values, they should suit for every application.min-height
or min-width
for your content, you have to do it with this two selectors:
body.os-host > .os-padding > .os-viewport > .os-content,
body.os-host > .os-padding > .os-viewport > .os-content-arrange {
min-width : 800px;
min-height : 600px;
}
Please use always both selectors and not just one.min-height
or min-width
directly for the body element, but that wouldn't make any sense, since you want the body element to be always as big as the window, to simulate a correct viewport. Besides that, the plugin style overrides your body min size(s) to 0 if the plugin is applied to the body element.
Textarea elements are special. Although they can't contain any DOM elements, the plugin has extended support for them..os-host-textarea
, every textarea-host-element has this class applied.inheritedAttrs
or className
options, to give your textarea individual classes or styles.textarea.dynHeight
is set to true, then the host-element must have the css property height: auto
set.textarea.dynWidth
is set to true, then the host-element must have the css properties width: auto
& float: left
set, additionally your textarea element must have the html attribute wrap="auto"
applied, to disable the autowrapping.
img, video, audio, input, embed, object, canvas, button, datalist, fieldset, label, legend, meter, optgroup, option, output, progress, select, [... and maybe more]
v1.5.0 or higher
os-host-flexbox
to your target element.
lower than v1.5.0
sizeAutoCapable : false
and set the overflow style of the target element to overflow: hidden
.display: block; height: 100%; width: 100%;
and initialize to plugin to that inner-div. With this setup the plugin will definitely work.//initializes the plugin to a single element and returns its instance
var instance = OverlayScrollbars(document.getElementById(id), { /* your options */ });
The first argument is the element or the elements to which the plugin shall be initialized.
The second argument represents the options with which the plugin shall be initialized.//returns the plugin instance or undefined if the element has no instance
var instance = OverlayScrollbars(document.getElementById(id));
//initializes plugin
OverlayScrollbars(document.getElementById(id), { });
//... later
//is the same as .options({ resize : "both" }) because the plugin is initialized already
OverlayScrollbars(document.getElementById(id), { resize : "both" });
The initialization for multiple elements works like the initialization for a single element. The only difference is, that the initialization method will return a array of instances.
//initialize plugin with custom options on all div elements and return all instances as array
var instances = OverlayScrollbars(document.querySelectorAll("div"), { });
//get the instance information of all elements on your page and store it into a variable
//the array can contain undefined entries
var instances = OverlayScrollbars(document.querySelectorAll("*"));
for(var i = 0; i < instances.length; i++) {
//check for validity
if(instances[i] !== undefined) {
//do domething with the instance
}
}
I've built-in a filtering possibility, if you want an array only with not undefined instances:
//returns an array with all instances which are not undefined
var instances = OverlayScrollbars(document.querySelectorAll("*"), "!");
for(var i = 0; i < instances.length; i++) {
//do something with the instance
}
Since v1.6.0
you can pass a custom filtering function.//returns an array with all instances which are not undefined and applied to a div-tag-element
var instances = OverlayScrollbars(document.querySelectorAll("*"),
function(element, instance) {
return element.tagName === 'DIV' && instance !== undefined;
}
);
for(var i = 0; i < instances.length; i++) {
//do something with the instance
}
The initialization with extensions provides a possibility to initialize your instance with one or multiple extensions.//register a extension with the name "myExtension"
OverlayScrollbars.extension("myExtension", function() { return { }; });
//register a 2nd extension with the name "myOtherExtension"
OverlayScrollbars.extension("myOtherExtension", function() { return { }; });
//initialize the plugin with just one extension via string
OverlayScrollbars((document.getElementById(id), { }, "myExtension");
//initialize the plugin with multiple extensions via array of strings
OverlayScrollbars((document.getElementById(id), { }, [ "myExtension", "myOtherExtension" ]);
//initialize the plugin with extensions with custom options via object
OverlayScrollbars((document.getElementById(id), { }, {
"myExtension" : { /* options for "myExtension" */ },
"myOtherExtension" : { /* options for "myOtherExtension" */ },
});
//initializes the plugin with empty options
$(id).overlayScrollbars({ /* your options */ });
The object which is passed to this method represents the options with which the plugin shall be initialized.//returns the plugin instance or undefined if the element has no instance
var instance = $(id).overlayScrollbars();
//initializes plugin and stores the instance into a variable
var instance = $(id).overlayScrollbars({ }).overlayScrollbars();
//initializes plugin
$(id).overlayScrollbars({ });
//... later
//is the same as .options({ resize : "both" }) because the plugin is initialized already
$(id).overlayScrollbars({ resize : "both" });
The initialization for multiple elements works like the initialization for a single element. The only difference is, that the initialization method will return an array of instances.
//initialize plugin with custom options on all div elements and return all instances as array
var instances = $("div").overlayScrollbars({ }).overlayScrollbars();
//get the instance information of all elements on your page and store it into a variable
//the array can contain undefined entries
var instances = $("*").overlayScrollbars();
$.each(instances, function(index, instance) {
//check for validity
if(instance !== undefined) {
//do domething with the instance
}
});
I've built-in a filtering possibility, if you want an array only with not undefined instances:
//returns a array with all instances which are not undefined
var instances = $("*").overlayScrollbars("!");
$.each(instances, function(index, instance) {
//do domething with the instance
});
Since v1.6.0
you can pass a custom filtering function.//returns a array with all instances which are not undefined and applied to a div-tag-element
var instances = $("*").overlayScrollbars(function(element, instance) {
return element.tagName === 'DIV' && instance !== undefined;
});
for(var i = 0; i < instances.length; i++) {
//do something with the instance
}
The initialization with extensions provides a possibility to initialize your instance with one or multiple extensions.//register a extension with the name "myExtension"
OverlayScrollbars.extension("myExtension", function() { return { }; });
//register a 2nd extension with the name "myOtherExtension"
OverlayScrollbars.extension("myOtherExtension", function() { return { }; });
//initialize the plugin with just one extension via string
$(id).overlayScrollbars({ }, "myExtension");
//initialize the plugin with multiple extensions via array of strings
$(id).overlayScrollbars({ }, [ "myExtension", "myOtherExtension" ]);
//initialize the plugin with extensions with custom options via object
$(id).overlayScrollbars({ }, {
"myExtension" : { /* options for "myExtension" */ },
"myOtherExtension" : { /* options for "myOtherExtension" */ },
});
Type: PlainObject
The current options of the instance.
optionName
Type: string
Type: *
var className = instance.options("className");
var visibility = instance.options("scrollbars.visibility");
newOptions
Type: PlainObject
instance.options({ className : null });
optionName
Type: string
optionValue
Type: *
instance.options("contentClipAlways", true);
instance.options("overflowBehavior.y", "hidden");
force
Type: boolean
//initialize the plugin and get its instance
var instance = OverlayScrollbars(document.getElementById(id), { });
//put the instance to sleep
instance.sleep();
//... later
//wake the instance up so it work properly again
instance.update();
//initialize the plugin and get its instance
var instance = OverlayScrollbars(document.getElementById(id), { });
//put the instance to sleep
instance.sleep();
Type: PlainObject
{
position : {
x : number,
y : number
},
ratio : {
x : number,
y : number
},
max : {
x : number,
y : number
},
handleOffset : {
x : number,
y : number
},
handleLength : {
x : number,
y : number
},
handleLengthRatio : {
x : number,
y : number
},
trackLength : {
x : number,
y : number
},
snappedHandleOffset : {
x : number,
y : number
},
isRTL : boolean,
isRTLNormalized : boolean
}
Description:
added in v1.7.0
The snapped handle offset of the horizontal scrollbar in pixels.scrollbars.snapHandle
option.
added in v1.7.0
The snapped handle offset of the vertical scrollbar in pixels.scrollbars.snapHandle
option.
deprecated since v1.6.0 & removed since v1.7.0
{
x : {
position : number,
ratio : number,
max : number,
handleOffset : number,
handleLength : number,
handleLengthRatio : number,
trackLength : number,
isRTL : boolean
isRTLNormalized : boolean
},
y : {
position : number,
ratio : number,
max : number,
handleOffset : number,
handleLength : number,
handleLengthRatio : number,
trackLength : number
}
}
Description:
coordinates
Type: *
//scrolls the y-axis to 100% -> to the bottom.
instance.scroll({ y : "100%" });
//scrolls the y-axis to 50%. You could write 50% directly, but I want to demonstrate the calculation possibility.
instance.scroll({ y : "100% / 2" });
//calculates the final result and then adds it to the current y-axis scroll-offset.
instance.scroll({ y : "+= 10% - 25" });
//subtracts 50 pixel from the currext y-axis scroll-offset.
instance.scroll({ y : "-= 50px" });
instance.scroll({ x : position, y : position });
//or
instance.scroll({ l : position, t : position });
//or
instance.scroll({ left : position, top : position });
//[ x, y ]
instance.scroll([ position, position ]);
instance.scroll(position);
instance.scroll($(selector));
//or
instance.scroll(document.getElementById("id"));
{
el : HTMLElement | jQueryElement,
scroll : string | array | object,
block : string | array | object,
margin : number | boolean | array | object
}
PlainObject description:
added in v1.5.0
[ "never", "always" ]
-
with this array a scroll will be performed only on the y-axis.
x
and y
.
If your object doesn't specify a value for a axis, it's treated as if the value was always
.{ x : "never" }
[ "begin", "end" ]
-
with this array the element will be docked to the left and bottom edge of the viewport.[ "center", "begin" ]
-
with this array the element will be docked to the top edge of the viewport and is centered horizontally.
added in v1.5.0
x
and y
.
If your object doesn't specify a value for an axis, it's treated as if the value was begin
.{ y : "center" }
[ left&right, top&bottom ]
[ top, right, bottom, left ]
The array can consist of numbers or booleans or a mix.[ true, 0, 0, 10 ]
added in v1.5.0
top
, right
, bottom
and left
.
The values can be booleans (if the original CSS margin value of the corresponding direction shall be used) or numbers (if a custom margin value shall be used).0
.{ top : true, left: 10 }
deprecated since v1.5.0
duration
Type: number
easing
Type: string | array | object
added in v1.6.0
complete
Type: function
//set the scroll-offset to 50 on both axis.
instance.scroll(50);
//scroll to 50% on both axis with a duration of 1000ms
instance.scroll({ x : "50%", y : "50%" }, 1000);
//scroll to 0 on the x-axis and to 100% on the y-axis with a duration of 2500ms
instance.scroll([ 0, "100%" ], 2500);
//scroll to 50% on both axis with a duration of 5500ms
//use a "linear" easing on the x axis and a "easeOutBounce" easing on the y axis
instance.scroll("50%", 5500, { x : "linear", y : "easeOutBounce" });
//set the x-axis scroll-offset to 0 and add a calculatd value to the y-axis scroll-offset
//with a duration of 1500ms
//with a "easeOutBounce" easing for both axis
instance.scroll({ x : 0, y : "+= 30% - 25px" }, 1500, "easeOutBounce");
//subtract 10 pixel from the current x-axis scroll-offset and set the y-axis scroll-offset to 10 pixel
instance.scroll({ x : "-= 10px", y : 10 });
//scroll to the left top corner of the passed element
instance.scroll(element);
//scroll to the left top corner of the passed element
//with a duration of 1300ms
//with no easing
//with a complete callback
instance.scroll(element, 1300, undefined, function() { });
//equivalent of the scrollIntoView() method
instance.scroll({ el : element, block : { y : "begin", x : "nearest" } });
//equivalent of the scrollIntoView(false) method
instance.scroll({ el : element, block : { y : "end", x : "nearest" } });
//scroll to the top edge of the passed element if it isn't in view
//with 500ms
instance.scroll({ el : element, scroll : { y : "ifneeded", x : "never" } }, 500);
//scroll to the bottom edge of the passed element
instance.scroll({ el : element, scroll : { x : "never" }, block : "end" });
//scroll to the bottom and left edge of the passed element if it isnt in view and let 10 pixel margin
instance.scroll({ el : element, scroll : "ifneeded", block : ["begin", "end"], margin : 10 });
coordinates
Type: *
added in v1.5.0
Type: OverlayScrollbars
//scroll-animation duration is 10 seconds
instance.scroll({ y : "100%" }, 10000);
//abort the 10 seconds scroll-animation immediately
instance.scrollStop();
//scroll-animation duration is 1 second
instance.scroll({ y : "100%" }, 1000);
//chaining added in v1.5.0 - stop the old animation and start a new one in one line
instance.scrollStop().scroll({ y : 500 }, 5000);
Type: PlainObject
{
target : HTMLElement,
host : HTMLElement,
padding : HTMLElement,
viewport : HTMLElement,
content : HTMLElement,
scrollbarHorizontal : {
scrollbar : HTMLElement,
track : HTMLElement,
handle : HTMLElement
},
scrollbarVertical : {
scrollbar : HTMLElement,
track : HTMLElement,
handle : HTMLElement
},
scrollbarCorner : HTMLElement
}
Description:
elementName
Type: string
Type: *
var host = instance.getElements("host");
var horizontalHandle = instance.getElements("scrollbarHorizontal.handle");
var verticalHandle = instance.getElements("scrollbarVertical.handle");
Type: PlainObject
{
destroyed : boolean,
sleeping : boolean,
autoUpdate : boolean,
widthAuto : boolean,
heightAuto : boolean,
documentMixed : boolean,
padding : {
t : number,
r : number,
b : number,
l : number
},
overflowAmount : {
x : number,
y : number
},
hideOverflow : {
x : boolean,
y : boolean,
xs : boolean,
ys : boolean
},
hasOverflow : {
x : boolean,
y : boolean
},
contentScrollSize : {
width : number,
height : number
},
viewportSize : {
width : number,
height : number
},
hostSize : {
width : number,
height : number
}
}
Description:
added in v1.8.0
added in v1.4.5
overflow-x: hidden
or overflow-x: scroll
.
overflow-y: hidden
or overflow-y: scroll
.
overflow-x: scroll
.
overflow-y: scroll
.
stateProperty
Type: string
Type: *
var isWidthAuto = instance.getState("widthAuto");
var contentScrollHeight = instance.getState("contentScrollSize.height");
//initialize the plugin and get its instance
var instance = OverlayScrollbars(document.getElementById(id), { });
//destroy the instance
instance.destroy();
//try to get the instance of the plugin again, but it's undefined
instance = var instance = OverlayScrollbars(document.getElementById(id));
added in v1.5.0
extensionName
Type: string
Type: PlainObject | undefined
//register a dummy extensions with the name "myExtension"
OverlayScrollbars.extension("myExtension", function() { return { }; });
//initialize the plugin with the extension "myExtension" and get the plugins instance
var instance = OverlayScrollbars(document.getElementById(id), { }, "myExtension");
//get the instance of the extension "myExtension"
var extensionInstance = instance.ext("myExtension");
Type: PlainObject
added in v1.5.0
extensionName
Type: string
options
Type: *
Type: PlainObject | undefined
//register a dummy extensions with the name "myExtension"
OverlayScrollbars.extension("myExtension", function() { return { }; });
//initialize the plugin and get its instance
var instance = OverlayScrollbars(document.getElementById(id), { });
//add the previously registered extension "myExtension" to the plugin instance
var extensionInstance = instance.addExt("myExtension");
added in v1.5.0
extensionName
Type: string
Type: boolean
//register a dummy extension with the name "myExtension"
OverlayScrollbars.extension("myExtension", function() { return { }; });
//initialize the plugin and get its instance
var instance = OverlayScrollbars(document.getElementById(id), { });
//add the previously registered extension "myExtension" to the plugin instance
instance.addExt("myExtension");
//remove the previously added extension "myExtension" from the plugin instance
instance.removeExt("myExtension");
Type: PlainObject
The object which describes the defaultOptions.
//Gets the current defaultOptions
var defaultOptions = OverlayScrollbars.defaultOptions();
newDefaultOptions
Type: PlainObject
//this instance has the default defaultOptions.
OverlayScrollbars(document.getElementById(id), { });
OverlayScrollbars.defaultOptions({
className : "my-custom-class",
resize : "both"
});
//this instance has the new defaultOptions, which means the options:
//className = "my-custom-class"
//resize = "both"
//are set automatically even without custom options in the constructor
OverlayScrollbars(document.getElementById(otherId), { });
Type: PlainObject
{
defaultOptions : PlainObject,
autoUpdateLoop : boolean,
autoUpdateRecommended : boolean,
supportMutationObserver : boolean,
supportResizeObserver : boolean,
supportPassiveEvents : boolean,
supportTransform : boolean,
supportTransition : boolean,
restrictedMeasuring : boolean,
nativeScrollbarStyling : boolean,
nativeScrollbarSize : {
x : number,
y : number
},
nativeScrollbarIsOverlaid : {
x : boolean,
y : boolean
},
overlayScrollbarDummySize : {
x : number,
y : number
},
rtlScrollBehavior : {
i : boolean,
n : boolean
}
}
Description:
OverlayScrollbars.defaultOptions()
function.
autoUpdate
is null and this property returns true, you can be sure that your instance is updating due to the update loop.deprecated since v1.12.0
//returns a object which represents global infromation about the plugin
var globals = OverlayScrollbars.globals();
added in v1.5.0
extensionName
Type: string
extensionFactory
Type: function
defaultOptions
Type: *
//register a dummy extension with the name "myExtension"
OverlayScrollbars.extension("myExtension", function() { return { }; });
extensionName
Type: string
extensionFactory
Type: null | undefined
//unregister the extension with the name "myExtension"
OverlayScrollbars.extension("myExtension", null);
extensionName
Type: string
Type: PlainObject
{
name : string,
extensionFactory : function,
defaultOptions : object | undefined
}
Description:
//get the extension-object with the name "myExtension"
var registeredExtension = OverlayScrollbars.extension("myExtension");
Type: ArrayLikeObject
var extensionObjects = OverlayScrollbars.extension(); //get all registered extension-objects
var registeredExtensionCount = extensionObjects.length; //get the number of registered extensions
var firstRegisteredExtensionObject = extensionObjects[0]; //get the first registered extension-object
added in v1.9.0
osInstance
Type: *
//create OverlayScrollbars instance
var osInstance = OverlayScrollbars(document.body, { });
//returns true
OverlayScrollbars.valid(osInstance);
//destroy the instance
osInstance.destroy();
//returns false
OverlayScrollbars.valid(osInstance);
//returns false
OverlayScrollbars.valid({ });
added in v1.5.0
.var extensionFactory = function() {
return { }; //<- this is the actual extension
};
In order to make it more simple and comfortable for developers, the function has a bunch of parameters which make the development much easier.
Furthermore the this
-context of the extensionFactory function is the OverlayScrollbars instance which is trying to add the extension.
var extensionFactory = function(defaultOptions, framework, compatibility) {
var osInstance = this;
return { }; //<- this is the actual extension
};
| Parameter | Description |
| defaultOptions | The "defaultOptions" value which were passed to the global extension method in order to register this extension. If no defaultOptions value was passed this parameter is undefined. |
| framework | The framework which OverlayScrollbars is using internally in order to make it simpler to manipulate and traverse the DOM. If the jQuery version is used, this parameter is the jQuery object. However, if the non-jQuery version is used, this parameter is a jQuery-like-object which has the same API-structure as jQuery but doesn't offer all its functionality. A documentation of the supported methods can be found here. |
| compatibility | A object which offers compatibility methods. These methods are unifying native methods which are different or not present across all browsers. (for example if methods or objects have vendor prefixes, different names or signatures and so on...) A documentation of all methods can be found here. |
| Method Name | Description |
| contract |
Gets called if an instance tries to add an extension. Use this method to determine whether the extension can be added or not. With this method you have the opportunity to abort the adding process. This method has to return a boolean, if the method returns any other type, the method will be ignored. If the method returns true the extension will be added, if it returns false the extension won't be added. If your extension doesn't have a contract method the extension will be added always. The method has one parameter: global : The global object of OverlayScrollbars. (The global window object) |
| added |
Gets called once the extension was successfully added to a OverlayScrollbars instance. Use this method to add all your functionality, DOM elements and so on. The method has one parameter: options : The custom options which have been passed to the extension. This parameter is optional and can be undefined if no options were passed. |
| removed |
Gets called once the extension was removed from a OverlayScrollbars instance. Use this method to remove all your added functionality, DOM elements and so on. The method has no parameters. |
| on |
Gets called after a event happened. The method has two parameters: callbackName : The callback name as specified in the options but without the prefix "on". For exampple the if the event onOverflowChanged happened this parameter is overflowChanged . callbackArgs : The corresponding callback argument. A documentation of all callback arguments can be read here. |
var extensionFactory = function(defaultOptions, compatibility, framework) {
var osInstance = this;
var extension = { };
//the reserved "contract" method, can't be called freely
extension.contract = function(global) { /* code... */ }
//the reserved "added" method, can't be called freely
extension.added = function(options) { /* code... */ };
//the reserved "removed" method, can't be called freely
extension.removed = function() { /* code... */ };
//the reserved "on" method, can't be called freely
extension.on = function(callbackName, callbackArgs) { /* code... */ };
//a custom method which can be called freely
extension.myCustomMethod = function() { /* code... */ };
return extension;
};
I've designed the extension system to be simple and powerful at the same time. However if you're missing any features please open an issue on github and make your suggestion.
added in v1.5.0
.OverlayScrollbars.extension("myBasicExtension", function(defaultOptions, framework, compatibility) {
var osInstance = this;
var extension = { };
var handleElmHorizontal;
var handleElmVertical;
extension.added = function() {
var instanceElements = osInstance.getElements();
var scrollbarHorizontalHandle = instanceElements.scrollbarHorizontal.handle;
var scrollbarVerticalHandle = instanceElements.scrollbarVertical.handle;
var html = '<div style="height: 100%; width: 100%; background: red;"></div>';
handleElmHorizontal = framework(html);
handleElmVertical = framework(html);
framework(scrollbarHorizontalHandle).append(handleElmHorizontal);
framework(scrollbarVerticalHandle).append(handleElmVertical);
}
extension.removed = function() {
handleElmHorizontal.remove();
handleElmVertical.remove();
}
return extension;
});
.addExt("myBasicExtension");
.removeExt("myBasicExtension");
OverlayScrollbars.extension("myAdvancedExtension", function(defaultOptions, framework, compatibility) {
var osInstance = this;
var extension = { };
var trackElmHorizontal;
var trackElmHorizontal2;
var trackElmVertical;
var trackElmVertical2;
//add the divs after the extension has been added to a instance
extension.added = function(options) {
//extend the defaultOptions with the passed options
//to determine the correct color
var parsedOptions = framework.extend(true, { }, defaultOptions, options);
var instanceElements = osInstance.getElements();
var scrollbarHorizontalHandle = instanceElements.scrollbarHorizontal.track;
var scrollbarVerticalHandle = instanceElements.scrollbarVertical.track;
var html = '<div style="height: 100%; width: 100%; top: 0; left: 0; position: absolute;"></div>';
var sInfo = osInstance.scroll();
trackElmHorizontal = framework(html).css({
background : parsedOptions.color,
width : sInfo.handleOffset.x
});
trackElmHorizontal2 = framework(html).css({
background : parsedOptions.color,
width : sInfo.trackLength.x - (sInfo.handleOffset.x + sInfo.handleLength.x),
left : sInfo.handleOffset.x + sInfo.handleLength.x
});
trackElmVertical = framework(html).css({
background : parsedOptions.color,
height : sInfo.handleOffset.y
});
trackElmVertical2 = framework(html).css({
background : parsedOptions.color,
height : sInfo.trackLength.y - (sInfo.handleOffset.y + sInfo.handleLength.y),
top : sInfo.handleOffset.y + sInfo.handleLength.y
});
framework(scrollbarHorizontalHandle).append([trackElmHorizontal, trackElmHorizontal2])
framework(scrollbarVerticalHandle).append([trackElmVertical, trackElmVertical2]);
}
//remove the divs after the extension has been removed from a instance
extension.removed = function() {
trackElmHorizontal.remove();
trackElmHorizontal2.remove();
trackElmVertical.remove();
trackElmVertical2.remove();
}
//hide the custom divs during scrolling
extension.on = function(callbackName, args) {
switch(callbackName) {
case "scroll":
var sInfo = osInstance.scroll();
trackElmHorizontal.css({
width : sInfo.handleOffset.x
});
trackElmHorizontal2.css({
width : sInfo.trackLength.x - (sInfo.handleOffset.x + sInfo.handleLength.x),
left : sInfo.handleOffset.x + sInfo.handleLength.x
});
trackElmVertical.css({
height : sInfo.handleOffset.y
});
trackElmVertical2.css({
height : sInfo.trackLength.y - (sInfo.handleOffset.y + sInfo.handleLength.y),
top : sInfo.handleOffset.y + sInfo.handleLength.y
});
break;
}
}
//a custom method which changes the colors of the added divs
extension.changeColor = function(color) {
trackElmHorizontal.css("background", color);
trackElmHorizontal2.css("background", color);
trackElmVertical.css("background", color);
trackElmVertical2.css("background", color);
}
return extension;
}, { //defaultOptions:
color : "orange"
});
.addExt("myAdvancedExtension");
.addExt("myAdvancedExtension", { color : "DodgerBlue" });
.ext("myAdvancedExtension").changeColor("Crimson");
.ext("myAdvancedExtension").changeColor("GreenYellow");
.removeExt("myAdvancedExtension");
OverlayScrollbars.extension("myDependencyExtension", function(defaultOptions, framework, compatibility) {
var osInstance = this;
var extension = { };
//determine if jQuery is available
extension.contract = function(global) {
return global.jQuery && global.jQuery.fn;
}
//write a message if this extension is added successfully
extension.added = function() {
console.log("The dependency extension was added successfully.");
}
//write a message if this extension is removed successfully
extension.removed = function() {
console.log("The dependency extension was removed successfully.");
}
return extension;
});
.os-theme-none
. Thus it can be activated if you set the className option to this value or null.
//initializes the plugin with "none" -theme
OverlayScrollbars(document.getElementById(id), { className : null });
.os-theme-dark
. Thus it can be activated if you set the className option to this value.
//initializes the plugin with "dark" -theme
OverlayScrollbars(document.getElementById(id), { className : "os-theme-dark" });
.os-theme-light
. Thus it can be activated if you set the className option to this value.
//initializes the plugin with "light" -theme
OverlayScrollbars(document.getElementById(id), { className : "os-theme-light" });
| Class Name | Description |
| .os-host | Indicates whether this element is a host-element. Only applied if the host-element is NOT for a textarea (the target-element is NOT a textarea element). |
| .os-host-textarea | Indicates whether this element is a host-element for a textarea. Only applied if the host-element is for a textarea (the target-element is a textarea element). |
| .os-host-transition | Indicates that the plugin is fully initialized and transitions are possible now. |
| .os-host-rtl | Indicates whether the detected horizontal scroll direction is RTL (Right To Left). |
| .os-host-resize-disabled | Indicates that the resize option is set to "none". |
| .os-host-scrolling | Indicates that a scroll is performing right now. |
| .os-host-overflow | Indicates whether a overflow on any axis is present. |
| .os-host-overflow-x | Indicates whether a overflow on the x-axis is present. |
| .os-host-overflow-y | Indicates whether a overflow on the y-axis is present. |
| .os-host-scrollbar-horizontal-hidden |
Indicates whether the horizontal scrollbar is hidden due to the "visibility" option. (If set to "hidden" this class is always applied. If set to "visible" this class is never applied. If set to "auto" this class is only applied if a overflow on the x-axis is present.) |
| .os-host-scrollbar-vertical-hidden |
Indicates whether the vertical scrollbar is hidden due to the "visibility" option. (If set to "hidden" this class is always applied. If set to "visible" this class is never applied. If set to "auto" this class is only applied if a overflow on the y-axis is present.) |
| * | The class name(s) which is set by the option "className". |
<div class="os-host">
<!-- ... --->
<div class="os-scrollbar os-scrollbar-horizontal">
<div class="os-scrollbar-track">
<div class="os-scrollbar-handle">
</div>
</div>
</div>
<div class="os-scrollbar os-scrollbar-vertical">
<div class="os-scrollbar-track">
<div class="os-scrollbar-handle">
</div>
</div>
</div>
<div class="os-scrollbar-corner">
</div>
</div>
| Class Name | Description |
| .os-scrollbar | Indicates that this element is a scrollbar. (The root element of all scrollbar elements) |
| .os-scrollbar-horizontal | Indicates that this element is a horizontal scrollbar. |
| .os-scrollbar-vertical | Indicates that this element is a vertical scrollbar. |
| .os-scrollbar-auto-hidden | Indicates that this scrollbar is hidden because of the "autoHide" option. Note that this scrollbar is potentially visible and is only hidden due to the configurated "autoHide" effect. |
| .os-scrollbar-auto-hidden | Indicates that this scrollbar is hidden because of the "autoHide" option. Note that this scrollbar is potentially visible and is only hidden due to the configurated "autoHide" effect. |
| .os-scrollbar-unusable | Indicates that this scrollbar is not usable due to no overflow or deactivation via the "overflowBehavior" option. |
| Class Name | Description |
| .os-scrollbar-track | Indicates that this element is a scrollbar track. |
| .os-scrollbar-track-off | Indicates that click scrolling is not possible. Only applied if the "scrollbars.clickScrolling" option is false. |
| Class Name | Description |
| .os-scrollbar-handle | Indicates that this element is a scrollbar handle. |
| .os-scrollbar-handle-off | Indicates that drag scrolling is not possible. Only applied if the "scrollbars.dragScrolling" option is false. |
| Element |
| .os-scrollbar |
| .os-scrollbar-track |
| .os-scrollbar-handle |
| .os-scrollbar-corner |
opacity
, transition
and visibility
on the .os-scrollbar
elements! They are handled automatically.padding
or border
to the .os-scrollbar-track
elements.
/* incorrect */
.os-scrollbar:active,
.os-scrollbar-track:active,
.os-scrollbar-handle:active {
/* DON'T use the :active pseudo-class */
}
/* correct */
.os-scrollbar.active,
.os-scrollbar-track.active,
.os-scrollbar-handle.active {
/* USE the .active class insted */
}
Let's say you like the built-in "dark" theme, but you hate the rounded corners of the handles.//initialize the plugin with custom classnames
OverlayScrollbars(document.getElementById(id), {
className : "os-theme-dark os-theme-dark-edgy"
});
After this command, your host-element has the "dark" -theme applied but has also the class .os-theme-dark-edgy
..os-theme-dark.os-theme-dark-edgy > .os-scrollbar > .os-scrollbar-track > .os-scrollbar-handle {
border-radius: 0px;
}
Make sure that this rule overrules the default "dark" -theme rules (e.g. put it at the bottom or use !important
).limited-handles
:
.limited-handles > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle {
max-width: 50%;
min-width: 30px;
}
.limited-handles > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle {
max-height: 50%;
min-height: 30px;
}
We have defined the required CSS, now we have to initialize the plugin correctly with the above described theme inheritance technique:OverlayScrollbars(document.getElementById(id), {
className : "os-theme-dark limited-handles"
});
The result looks like this:.deviant-scrollbars > .os-scrollbar-horizontal {
top: 0;
right: 0;
bottom: auto;
left: 10px;
width: 50%;
background: rgba(0, 0, 255, 0.3);
}
.deviant-scrollbars > .os-scrollbar-vertical {
left: 0;
bottom: 0;
right: auto;
top: 10px;
height: 50%;
background: rgba(255, 0, 0, 0.3);
}
.deviant-scrollbars.os-host-scrollbar-horizontal-hidden > .os-scrollbar-vertical {
top: 0;
}
.deviant-scrollbars.os-host-scrollbar-vertical-hidden > .os-scrollbar-horizontal {
left: 0;
}
Then we initialize the plugin correctly:OverlayScrollbars(document.getElementById(id), {
className : "os-theme-dark deviant-scrollbars"
});
The result looks like this://your theme name
$theme-name: os-theme-custom;
//horizontal scrollbar
$scrollbar-horizontal-size: 6px; //horizontal scrollbar height
$scrollbar-horizontal-padding: 2px;
$scrollbar-horizontal-inner-expansion: 6px;
$scrollbar-horizontal-track-background: transparent;
$scrollbar-horizontal-track-background-hover: transparent;
$scrollbar-horizontal-track-background-active: transparent;
$scrollbar-horizontal-track-transition: background-color 0.3s;
$scrollbar-horizontal-handle-min-size: 30px; //horizontal scrollbar handle min width
$scrollbar-horizontal-handle-max-size: none; //horizontal scrollbar handle max width
$scrollbar-horizontal-handle-background: rgba(0, 0, 0, 0.4);
$scrollbar-horizontal-handle-background-hover: rgba(0, 0, 0, 0.6);
$scrollbar-horizontal-handle-background-active: rgba(0, 0, 0, 1);
$scrollbar-horizontal-handle-transition: background-color 0.3s;
//vertical scrollbar
$scrollbar-vertical-size: 6px; //vertical scrollbar width
$scrollbar-vertical-padding: 2px;
$scrollbar-vertical-inner-expansion: 6px;
$scrollbar-vertical-track-background: transparent;
$scrollbar-vertical-track-background-hover: transparent;
$scrollbar-vertical-track-background-active: transparent;
$scrollbar-vertical-track-transition: background-color 0.3s;
$scrollbar-vertical-handle-min-size: 30px; //vertical scrollbar handle min height
$scrollbar-vertical-handle-max-size: none; //vertical scrollbar handle max height
$scrollbar-vertical-handle-background: rgba(0, 0, 0, 0.4);
$scrollbar-vertical-handle-background-hover: rgba(0, 0, 0, 0.6);
$scrollbar-vertical-handle-background-active: rgba(0, 0, 0, 1);
$scrollbar-vertical-handle-transition: background-color 0.3s;
//scrollbar corner
$scrollbar-corner-background-color: transparent;
.#{$theme-name} > .os-scrollbar-horizontal {
right: $scrollbar-vertical-size + ($scrollbar-vertical-padding * 2);
height: $scrollbar-horizontal-size;
padding: $scrollbar-horizontal-padding;
}
.#{$theme-name} > .os-scrollbar-vertical {
bottom: $scrollbar-horizontal-size + ($scrollbar-horizontal-padding * 2);
width: $scrollbar-vertical-size;
padding: $scrollbar-vertical-padding;
}
.#{$theme-name}.os-host-rtl > .os-scrollbar-horizontal {
left: $scrollbar-vertical-size + ($scrollbar-vertical-padding * 2);
right: 0;
}
.#{$theme-name} > .os-scrollbar-corner {
height: $scrollbar-horizontal-size + ($scrollbar-horizontal-padding * 2);
width: $scrollbar-vertical-size + ($scrollbar-vertical-padding * 2);
background-color: $scrollbar-corner-background-color;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track {
background: $scrollbar-horizontal-track-background;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track {
background: $scrollbar-vertical-track-background;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track:hover {
background: $scrollbar-horizontal-track-background-hover;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track:hover {
background: $scrollbar-vertical-track-background-hover;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track.active {
background: $scrollbar-horizontal-track-background-active;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track.active {
background: $scrollbar-vertical-track-background-active;
}
.#{$theme-name}.os-host-transition > .os-scrollbar-horizontal > .os-scrollbar-track {
-webkit-transition: $scrollbar-horizontal-track-transition;
transition: $scrollbar-horizontal-track-transition;
}
.#{$theme-name}.os-host-transition > .os-scrollbar-vertical > .os-scrollbar-track {
-webkit-transition: $scrollbar-vertical-track-transition;
transition: $scrollbar-vertical-track-transition;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle:before,
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle:before {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: block;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle:before {
top: -$scrollbar-horizontal-inner-expansion;
bottom: -$scrollbar-horizontal-padding;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle:before {
left: -$scrollbar-vertical-inner-expansion;
right: -$scrollbar-vertical-padding;
}
.#{$theme-name}.os-host-rtl > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle:before {
right: -$scrollbar-vertical-inner-expansion;
left: -$scrollbar-vertical-padding;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle {
border-radius: $scrollbar-horizontal-size;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle {
border-radius: $scrollbar-vertical-size;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle {
min-width: $scrollbar-horizontal-handle-min-size;
max-width: $scrollbar-horizontal-handle-max-size;
background: $scrollbar-horizontal-handle-background;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle {
min-height: $scrollbar-vertical-handle-min-size;
max-height: $scrollbar-vertical-handle-max-size;
background: $scrollbar-vertical-handle-background;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle:hover {
background: $scrollbar-horizontal-handle-background-hover;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle:hover {
background: $scrollbar-vertical-handle-background-hover;
}
.#{$theme-name} > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle.active {
background: $scrollbar-horizontal-handle-background-active;
}
.#{$theme-name} > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle.active {
background: $scrollbar-vertical-handle-background-active;
}
.#{$theme-name}.os-host-transition > .os-scrollbar-horizontal > .os-scrollbar-track > .os-scrollbar-handle {
-webkit-transition: $scrollbar-horizontal-handle-transition;
transition: $scrollbar-horizontal-handle-transition;
}
.#{$theme-name}.os-host-transition > .os-scrollbar-vertical > .os-scrollbar-track > .os-scrollbar-handle {
-webkit-transition: $scrollbar-vertical-handle-transition;
transition: $scrollbar-vertical-handle-transition;
}
.............
..........................................
..................................................
..........................................................................................
............................
................................
........................................................................
..........................................
.....................
..................................................................
............................
.............................................................................
.....................................
..................................................
..........................................................................................
............................
................................
........................................................................
.............
..........................................
.....................
Textarea:
The element to which the plugin was initialized (target element).Host Element:
After initialization it is the root element which contains all divs of the plugin.Host Element:
The element to which the plugin was initialized (target element).Content Item Element(s):
The element(s) which are affected by scrolling.Size Observer Element:
Detects any size, padding, border, margin and direction changes of the host element.Size Auto Observer Element:
Only applied if the plugin is initialized with the optionsizeAutoCapable: true
or if the option is set for the first time to true.Content Glue Element:
Only applied if the plugin is initialized with the optionsizeAutoCapable: true
or if the option is set for the first time to true.Padding Element:
Manages the correct padding appearance. The size of this elements is the correct viewport size, since this element never has margin, padding or border values applied.Viewport Element:
The element which contains the native scrollbars and thus is responsible for the scrolling itself. In order to hide the native scrollbars this element can have margin, padding, border as well as absolute position values applied.Content Arrange Element:
Only applied if scrollbars are natively overlaid and the browser isn't capable of native Scrollbar-Styling. Is responsible for the correct hiding of natively overlaid scrollbars and the correct scroll position. If the target-element is the body element, this element is also responsible for the correct min-width and min-height if specified.Content Element:
Is responsible for the correct appearance of percent sized elements as well as for measuring the correct overflow values.Scrollbar Horizontal / Vertical Element:
These elements are the custom styled scrollbar elements. The inner structure of each scrollbar element looks like:Scrollbar Track Element:
Responsible for scrolling with a mouse down on the track.Scrollbar Handle Element:
Responsible for drag scrolling and scroll position indication.Scrollbar Corner Element:
This element is responsible for resizing (if activated) or for style purposes only.{
wW : function,
wH : function,
mO : function,
rO : function,
rAF : function,
cAF : function,
now : function,
stpP : function ( event ),
prvD : function ( event ),
page : function ( event ),
mBtn : function ( event ),
inA : function ( item, array ),
isA : function ( array ),
type : function ( obj ),
bind : function ( function, thisObj [, arg1[, arg2[, ...]]] )
}
//Example usage
var wndWidth = compatibility.wW();
//Example usage
var wndHeight = compatibility.wH();
//Example usage
var mO = compatibility.mO();
if(mO) {
var myMutationObserver = new mO(function(mutations) {
console.log(mutations);
});
}
//Example usage
var rO = compatibility.rO();
if(rO) {
var myResizeObserver = new rO(function(entries) {
console.log(entries);
});
}
//Example usage
var rAF = compatibility.rAF();
var requestID = rAF(function() { /* example code */ });
//Example usage
var rAF = compatibility.rAF();
var requestID = rAF(function() { /* example code */ });
var cAF = compatibility.cAF();
cAF(requestID);
//Example usage
var time = compatibility.now();
//Example usage
document.addEventListener('mousedown', function(event) {
compatibility.stpP(event);
});
//Example usage
document.addEventListener('mousedown', function(event) {
compatibility.prvD(event);
});
//Example usage
document.addEventListener('mousedown', function(event) {
var mouseButton = compatibility.mBtn(event);
});
//Example usage
var array = document.querySelectorAll('*');
var index = compatibility.inA(document.body, array);
//Example usage
var first = [ 1, 2, 3 ];
var second = { prop : "value" };
framework.isArray(first); //true
framework.isArray(second); //false
//Example usage
//following statements are true:
framework.type(undefined) === "undefined";
framework.type() === "undefined";
framework.type(window.notDefined) === "undefined";
framework.type(null) === "null";
framework.type(true) === "boolean";
framework.type(new Boolean()) === "boolean";
framework.type(3) === "number";
framework.type(new Number(3)) === "number";
framework.type("test") === "string";
framework.type(new String("test")) === "string";
framework.type(function() { }) === "function";
framework.type([ ]) === "array";
framework.type(new Array()) === "array";
framework.type(new Date()) === "date";
framework.type(new Error()) === "error";
framework.type(/test/) === "regexp";
//Example usage
var add = function(a, b) { return this + a + b; }
var add012 = compatibility.bind(add, 0, 1, 2);
var result = add012(); //3
//Example usage
var clone = framework.extend({ }, object1, object2);
var deepClone = framework.extend(true, { }, object1, object2);
//Example usage
framework.isEmptyObject({ }); // true
framework.isEmptyObject({ prop: "value" }); // false
//Example usage
framework.isPlainObject({ }); // true
framework.isPlainObject("test"); // false
//Example usage
var array = [ 10, 20, 30 ];
framework.each(array, function(index, value) {
console.log(value);
});
//Example usage
var array = [ 10, 20, 30, 40 ];
framework.inArray(40, array); //4
//Example usage
framework("div").append("<div></div>");
var myElm = framework("<div></div>");
framework("div").append(myElm);
//Example usage
framework("div").prepend("<div></div>");
var myElm = framework("<div></div>");
framework("div").prepend(myElm);
//Example usage
framework("div").before("<div></div>");
var myElm = framework("<div></div>");
framework("div").before(myElm);
//Example usage
framework("div").after("<div></div>");
var myElm = framework("<div></div>");
framework("div").after(myElm);
//Example usage
framework("div").remove();
//Example usage
framework("div").wrap("<div></div>");
//Example usage
framework("div").wrapAll("<div></div>");
//Example usage
framework("div").wrapInner("<div></div>");
//Example usage
framework("div").unwrap();
//Example usage
framework("div").css("display"); //get the current css "display" of the matched element
framework("div").css("display", "none"); //set the css display value to "none"
framework("div").css({ opacity: 1, display: "block", background: "red" }); //change multiple styles
//Example usage
framework("div.test-class").hasClass("test-class"); //true
//Example usage
framework("div.test-class-one").addClass("test-class-two"); //add one class
framework("div.test-class-one").addClass("test-class-two test-class-three"); //add mutliple classes
//Example usage
framework("div.test-class-one").removeClass("test-class-two"); //removes one class
framework("div.test-class-one").removeClass("test-class-two test-class-three"); //removes mutliple classes
//Example usage
framework("div").offset(); //gets the offset of the first found div element
//Example usage
framework("div").position(); //gets the position of the first found div
//Example usage
framework("div").scrollLeft(); //gets the scrollLeft offset of the first found div
framework("div").scrollLeft(200); //sets the scrollLeft offset to 200 for all found divs
//Example usage
framework("div").scrollTop(); //gets the scrollTop offset of the first found div
framework("div").scrollTop(200); //sets the scrollTop offset to 200 for all found divs
//Example usage
framework("div").attr("id"); //get the attribute "id" of the first matched element
framework("div").attr("id", "myId"); //set the attribute "id" for the matched element(s)
//Example usage
framework("div").removeAttr("id"); //remove the attribute "id" for the matched elements
//Example usage
framework("input").val(); //gets the value of the first found input element
framework("input").val("hello world"); //sets the value for all found input elements to "hello world"
//Example usage
framework("div").hide();
//Example usage
framework("div").show();
//Example usage
framework("div").first(); //reduced to the first found div element
//Example usage
framework("div").last(); //reduced to the last found div element
//Example usage
framework("div").eq(2); //reduced to the 2nd div which was found
framework("div").eq(-2); //reduced to the 2nd last div which was found
//Example usage
framework("ul").find("li:first-child"); //returns the first list element
//Example usage
framework("ul").children(); //returns all list elements of the list
//Example usage
framework("li").parent(); //returns the "ul" element of the list element
:hidden
and :visible
- Read more//Example usage
framework("div").is("body"); //false
framework("div").is(":hidden");
framework("div").is(":visible");
//Example usage
framework("div").contents();
//Example usage
framework("div").each(function(index, element) {
console.log(index);
console.log(element);
});
var exampleCallback = function(event) { console.log(event); };
//Example usage with a single event
framework("button").on("click", exampleCallback);
//Example usage with multiple events
framework("body").on("mousedown mouseup mousemove", exampleCallback);
var exampleCallback = function(event) { console.log(event); };
//Example usage with a single event
framework("button").off("click", exampleCallback);
//Example usage with multiple events
framework("body").off("mousedown mouseup mousemove", exampleCallback);
var exampleCallback = function(event) { console.log(event); };
//Example usage with a single event
framework("button").one("click", exampleCallback);
//Example usage with multiple events
framework("body").one("click keydown", exampleCallback);
//Example usage
framework("button").on("click", function(event) { console.log(event); });
framework("button").trigger("click");
//Example usage
framework("div").animate({ height: "50px", opacity: 0.5, scrollTop : 0 }, 1000);
//Example usage
framework("div").animate({ height: "50px", opacity: 0.5, scrollTop : 0 }, 1000);
framework("div").stop(); //the animation above is stopped immediately


@import views.html.util._ @import org.apache.commons.lang3.StringUtils @import models.view.AnswerView @import models.view.BreadcrumbView @import views.html.triage.subAnswers @import views.html.frontendComponents.formCheckboxWithDetailPanel @import play.twirl.api.HtmlFormat @import models.view.ProgressView @this(standardPage: standardPage, triageBreadcrumb: triageBreadcrumb) @(sessionId: String, resumeCode: String, progressView: ProgressView, breadcrumbView: BreadcrumbView) @standardPage("We cannot find your item", None, twoThirdsColumn = false, resumeCode = resumeCode, showBackLink = true){ }{
To find out if your item is controlled and has a control list entry, log in to SPIRE and submit a request using the Control List Classification Advice Service (CLCAS) (opens in a new tab)
When you log in to SPIRE to submit your request through the CLCAS, you'll be asked to:


Next: pprint-newline, Previous: pprint-indent, Up: Printer Dictionary
pprint-logical-block
(stream-symbol object
&key prefix per-line-prefix suffix)
{declaration}* {form}*
⇒ nil
stream-symbol—a stream variable designator.
object—an object; evaluated.
:prefix—a string; evaluated. Complicated defaulting behavior; see below.
:per-line-prefix—a string; evaluated. Complicated defaulting behavior; see below.
:suffix—a string; evaluated. The default is the null string.
declaration—a declare expression; not evaluated.
forms—an implicit progn.
Causes printing to be grouped into a logical block.
The logical block is printed to the stream that is the value of the variable denoted by stream-symbol. During the execution of the forms, that variable is bound to a pretty printing stream that supports decisions about the arrangement of output and then forwards the output to the destination stream.
All the standard printing functions (e.g., write, princ, and terpri) can be used to print output to the pretty printing stream. All and only the output sent to this pretty printing stream is treated as being in the logical block.
The prefix specifies a prefix to be printed before the beginning of the logical block. The per-line-prefix specifies a prefix that is printed before the block and at the beginning of each new line in the block. The :prefix and :pre-line-prefix arguments are mutually exclusive. If neither :prefix nor :per-line-prefix is specified, a prefix of the null string is assumed.
The suffix specifies a suffix that is printed just after the logical block.
The object is normally a list that the body forms are responsible for printing. If object is not a list, it is printed using write. (This makes it easier to write printing functions that are robust in the face of malformed arguments.) If *print-circle* is non-nil and object is a circular (or shared) reference to a cons, then an appropriate "#n#" marker is printed. (This makes it easy to write printing functions that provide full support for circularity and sharing abbreviation.) If *print-level* is not nil and the logical block is at a dynamic nesting depth of greater than *print-level* in logical blocks, "#" is printed. (This makes easy to write printing functions that provide full support for depth abbreviation.)
If either of the three conditions above occurs, the indicated output is printed on stream-symbol and the body forms are skipped along with the printing of the :prefix and :suffix. (If the body forms are not to be responsible for printing a list, then the first two tests above can be turned off by supplying nil for the object argument.)
In addition to the object argument of pprint-logical-block, the arguments of the standard printing functions (such as write, print, prin1, and pprint, as well as the arguments of the standard format directives such as ~A, ~S, (and ~W) are all checked (when necessary) for circularity and sharing. However, such checking is not applied to the arguments of the functions write-line, write-string, and write-char or to the literal text output by format. A consequence of this is that you must use one of the latter functions if you want to print some literal text in the output that is not supposed to be checked for circularity or sharing.
The body forms of a pprint-logical-block form must not perform any side-effects on the surrounding environment; for example, no variables must be assigned which have not been bound within its scope.
The pprint-logical-block macro may be used regardless of the value of *print-pretty*.
*print-circle*, *print-level*.
An error of type type-error is signaled if any of the :suffix, :prefix, or :per-line-prefix is supplied but does not evaluate to a string.
An error is signaled if :prefix and :pre-line-prefix are both used.
pprint-logical-block and the pretty printing stream it creates have dynamic extent. The consequences are undefined if, outside of this extent, output is attempted to the pretty printing stream it creates.
It is also unspecified what happens if, within this extent, any output is sent directly to the underlying destination stream.
pprint-pop, pprint-exit-if-list-exhausted, Tilde Less-Than-Sign-> Logical Block
One reason for using the pprint-logical-block macro when the value of *print-pretty* is nil would be to allow it to perform checking for dotted lists, as well as (in conjunction with pprint-pop) checking for *print-level* or *print-length* being exceeded.
Detection of circularity and sharing is supported by the pretty printer by in essence performing requested output twice. On the first pass, circularities and sharing are detected and the actual outputting of characters is suppressed. On the second pass, the appropriate "#n=" and "#n#" markers are inserted and characters are output. This is why the restriction on side-effects is necessary. Obeying this restriction is facilitated by using pprint-pop, instead of an ordinary pop when traversing a list being printed by the body forms of the pprint-logical-block form.)
Next: pprint-newline, Previous: pprint-indent, Up: Printer Dictionary