jQuery - Placing a div with offset, then placing it again = different results - javascript

I'm placing a div, by using another div id as a reference on the page (to make sure that it appears where I want it to). The code is as follows:-
$('#' + contentDiv).offset({top:($('#' + placementID).offset().top), left: ($('#' + placementID).offset().left)});
The problem is, that though the placementID offset figures are the same each time. Whenever I call this again, it seems to double and put a new left offset that is the the same amount on-top of the previous offset.
E.g. I call a function on a click and say, place this div next to this placement div please. It does it. User then exits and then does another click and the same function is used to place another div next to the same placement div. It does it, but instead of placing it in the same position as last time, seems to reference the position of last time as the 0 point and adds the left amount to that. Meaning the div is placed double distance away now.
Please note; I have consoled out the placement box top and left dimensions and it hasn't changed after each time.
Not sure what's going on.

If someone runs into this, I've managed to solve the problem very simply... by using css instead of offset. I.e.
$('#contentDiv').css({top:placeTop,left:placeLeft});

Im guessing that when you change the offset of $('#' + contentDiv) it affects the offset of your $('#' + placementID) that you subsequently call.
Say you have 3 placement Id's #1,#2 and #3.
With offsets #1: 0,0 #2: 0,100 and #3: 0,200.
Then you set #contentDiv's offest to #1's offset.
Now, #contentDiv's offset is 0,100. This makes your placement offsets #1: 0,100 #2: 0,200 and #3: 0,300 respectively now. Which is probably what is throwing you off.

According to
http://bugs.jqueryui.com/ticket/6868
The element must be visible before calling .position().
after changing my code to show the element before calling offet() it worked like a charm.

Reset your properties before setting the desired offset-value with (e. g.)
$(this).css('top', '').offset({top: desiredTopOffset});

Related

Move to center a selected object with scrollableWidth and scrollToHorizontalOffset

I am having a number (10) of objects which are clickable, but struggling with moving a selected one to the middle of the scroll view. You can see on the image below that number four is selected but not in the middle.
I tried to use:
myScrollView.scrollToHorizontalOffset(myScrollView.scrollableWidth / 2, true)
But it always bring the whole scroll view into the middle. Can anyone help with making it working? Thank you in advance.
Since You didn't put the Angular tag, I am assuming you are using the Typescript flavor of Nativescript.
In order to do this, you'd have to find a way keep track of your base (starting point) and your target (the one that the user just clicked) so that you can get there x offsets and animate the scroll from one to another.
Here's an example in your code behind:
export function() {
const base = page.getViewById('label1') as Label;
const target = page.getViewById('label2') as Label;
myScrollView.scrollToHorizontalOffset(target.getLocationRelativeTo(base).x, true);
}
Now, the code above will just do a minimum scroll to get to your target element (and you can use a different element other than the example label). But if you want to make it center, you can add an additional offset depending on how wide your scroll container is.
eg.
myScrollView.scrollToHorizontalOffset(target.getLocationRelativeTo(base).x + (myScrollView.width / 2), true);
Note that this is my hypothesis from something similar I've done before (just not needing to be center). So might need to play with the additional offset.
EDIT: (This is how to make it work specifically according to the OPs need)
myScrollView.scrollToHorizontalOffset(target.getLocationRelativeTo(base).x - (myScrollView.scrollableWidth / 2)), true);

Not coherent behaviour of jQuery offset(coords) when called twice

I'm trying to position an absolute positioned div using jQuery offset() function.
The idea is to position it at a fixed offset from another element of the DOM. This happens in a quite complex environment with multiple nested divs.
The strange thing that happens is that calling it twice gives two different results. To me it seems there is no reason for this, although I am quite new at jQuery so I could be oversighting something obvious.
I do think that
var pos = $(document.getElementById(someElementInTheDOM)).offset();
$(document.getElementById(MyDiv)).offset( pos );
should position MyDiv always in the same place, even if I call this code some 10 times. That's what correctly happens in this fiddle. Click on the magnifying glass several times, everything is ok.
But as soon as I start adding display:none and display:block properties the thing gets disrupted. I tried to bring it down to basic and I created a fiddle here. To see what I mean press on the magnifying glass, click on the magnifying glass again, click on the magnifying glass once more, close the div by the white "X", click on the magnifying glass once more.
Any clue what's going on?
You just have to change the order:
document.getElementById("iuocboun_filter_window").style.display="block";
$(document.getElementById("iuocboun_filter_window")).offset( pos );
instead of
$(document.getElementById("iuocboun_filter_window")).offset( pos );
document.getElementById("iuocboun_filter_window").style.display="block";
EDIT:
Explanation: The offset does not work on hidden elements, thats why you have to make it first visible and than set the offset. ;)

Problems with Dynamic height and width images on mouseenter and mouseleave function

