jQuery documentation for offset() states:
Also, dimensions may be incorrect when the page is zoomed by the user; browsers do not expose an API to detect this condition.
However, is there a way I could calculate the correct offset in browsers in touch environment when using spread to zoom in the contents of a page?
I created a small sample demonstrating the issue: https://jsfiddle.net/dhykgsmp/4/ (open in Chrome). Please scroll down and click zoom in. The offset of the autocomplete input is wrong.
Thank you.
I had the same problem and found a workaround.
You need a root child element with zero offsets to make this work.
$.fn.oldOffset = $.fn.offset;
$.fn.offset = function () {
var c = $.fn.oldOffset.apply(this, arguments);
// root child element with zero offset
var wrc = $('body').children().first().oldOffset();
var needToFix = wrc.left > 0 || wrc.top > 0;
if (needToFix) {
return {
left: c.left - wrc.left,
top: c.top - wrc.top
};
} else {
return c;
}
}
I'm not sure what the intended functionality of this code is, but if you'd like the 'autocomplete input' element to be positioned relative to the 'autocomplete container' I would suggest using the .style.top attribute, or getting the location with Element.getBoundingClientRect() and setting the position accordingly in your positionDropdown() function.
Related
I've been trying to make a simple input element to search for id's and focus on specific vertexes, as shown below:
Screen before Searching
And the code seems to be working with this simple method:
function searchForNode() {
const id = document.getElementById("input-search-id").value;
const { vertex } = findById(id);
const point = new mxPoint(-(vertex.geometry.x), -(vertex.geometry.y));
graph.view.translate = point;
}
The problem starts after the first search, where my top left screen focuses on the desired vertex but from there on I'm enabled to scroll up or left.
Screen after Searching
Also, if I scroll before searching for anything, it seems that my graph.view.translate doesn't update to my current position, so, when I search for a vertex it focuses on a different location instead of the expected vertex.
Is there any method from MxGraph Library that I'm missing? I've tried graph.getView().setTranslate(translate) and graph.panGraph(translate) but the behaviour is the same.
Thank you in advance
So, I found a solution for this problem but not in the most convenient way.
For what I understood, the native scrollbars and the mxGraph panning are different approaches to the display movement, when you scroll you aren't necessarily updating your mxGraph position but when you pan with the mxGraph library you are dragging all the cells along the screen, instead of "scrolling" to them.
I disabled the mxGraph panning option and simply used the javascript native method scrollTo, as show below, I hope it helps.
function searchForNode() {
const inputValue = document.getElementById("input-search-id").value;
const { vertex } = flowMap.findNodeByIdOrName(inputValue);
if( !vertex ) return null;
window.scrollTo({
top: vertex.geometry.y - MARGIN_TO_CENTER,
left: vertex.geometry.x - MARGIN_TO_CENTER,
behavior: 'smooth'
});
}
*The flowMap.findNodeByIdOrName on the last image and the findById(id) on the question post are my own methods to search on my array of vertexes.
Assume there is a scroll list, when I insert some new DOM append to the current dom, it works fine.
pullup
But if I insert some new DOM before, the new DOM will be in the viewport, and the old DOM will be push down.
pulldown
Is there a way that I can make pulldown behave like pullup? Without manually set scrollTop after?
In Google Chrome, I cannot reproduce the behavior you describe. Could there be a difference in how browsers manage maintaining scroll positions upon DOM edits?
In Safari, I do see the behavior you describe. I'm not aware of any different injection methods to bypass the issue, and I don't think css-like tricks such as translateY or position: absolute are the way to go...
So, that brings us to the one option you said you didn't want to use... Modifying scrollTop. I don't see many problems with an approach like this though...
function scrollSafeInsertBefore(fragment, el, scrollContainer) {
var scroller = scrollContainer || document.body;
var parent = el.parentElement;
var aboveScroll = el.getBoundingClientRect().top < 0;
if (aboveScroll) {
var st = parent.scrollHeight;
parent.insertBefore(fragment, el);
var dy = parent.scrollHeight - st;
scroller.scrollTop += dy; // Move back the height change
} else {
parent.insertBefore(fragment, el); // Normal injection
}
}
Fiddle: https://jsfiddle.net/pq4t2zbn/ (press the insert button)
I have a scroll into view already which works, however I was thinking to make it smarter.
This is my code so far
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", element);
which is hooked into my OnClicking event listener - so whenever it goes to click an element, first it scrolls it into view.
This is great and it does what I want it to, however when running my tests my page is scrolling up and down even if the element is in the middle of the screen.
So my question is, how do I set a parameter on this to say, if the element is below 3/4 on the viewable screen then scroll?
I think. You can try it.
var element = driver.FindElement(By.Xpath("//*/blabla"));
var js = driver as IJavaScriptExecutor;
js.ExecuteScript("window.scrollTo(" + element.Location.X + ","+(element.Location.Y - 100) + ");");
You can use javascript to get the X/Y cordinates:
var cumulativeOffset = function(element) {
var top = 0, left = 0;
do {
top += element.offsetTop || 0;
left += element.offsetLeft || 0;
element = element.offsetParent;
} while(element);
return {
top: top,
left: left
};
};
In this case you want the Y coordinate.
And use this: http://www.w3schools.com/jsref/met_win_scrollto.asp
Or... take a look at this:
Javascript scrollIntoView() middle alignment?
I know this is old post, but if people looking for answer, here it is
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView({block: \"center\"});", webElement);
The error I'm having is the following:
To the right of my page, I have a list of interesting points (displayed on a map to the left of the page).
Because the list is so long, I am using iScroll 4 (great plugin).
However, what I would like to do is fire an event when the user has scrolled the list, so I can check which items are currently visible to the user. iScroll already has an event set up for that, so I have a function that fires when needed. However, I cannot seem to get the proper coordinates of my list items.
What happens is the following:
When the list loads, I get an .offset() value for the first element. offset.top = 35, because my list starts 35px lower than the top edge of the page. This is good.
When I scroll the list; say I pull it down for 500px; I would expect the new location to be 35px - 500px = -465px. However, it sill says 35. Scrolling though the list does not affect the elemen'ts coordinates even though it has moved.
How can I get the actual coordinates?
Playing with iScroll, I think I found the solution. the offset() function is javascript refering to the #scroller div, which doesn't change. However internally, iScroll uses its own x and y properties.
So you can refer to the iScroll offset like this
var myScroll = new iScroll(...)
alert(myScroll.y) // -- will return your offset (negative number)
add in iscroll.js
getScrollY: function () { var that = this; return that.y; },
i have a div with a with of 300px.
this DIV contains different Icons and if there are too many Icons then they are not visible due to overflow:hidden
How may i programatically check if an icon is visible or is in overflow area?
I couldn't find anything exactly like that so I wrote a quick library function.
Element.addMethods({
isClipped: function(element, recursive){
element = $(element);
var parent = element.up();
if ((element === document.body) || !parent) return true;
var eLeft = element.offsetLeft,
eRight = eLeft+element.getWidth(),
eTop = element.offsetTop,
eBottom = eTop+element.getHeight();
var pWidth = $R(parent.scrollLeft, parent.getWidth()+parent.scrollLeft),
pHeight = $R(parent.scrollTop, parent.getHeight()+parent.scrollTop);
if (!pWidth.include(eLeft) || !pWidth.include(eRight) || !pHeight.include(eTop) || !pHeight.include(eBottom)) {
return true;
}
if (recursive) return parent.isClipped(true);
return false;
}
});
It's not elegant (I did say "quick") but it allows you to use isClipped() on any element. You can see a jsfiddle test here. It tests if any part of an element (excluding borders) is part of the overflow. You could do something similar to test for elements that are entirely outside the containing client area.
http://elvingrodriguez.com/overflowed/
It's a jQuery plugin that tells you if an element is overflowed.
If a node's scrollWidth/Height is higher than it's offsetWidth/Height, then something will be (partially) hidden. It's then a matter of determining which area is hidden through simple math (adding up icon widths, calculating the scroll offset and then eventually checking if an icon is within that visible area).