We have a number of list items in an unordered list of which we can see five at a time. The currently selected list item has its own class ("selected") and when we click up or down, the next list item gets the "selected" class, while the previous one loses it. How do we make it so that when the list item with the "selected" class comes out of the ul's viewable region, the scroll bar will also scroll with the "selected" item?
It scrolls fine with the mouse, but when the up/down buttons are clicked, the selected class changes but it doesn't scroll. In the CSS, the ul is styled with overflow:auto. I've tried changing the overflow but it doesn't have an effect on the result.
EDIT the problem can be seen here: http://jsfiddle.net/E7MSN/63/
click enter on the textbox, and a dropdown list will appear. Then using the keyboard up/down arrows, keep going until you reach out of bounds. Notice the scroll does not follow the "selected" element.
Use scrollTop to move up and down the ul scroll position.
So in your case:
$(".services ul").scrollTop($('li').index($(".selected")) * $('.services li').height());
In the above code, the $('li').index($(".selected")) gets the number of the currently selected li element. Then this number is multiplied by the height of each li.
Updated jsFiddle
You may need to clean it up to your liking.
Did you tried style="overflow:scroll"?
Related
I have a Vue3 app with vue-draggable and I have a list of sortable cards which possibly contain long text inside. To make dragging easier, I want to hide the text contained in the cards and only show their title when one is being dragged. This makes it easier to drop the card into the right position.
In order to achieve this, the elements which I want to hide inside of the cards while one is being dragged are given a CSS class hidden-while-dragging and the whole collection receives a class dragging while an item is being dragged. This is achieved by setting a boolean variable to the correct value upon receiving the events start and end and conditionally setting the class on the whole <draggable> element. Then I have this CSS rule:
.dragging .hidden-while-dragging {
display: none;
}
This works fine except for one case: if I drag an element and, upon dragging, the height of the parent container changes (due to the disappearing of the content inside of the cards), I am not able to drag the item: it instantly gets dropped in place, and no end event is emitted, so for example the collection keeps the class dragging.
Afterwards, I am able to drop the element once again: the issue doesn't occur this time, because no change in height occurs, and after I drop the element, everything goes back to "normal".
I made this repo in order to have a reproducible example: https://github.com/samul-1/vue-draggable-bug-demo
Here's a codepen as well: https://codepen.io/samul-11/pen/mdjKvZa try and drag the first or last element and you'll see the issue.
You can observe the height of the #app element changing when dragging an element. An interesting thing is that this only happens if dragging the first or third item in my example, not the second. So apparenly the issue is with elements at the edge of the parent.
Is this a bug with the library or is there a way around it?
I am trying to implement a vertical ticker feed of 20 news say. Here I want to have this with below points :
1.) The ticker should display first 5 news at a time. When a user scroll down in the ticket box, he/she can view the others news down to 20th one.
2.) when a user hovers on any news div section, it should display a box in the left side of the news text. Just like as in the case of Facebook ticker. Here what's important is, The box should be displayed well relative to the position of the news div section. If the current position of the news div section is at the bottom of the page then the hover box should be appear at the bottom only. Similarly if the news div position is at the middle of the page, then it should display the hover box at the middle. In a nutshell the hover box should be dynamically adjust its position based on the position of the new div section.
I am facing challenges while developing this so decided to take help from you guys. The main challenge is, while trying to make the ticker box scrollable of fixed height to contain only 5 elements, it is hiding the hover box as well.
The easiest way to achieve the moving context div would be to render it for every item and show it when the user hovers over the ticker item.
Each item would look like <div class="a">NEWS 1 <div class="a1">TO THE LEFT (news)</div></div>
Then you simply set .a1 to display:none on load and add
.a:hover .a1 {
display:block;
}
in your css.
To solve your overflow problem when setting overflow-y to scroll, you can set a margin-left to your list which will expand the overflow-x bounds (and allow your hover over content to display)
Example here
to get what you're really wanting, you're gonna have to use javascript. You'll need to listen to the onmouseover event for all your ticker items and set the Y position of the content div to match. example here: codepen you'll need to sort updating the content of the div and correct left/right position based on where you want it to show
I essentially have an unordered list of list items in a div that doesn't scroll to the next element properly. I'm just trying to have a button to scroll up and down the list.
While the code does scroll, it doesn't match up with the li elements. After every click, it scrolls up a little bit, then down on the next click. I've tried walking the DOM and verifying the element it is scrolling to is an li element, but didn't see the issue.
I have the following jsfiddle:
http://jsfiddle.net/YD9s5/9/
The elements are:
A scrolling div with an id of photos-div
An unordered list with an id of photos-li (whoops, leaving it for now)
List items with incrementing ids of photo-li-X where X is a number
The code being used to scroll the div is:
$('#photos-div').scrollTop($('#photo-li-' + i).offset().top);
The i variable is being incremented, as you can see.
The problem is that .offset() gets the position of an element relative to the entire document, and that position is constantly moving up. So once you've scrolled to item 1, it returns the .offset().top that item 1 currently has in the document, which is now where item 0 used to be.
Add console.log( $('#photo-li-0').offset() ); to the top of your scrollToElement() function and you'll see what I mean. Notice that the top offset keeps decreasing, quickly moving into the negative numbers as it moves off the top of the document.
The fix is to take the difference between the offset of $('#photo-li-'+i) and $('#photo-li-0') (or the container $('#photos-li') itself) and scroll to that instead:
var newpos = $('#photo-li-' + i).offset().top - $('#photo-li-0').offset().top;
$('#photos-div').scrollTop(newpos);
http://jsfiddle.net/mblase75/x4hQP/ (incorporates other improvements)
It appears that .offset() only measures from the top of the document. You are interested in how far the element is from the top of #photos-div. Here's a working version where I track the position in the div manually. Notice in the console that when I log the value of .offset() it's relative to the document rather than the scrolling div.
Seems that there should be a way to do this without carrying the position of that div in state. Working on it...
Here's my more programatic solution.
I am using a div container as a window to slide a list of horizontal li items in and out of view using jquery.
This is what I have so far:
http://jsfiddle.net/TX5fJ/5/
It initializes a list of 8 items and allows you to scroll them left and right within the div window. It also has functions for adding an item to the end of the list and removing an item from the beginning of the list.
What I am trying to do:
1) Add an item to the end of the list (item not visible)
2) Scroll the list to the left to make the item just added visible (first item moves out of view)
3) Remove the item from the head of the list (no longer needed)
The problem is that removing the first item causes the whole list to shift to the left.
If I don't remove the first item it seems to work. (see my test function)
My concerns with that solution is that the ul will have to be wide enough to hold all the potential items. If I don't give it a fixed width it does not work.
So i guess I could make it 99999px wide, and use the current method in the test button.
Anyone have a ideas on a better implementation then the current?
Thanks.
You could simply reset the margin-left property of your list after you have removed the list-item from the head:
function RemoveItem() {
$('#slider-items li').first().remove();
$('#slider-items').css('marginLeft', 0);
}
Updated fiddle.
I have a menu system made up of divs and i want to animate the left property to slide each time the user mouses over a menu item but i need the outer div(which is black) element to expand as the menu items move left to right also I want the div element(.container) to slide back and contract the outer div element(this black div which is 0 width) I have a basic example done in jsFiddle it olny moves the elements to the left
Having a little trouble fully understanding, but is this sort of what you mean?
http://jsfiddle.net/V3RHr/2/
If I could rewrite your html a bit, I would put make each .menu-item into an unordered list.
When you mouseenter the unordered list, you expand the second container. Inside that mouseenter function, I would have a second event when you mouseenter a list item, you populate the second container and stopPropogation.
You could probably still do it with a mouseenter on the first container, and another mouseenter on the div.menu-item, but your first container has extra height and width.
You should be able to fix the left is null issue by having the code not execute on the last .content, like this:
$('.container').not(':last').find('.menu-item').mouseenter(function () {
This will not apply to the menu-items within the green box.
For the re-show issue, I would change the way you are showing. Instead of sliding the box out from behind the other, you can position it where you want it to end up and hide it, then you can use:
.animate({width: 'show'})
Which will give a similar sliding effect.
That, or do it similar to my response to your other question, only without the collapsing I had previously:
http://jsfiddle.net/V3RHr/3/