How to detect HTML elements movements? - javascript

I need to detect when an image is moved. The point is that my page has a related HTML element (another image) to the first one that depends on its position. I though that a plugin like Watch can help, but the only properties I know involved with position (top and left) are not changed never to this plugin (keep its original value to 'auto').
How can I get an event triggered when there is a page element move?
UPDATE: In order to avoid missunderstandigs, I'll explain what really happens. I have an image (call it AUX, position absolute) that is situated in function of another image position (image BASE). BASE and AUX don't share anything in the HTML except the BODY element, so it's not possible to use position relative or similar. So, I have a function that gets BASE position and computes AUX position. The problem is when the page is loaded: function is called when document is loaded and BASE has a position different from the final position (when other elements are loaded, like other images, javascript functions, etc, BASE changes its position). This makes AUX have an invalid position (it was valid, but not yet).

Instead of using javascript to set the position, I would use javascript to make them both a child of a minimal common element so that relative positioning schemes could be used. Because otherwise, you would need to poll for the position and update, and at best you can only do that every 10-15 ms or so.

Related

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).

Javascript detect elements in front of elements

How can one know if an element is in front of another element, if the overlaying element is transparent? The purpose for this is if you're artificially clicking a page element by its ID, and you're ensuring there's no overlay on top of the element that would make confirm the click as synthetic (as a normal user would have to click on the overlay).
Case 1: The overlay is a child of the clickable element To Detect it: Ensure there's no children of the clickable element that look unusual.
Case 2: The overlay has an absolute position and a higher z-index to overlay the clickable element
To Detect it: No clue! Unless you iterate through the bounding rectangles and z-index of every element in the DOM or go through the entire DOM looking for particular style attributes. That is expensive.
So, given the number of ways an element can be made to overlay another element, how can a user script detect elements overlaying elements? I suspect a very verbose method of going through the entire DOM could be avoided.
It turns out there's two ways to do this, and by this I mean two ways to find out if any given element is the top most element regardless of opacity.
Adapted from this blog post post and using their code (with some modifications) it's possible to see the top most element at any given mouse position. I modified their code to look for the computed style zIndex of any elements at a position. The downside to this approach is it's computationally costly in that you're looking at the positions of every element in the DOM more or less.
This stack question about checking whether an element is really visible on screen received an answer that linked to a browser method document.elementFromPoint which when given some screen coordinates returns the top most element, regardless of opacity but in accordance with its display style. It appears as though that function is supported in at least Firefox and Chrome.
In the end, there's two solutions to choose from, with the latter likely being the best solution in terms of reliability and cost.

XHTML strict: positioning of div/img does not work as intended

after several days of researching and trying I want to see if you can help me.
I have a graph (coord) and students should mark the extrema of the graph. I have to use JavaScript for this and work in XHTML 1.0 Strict//EN. The idea was that the student clicks on the position on the graph where he/she thinks an extremum lies, this triggers a JavaScript function (addPoint) which adds an img into the same div in which the graph lies (coordDiv) and gives it the position where the student clicked. For an example visit http://ourresidence.net/JavaScript/ where you should be able to view both the site code and the JavaScript code.
As far as I understood, the positioning has to be absolute. static and fixed are incompatible with the desired behaviour and relative would be very difficult because 1. I don't know where the next "ordinary" positioning would be and 2. it would get more complicated with a student deleting a point. So, absolute it is.
Then the positioning should be absolute relative to the div coordDiv and after some time I even figured out how to give the div a concrete dimension (through it's a bit static, the approach with adjustCoordDiv() in klausur.js hasn't work out). However, if I resize the bounderies of the browser, the div and the graph wanders (since they are centered) but the point does not. That needs to be fixed.
And reading how mixed up the acknowledgement of zooming is in different browsers by now I've already completely given up handling zooming in the exercise, but if you come with a solution for that too, my praise would know no end.
Positioning is relative to some containing element in HTML that is positioned itself. If there isn't any such element, positioning is relative to document's body (as in your case). Positioning basically means to have applied some other position in CSS than static.
So you basically need to subordinate your click points to the DIV containing the whole coordinate system (as you do now ). That div should have
position:relative
without any repositioning to position it and to start a new "local coordinate system" for using
position:absolute
on any subordinated element.
On clicking, coordinates of that click need to be converted from global coordinate space to local one. This might be achieved iterating from clicked element to document element using properties offsetParent, offsetTop and offsetLeft of each passed element.

