Disable scrolling entirely - javascript

Is there a way to make "scrolling" inside an element completely impossible? By that, I mean the content of the element must always keep the same position relative to the element. The element in question has fixed dimensions and overflow: hidden;.
I am not talking about preventing the user to scroll inside a certain element, for example by overriding the behaviours of key presses with JavaScript. I don't think doing so would be a good idea as it's impossible to comprehensively predict all the controls of the user and their associated key-bindings. I want to entirely disable scrolling, even when not done by the user.
For example, if the element contains another element with an id attribute, accessing this id (by clicking a link with href="#the-id-in-question") would automatically cause the content to scroll so that the targeted element (the one with an id) is positioned at the top left of its parent.
Another example: if the element in which we want to disable scrolling contains interactive content, tabbing through it will again change the positioning of its content.

Related

How to make several elements elegantly non-focusable?

I want to create a window overlaying my actual content. When visible, this window (and it's children) should be the only elements receiving focus via Mouse and the Tab-key. Any background elements should not be focusable anymore.
I am certain that I can prevent the elements in the background from receiving focus or being clicked using pointer-events: none; . I know that any focus via the Tab-key can be prevented by setting a tabindex="-1" on that specific element. So I am wondering whether there is a more elegant solution to that, rather than applying a negative tabindex to each element individually.

Prevent element from scrolling with page when position is fixed?

Is it possible to make an element have fixed position, but stop it from scrolling with the page?
My problem: I am building a tooltip that I dynamically determine the placement for depending on what space is available on the page for it. It needs to pop up over everything else next to its target element and not take up space. So I initially thought position absolute.
But absolute position is based off of the element's parent wrapper. My page gets wrapped in multiple various wrappers that I have no control over (on Salesforce, but this isn't necessarily a Salesforce specific question).
So I need to position it off of the viewport instead of relying on what parent it ends up getting wrapped in. So position fixed, works great.
The only issue is position fixed has the element scroll with the page. I don't really want the tooltip to follow the user as they scroll.
I feel I need to keep the position based on the viewport due to not being able to control the parent wrappers. But all I have found is position fixed, so not sure if some method exists to stop the element from scrolling with the page.
Seems like you want to use position: absolute; instead of fixed.
If you're set on position: fixed, the only way I know of to have the element move with the rest of the page as the user scrolls is by editing the location with JavaScript when the browser scroll event fires. Otherwise, if you position with respect to the viewport at first, you'll be positioned with respect to the viewport on an ongoing basis. However, hooking into the scroll event doesn't necessarily perform well, and although there are debouncer functions available to help with that, it wouldn't be my first choice.
You may be able to use position: absolute without tangling with the extra page wrappers, however. Is there is an element (call it A) that has these properties:
your tooltip lives inside A (or can be moved there)
you can correctly position your tooltip relative to A
the extra wrappers are always outside A
If so, set position: relative on element A. Your tooltip will use A for reference and not an extra wrapper outside A (even if that wrapper also has position: relative set on it).

Bring an element in front of others that have the same z-index

The user can press a button to create new divs on the screen. Each div is the same and has the same z-index. Newer elements display in front of older elements. The user has the ability to drag around the elements. I would like it so that when a user drags an element, that element is now permanently in front of the other elements (until a different one is created/dragged).
Is it possible to do this without keeping track of z-index somewhere in JS and increment it on creation/click? I'd like to avoid this if possible. Is there some way I can use jQuery or something to make a clicked element act as if it was recently created (which I guess is just determined by position in the DOM?)
I assume you are doing something like
container.appendChild(newDiv)
Now, when you click and drag an element, you can move it to the front.
var parent = recentlyClicked.parentElement // or container
parent.insertBefore(recentlyClicked, parent.firstChild)
This inserts your desired div as the first child of its parent, which will move to the top.
Edit: it appears that elements later in the DOM are the ones that are shown on top. In that case, you'll probably want to append the child instead.
recentlyClicked.parentElement.appendChild(recentlyClicked)
On click you could add a class to the element where the CSS targeting that class has a slightly higher z-index. This is probably the cleanest way to do it (no keeping track of z-indexes, just toggling the existence of that class on mouse down & mouse up.
Another idea (not sure if it'd work, but might be fun to try) would be to add a tabindex="0" to all the elements. They can now receive focus. Then in your CSS add a ":focus" state selector targeting those elements. Increase their z-index with that. I don't recall if the focus happens on mouse down or after a full click. It might bring along other side effects line outlines on the element you don't want. And mess with the usability of the tab key on your website. I'd probably not use this unless it's somehow really much simpler in a non-production circumstance.

Jumping position with content update

I have a container div that holds many other div elements that are sent from the server. I have a <select> that controls the ordering of the elements. Changing this value will trigger the container to be emptied and then new content is sent from the server once again repopulating the container. To clear the container I'm just doing an jquery .empty() (after first detaching some of the elements I need to keep, and restoring those later).
The problem is that this causes the position of the select control to change position and generally move around randomly (due to changes in vertical scrolling). I like the way youtube.com works upon changing of the comment selection from "top comments" to "Newest First". It brings up a spinner and then changes the elements without causing any position or scroll changes. This is similar to what I want to achieve. Does anyone know how I can achieve this?
Note I already have overflow-y: scroll; within my body of the css.

Absolutely positioned block againt any element in the document

Example code: http://jsfiddle.net/ZAm2A/3/
The goal is to position certain popup(div.absolute-block) window against(relative to) any dom element on any page with different html structure.
In order to be able to position popup absolutely, we need to embed it into that dom element, having previously wrapped div.absolute-block with relatively or absolutely positioned block (div.relative1 in our example).
The trouble is that if dom element, we embedded popup in, has block with overfillw: hidden (div.overflow1) among it's ancestors, div.overflow1 will probably crop popup. div.overflow1 may be positioned relatively and we cannot influence it in our situation.
The second approach is to append our popup to page body. In this case we face problem of positioning our popup relatively to certain dom element. We can calculate and set top and left properties for popup on document ready event. But in case of window resizing, ajax content changes or any events changing position of tracked element we have to recalculate popup position.
I think whether there could be some new html 5 features that will let me position popup without embedding it into dom element, i want to position popup relative to? Any other ideas are appreciated.
There's no way to have a child element escape a parent element that has overflow set to hidden. If you want to have an element positioned exactly over the top of a certain element on the page, your safest option is to put it at the root of the document, use Javascript to calculate and adjust the position, and update on window resize, etc. You might be interested in using jQuery's position() (relative to parent) or offset() (relative to entire document) methods to help calculate this.
Also, here's a somewhat-related question on the overflow: hidden issue which might help: Make child visible outside an overflow:hidden parent

Categories

Resources