I am working on this image hover zoom part using jquery . The codes works fine , as the bigger image is showed on mouseenter and hides on mouseleave. since, the image showed on hover can have dynamic width and height(it depends on the image size..) i want to decrease the image width and height to 75% of the actual width and height.. even that is fine and it works..
now the problem i am facing is, whn mouse enters for second time, the image is reduced again.. third time it gets smaller than the second time... so eachtime mouse enters, image gets smaller and smaller...(which i think is obivous since each time mouseenters it reduces the image by 75%...) i have tried lots of things like creating a global variable, and checkin it.. if (first time) thn (reduce) else (reduce from the original image ).
BUT cannot make it work.. here is my code....
http://jsfiddle.net/ugnNU/11/
hoping for some advice. your help will be appreciated.
Thanks.
I tried to update your code as little as possible. Here is an example of how to do what I think you are trying to do. http://jsfiddle.net/ugnNU/12/
There are many many ways to get there, I chose this one because it came close to what you already had.
I added this:
var childImage = $(this).children("div.tooltip");
if (childImage.attr('saveWidth') == ""){
//we haven't saved it's height yet
childImage.attr('saveWidth', childImage.width());
childImage.attr('saveHeight', childImage.height());
}
var hoverImgWidth = childImage.attr('saveWidth');
var finalHoverImagewidth = hoverImgWidth * 0.75;
var hoverImgHeight = childImage.attr('saveHeight');
var finalHoverImageWidth = hoverImgHeight * 0.75;
Basically it just checks to see if we have already saved the 'tooltip' image height inside an attribute. If we have, it just uses that value. But if not, we save the height or width inside that attribute and then uses it.
I'm also only selecting ("div.tooltip") once and saving it in childImage. The reason for this is that each time you do this $(selector) jQuery has to go find that element. If you do this alot, it can impact performance. So it's good practice to just save your selector in a local variable.
http://jsfiddle.net/ugnNU/13/
It does not use a custom attribute. It just undoes in mouseleave, what you did in mouseenter
each time you call this code
var hoverImgWidth = $(this).children("div.tooltip").width();
var finalHoverImagewidth = hoverImgWidth * 0.75;
The width value of div.tooltip gets multiplied with 0.75.
The next time the code is executed this gets the current width (the lowered value) and lowers that again.
You could set the size back again when you hide it, but my advice would be to calculate the values on document ready and only show and hide the image with the mouseenter and mouseleave events.

Prepend a div without shifting the contents down? Using iScroll

I've got a container div with a bunch of scrollable content (for the record I'm using iScroll - if that changes the solution). When I scroll to the top I want to load content above the current scroll position. If I simply prepend the div using jQuery "prepend();" the contents in my scrollable area shift down. Ideally we'd want to keep the current content in the frame and have the scrollable area grow upwards above the content.
Any thoughts?
Thanks!
According to the iScroll website, it has a method called scrollToElement:
scrollToElement(el, runtime): scrolls to any element inside the scrolling area. el must be a CSS3 selector. Eg: scrollToElement("#elementID", '400ms')
If you always prepend a fixed amount of divs (e.g. always a single div), I imagine you could use it to scroll to (e.g.) the second element right after you've prepended the new content:
// ... (prepend new content)
myScroll.scrollToElement('#scroller :nth-child(2)', '0ms');
I haven't tried this, so please let us know if this works for you.
After a quick look through iScroll's source, here's what I've found:
The current x and y are always available through myScroll.x and myScroll.y.
iScroll has an internal function _offset(el), which returns the left and top offset of any given element.
This basically opens up two solutions:
Use _offset(el). While possible, this is inadvisable. The underscore is a convention for marking a function "private", meaning, amongst other things, that it's not part of the official API.
or
Use the newly added element's height:
var x = myScroll.x;
var y = myScroll.y;
// ... (prepend new content)
y += $('#scroller :first-child').outerHeight();
myScroll.scrollTo(x, y, '0ms');
You may need to pass true to .outerHeight(), which makes it include margins.
Once again, I haven't tested this, so please let us know if it works.

How to keep an absolutely positioned element directly over the position of inline one?

This is a follow up question to How can I stop an IFrame reloading when I change it's position in the DOM? if you want the background.
I have an inline div <div id="leaderboard-slot"></div> (with a fixed width and height) and another div ("leaderboard-loader") further down the page with the actual content for that div.
For various reasons (see previous thread), I am unable to simply do an appendChild or similar.
Instead, I'm hoping to position leaderboard-loader such that it takes up the space "reserved" by leaderboard slot. I've used some jQuery methods to do this:
var loader = $('leaderboard-loader');
var dest = $('leaderboard-slot');
var pos = dest.getPosition();
loader.setStyle('top', pos.y + 'px');
loader.setStyle('left', pos.x + 'px');
which I fire on document load and resize. However, if other elements within the page cause a reflow, then the target div moves, but the loader doesn't.
Is there a safe way of doing this - it needs to work when I know nothing else about the page (ie I can't just make this call on any other methods that might cause a reflow, because I don't know what those are).
Any help would be much appreciated - thank you :)
If I understand your question correctly, there is no need for Javascript. Just put leaderboard-loader in front of the leaderboard-slot tag, give it position: absolute and identical width and height. If slot is a normal element, loader will float above it and cover it perfectly.
<div id="leaderboard-loader"></div><div id="leaderboard-slot"></div>
I'm starting to regret my answer now. Hopefully you can find something better than the absolute positioning workaround. But, in the spirit of kludgey solutions, you could call the repositioning script on a timer. sigh.
You could put them both in the same relative positioned, 0 margin div, with the temporary div z-indexed on top of the slow loader.
Make them both absoluely positioned in the parent, not the window, at 0:0 and the same size.
You can use opacity and fade one in as you fade the other one out, or just swap visibility:hidden and visible for the two elements when you are ready..

Categories

Resources