Animate page reflow?

I am switching the contents of divs (fading old contents out, then fading new contents in) and because they are slightly different contents, the moment they change there is a jarring reorganization of everything below them.
My question is, is there a way to make this movement smooth?
I suspect that pretty much the only feasible way to do this is to use javascript to determine ahead of time what the heights (in my case I only deal with blocks where the vertical alignment shifts) of the starting and ending elements are, and assign these values directly. Once I do this I am sure CSS3 transition will apply a pleasant animation.
Is there perhaps a way to get this without specifying explicit dimensions? I seem to recall at some point having experienced items getting moved around the page in an animated fashion. This gives me hope that it could be done using just CSS.
I'd normally create a temporary (invisible) element holding new content so as to calculate its height. After that, the original element can be animated from its current height to the newly calculated height.
It is important that the temporary element created is an identical sibling of the original element so that all the necessary styles cascade and get inherited correctly (for instance, calculating new content height is useless if it doesn't have correct font-size applied)
While animating between different heights set explicitly (i.e. with JS as described above) can be accomplished with CSS3 (transition: height .5s ease;), it will not work for different heights set implicitly (i.e. modifying element content with height:auto)

Why isn't z-index working as I'd expect it to here?

A requirement for a current project of mine involves "highlighting" an HTML element in the context of a page. That is, I need to provide some sort of visual effect that decreases the brightness of the surrounding page while leaving the element at full brightness.
To achieve this, I'm trying the following approach:
Determining the highest z-index value of any element on the page (using JavaScript).
Creating an element to function as a "backdrop" on top of the page. This is just a <div> with a translucent gray background image, sized to 100% of the width and height of the <body> element, with position: fixed. I set its z-index to 1 greater than the highest z-index I've found on the page, with the intent that it will overlay every other element on the page.
Change the z-index of the "highlighted" element to 1 greater than the backdrop. The intent is to allow it to sit on top of the backdrop, which in turn sits on top of the rest of the page.
I got it working on a quick test page:
http://troy.onespot.com/static/stack_overflow/z_index_test.html
but when I tried to set it up on a few actual Web pages, it didn't work in all cases. For example:
http://troy.onespot.com/static/stack_overflow/z_index.html
Here, I've inserted two "dummy" elements on a copy of a Jacksonville.com article page, both with a class of test (if you're looking at the page source, they're at lines 169 & 859).
I also added some JavaScript (using jQuery) at the very end of the page that functions as I've described above.
The first <div class="test"> does function as I'd expect it to. However, the second one does not - it seems to still be stuck beneath the "backdrop" element, despite having a higher z-index.
I think this may have something to do with stacking contexts, but after reading through the relevant W3C docs (http://www.w3.org/TR/CSS21/visuren.html#z-index & http://www.w3.org/TR/CSS21/zindex.html), I still can't fathom why this is happening. I'd appreciate anyone more familiar with z-index and stacking order than I to take a look at my examples and let me know if anything looks suspicious.
Please note that I've only tested these examples in Firefox v3.6.
Thanks very much for any help!
The problem is that the second test div is inside a bunch of other HTML elements, one of which must be creating a new stacking context (it may be the #wl-wrapper-tier-1 div). Basically, a new stacking context is created whenever an element is positioned and has a z-index other than auto, see this MDC article for more info on stacking contexts.
Ultimately this means you can't achieve your desired effect reliably with this method. I think you're probably better off composing 4 divs to surround the target element.
If the element that you're highlighting is inside a different element (stacking context) with a z-index lower than the backdrop, it will not appear higher than the backdrop, since the element's z-index only controls stacking order within that parent.
The only good solution is to clone the highlighted element and add the clone to the <body> tag.
Beware of inherited CSS styles, which would be lost.

Categories

Resources