I wish to have two slimscrolled div and be able to drag and drop elements between them. The latter is tested, and is working perfectly with the sortable method, but when I apply the slimscrolls, the two divs receive the overflow: hidden attribute, which makes the dragged elements disappear when moved outside of the div. As per documentation I saw no option to modify the slimscroll's overflow attribute, which I would like to change to overflow-x: visible and overflow-y: hidden, for obvious reasons. The CSS attribute is applied on element level, so workaround with CSS rules are not an option afaik.
I want the slimscroll to be functional, but I want to be able to drag and drop elements between the two slimscrolled divs. How to proceed?
EDIT
In hope of receiving answer I add a code example:
<div id="container1">
<ul><li>...</li></ul>
</div>
<div id="container2">
<ul><li>...</li></ul>
</div>
<script>
$('#container1').slimScroll({...});
$('#container2').slimScroll({...});
$('#container1').sortable({
connectWith: "#container2",
});
</script>
In the above example, elements from #container1 should be dragged to #container2, but due to the overflow:hidden property applied by the slimScroll(), the dragged element will disappear when dragged outside of the area of #container1. I wish to be able to drag the element and also see the element I am dragging.
The issue was a setting in jquery.slimscroll.js. In v1.3.8 starting from the 160th line I did the following;
// wrap content
var wrapper = $(divS)
.addClass(o.wrapperClass)
.css({
position: 'relative',
overflow: 'visible', // <--- change this from 'hidden' to 'visible' !!!
width: o.width,
height: o.height
});
After applying the above change, the problem I described ceased to exist.
Related
Using the Google Chrome browser, I need to drag-and-drop an item from a menu, in a way so that the menu will automatically close/hide/collapse/disappear/(or something similar) as soon as the dragstart event fires. This has to be done in a way such that the DOM space is freed up, so approaches using "visibility" and "opacity" for instance while possible are not good for this situation.
Instead, it is necessary to do something like display:none or pushing the menu off of the web page (without scrollbar). However, I've gotten stuck trying to accomplish this and could use some help (or if an alternative approach comes to mind that accomplishes the same, please let me know. I also tried a z-index approach without success.):
Approach 1 - Trying to hide dragged item's parent element via absolute positioning
https://jsfiddle.net/gratiafide/4m5r186v/
function dragstart_handler(ev) {
ev.dataTransfer.setData("text/plain", ev.target.id);
ev.currentTarget.parentElement.style.cssText = "position:absolute; right:-5000px;";
}
Approach 2 - Trying to hide dragged item's parent via setting display:none
https://jsfiddle.net/gratiafide/Luj7d089/
function drag(event) {
event.dataTransfer.setData("Text", event.target.id);
document.getElementById('parent').style.display = 'none';
}
You will see in both approaches, the dragged item gets dropped in both instances as soon as the CSS rule gets applied to the dragged item's parent element. I just want to be able to keep dragging the element even though I've hidden or moved the parent element out of sight. Thanks in advance for your help!
You seem to want your parents to disappear by dragging your child's element as it is.
The child element is influenced by the CSS style attribute of the parent element. If parents are erased through css properties such as "display", "visibility", and "opacity", the child element is not visible unconditionally.
Hiding using the "absolute" property(but not z-index -1) is also a way, but unwanted scrollbars may occur depending on the "overflow" attribute of the parent element, and the child element position must be added in reverse and recalculated.
As a result of my test, a dragend event occurred in Chrome when the parent element of the element to be dragged was redrawn. But in Firefox, both of your examples work.
Anyway, to explain based on how it works in Chrome, it is to separate the relationship between Child and Parent and use it as a sibling. Modify your HTML as follows.
<div id='relative_div'>
<div id="parent"></div>
<p id="source" ondragstart="dragstart_handler(event);" draggable="true">Drag me to the Drop Zone below</p>
</div>
Next update your CSS as follows. #parent should serve as a background for filling in #relative_div.
#relative_div {
position: relative;
overflow: hidden;
width: 200px;
height: 100px;
padding: 2em;
}
#parent {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color: lightgrey;
}
#source {
position: relative;
cursor: grab;
color: blue;
border: 1px solid black;
}
Now, regardless of whether you use #parent's "position" to push it away, or hide it using "display", "opaicty", or "visibility", #source drag does not stop.
ok, I think my comment was wrong and that you want to remove the space on the page occupied by the origin element (rather than freeing up memory).
To achieve this, add document.body.removeChild(document.getElementById('parent')); to your drop handler. I've made a js fiddle to demonstrate (with the id=spacer div removed and an extra paragraph below it to show the element is removed):
https://jsfiddle.net/dj825rbo/
(revision following comment clarifying that the origin element should disappear as the drag begins)
This is horrible, but works (horrible because you can't see the text while it is being dragged). It relies on a hidden element into which the origin's content is stored while the drag is proceeding. Replacing the 'drop' event listener with a 'mouseup' listeners, allows the content of the temp (hidden element to be transferred to the target where the mouse click was released)
https://jsfiddle.net/dj825rbo/1/
I have a div element with overflow-y: scroll which wasn't scrolling when I used the keyboard up and down arrows. I finally found a fix which was simply to add to my div tabindex="0". I am okay with this fix, but I was very surprised that if I select text in my div to make it the selected node (proved by using window.getSelection()), arrow keys still didn't work. Apparently the target of my keydown event goes to a parent which has a tabindex.
// DIRECTIONS:
// 1) Run the Fiddle
// 2) Using the mouse select some text in the green box
// 3) Use up and down arrows to scroll
// --- Scrolling was scoped to the parent so the green box doesn't scroll
// --- Add this to the scrollBox div to fix: tabindex="0"
window.addEventListener('keydown', listener);
function listener(evt) {
console.log(`${evt.code}: ${evt.target.tagName}, ${evt.target.className}`);
//console.log(window.getSelection());
}
.foreground {
height: 100%;
width: 100%;
}
.scroll-box {
background-color: green;
overflow: scroll;
max-height: 200px;
}
<div tabindex="0" class="foreground">
<div class="scroll-box" id="scrollBox">
Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test<br>Test
</div>
</div>
Why am I seeing this behavior? Why would tabindex take precedent over the focused/selected element when it comes to using keys for scrolling? Is the recommendation then that all of my divs which overflows with scroll or auto also include tabindex?
Thanks
Update: I forgot to mention that I do not control the parent div and cannot remove the parent div's tab index.
Update 2: Even more strange behavior regarding this... elements without tabIndex do not return undefined from tabIndex, instead they always return -1. Therefore if I do document.documentElement.tabIndex = document.documentElement.tabIndex, the value before and after will be -1 when read. Only, afterward the entire document is applying the tabIndex behavior such that scrollable divs cannot be used with keyboard navigation unless they have tabIndex="0".
Is there no way to detect whether or not an element has an implied tabIndex behavior set? What if I wanted to create a function that detected whether or not the container of selected text would scroll, I would have no way of detecting for sure because of the tabIndex read behavior?
I have created a pop out sideBar. In that sideBar I have a accordion which contains divs. Those divs are draggable. The user can drag those divs and position them main page.
The problem that I am experiencing is that when the divs are dragged they are not visible outside the accordion. This can been seen in This video.
I can see that it is to do with the overflow being set to hidden however when I remove this the accordion content is shown when it should be hidden.
overflow: hidden;
JSFiddle to further show my problem.
How could I possibly fix this / what are possible ways to get around it.
Try adding this to your css
.accordion-heading + div.accordion-body {
position: static;
}
Is this what you are looking for? Updated fiddle http://jsfiddle.net/gNAFY/3/
If this solved your problem, it seems that inside bootstrap.css file, at line 5245, "position: relative" rule makes your divs not appearing outside the accordion. So you need to "reset" position to static.
For "el + el" css selector to work in IE8 and earlier, don't forget the <!DOCTYPE>.
I have this demo
However the mouse over when dragged to left or right stops the toogle.
The hover() event didn't solve the problem.
Any idea ?
div.fileinputs {
position: relative;
display: none;
}
#show {
width: 200px;
height: 40px;
background-color: red;
z-index: -2px;
position: absolute;
}
<div id="show"></div>
<div class="fileinputs">Visible Panel Div</div>
$('#show').mouseover(function() {
$('.fileinputs').toggle();
});
Given that you want to simply show the element on mouseover and then hide it on mouseout, you should also use mouseout() to define the desired behavior you want when the mouse is removed:
$("#show")
.mouseover(function(){
$(".fileinputs").toggle();
})
.mouseout(function(){
$(".fileinputs").toggle();
});
Example. (It's choppy because fileinputs is a separate element, and it's not counting hovering over that as hovering over the show div).
But you should use hover, just to make it easier:
$("#show").hover(function(){
$(".fileinputs").show();
}, function(){
$(".fileinputs").hide();
});
Example. (Choppy for the same reason as above).
Since your desired behavior is definite, we'll just use show() for when the mouse is over it and hide() when it is removed.
By the way, it is preferred that you bind events using delegate() (for older versions of jQuery) or on() (for jQuery 1.7+):
$(document).on("mouseover mouseout", "#show", function(){
$(".fileinputs").toggle();
});
Example.
Though, you really should just use CSS for this. You can place fileinputs inside of show and use a child selector:
#show:hover > .fileinputs {
display: block;
}
Example. This one doesn't flicker because the element is inside the one that's getting the hover declarations attached to it, and CSS considers it as though you are still hovering over the parent element (because you technically are, as the target of the hover is within the boundaries of the parent [it would still work if it was outside the boundaries because the element is still nested]).
I think it's because you set your z-index on show to be -2. Once the fileInputs div is visible, it becomes on top of show, and as a result, mouseover for show no longer responds.
If you notice, if you hover from left to right over the red show div, but just below where the text is, the fileinputs div does in fact toggle.
If you add a border around the fileinputs div, the cause of the behavior will be clearer.
See: http://jsfiddle.net/pS9L8/
Moving your cursor over the region where the two divs overlap triggers a mouseover event, showing the hidden fileinputs div. Since that div is now displayed on top of show, your cursor is no longer directly over the original show div. You then continue to move your cursor, and as it moves outside the fileinputs region, that move is seen as another entrance to the underlying show div. Which again triggers the .toggle(), re-hiding the fileinputs div.
One quick fix is to switch to the jQuery custom event mouseEnter instead of mouseover (although you may get some jerky artifacts as jQuery reasons about the meaning of "over"). Depending on what you're trying to achieve, another option would be to reorder the two divs by z-index.
I've created an effect whereby an HTML element is initially hidden behind another HTML element, and the CSS 'top' value of the hidden element is animated to expose it from beneath the masking element in a smooth sliding motion.
Does anyone know if there is a way to recreate this effect without the masking element on top?
I want to avoid the jQuery'esque slideDown where the height of the element being shown is animated.
I have the feeling that this just isn't possible, but if someone is otherwise aware, your advise would be much appreciated.
You can easily do this with a wrapper that has overflow set to hidden
http://jsfiddle.net/xvNf6/1/
HTML
<div id="wrapper" style="height:0px;">
<div>content</div>
</div>
Sample CSS
#wrapper{width:300px;height:280px;margin:0 auto; overflow:hidden; background:#eee}
Javascript
//if you must not use jQuery
var animationTimer = setInterval(function(){
var wrapper = document.getElementById("wrapper");
wrapper.style.height = (parseInt(wrapper.style.height) + 1) + "px";
if(parseInt(wrapper.style.height) >= 280)
clearInterval(animationTimer)
},1);
//if you can use jQuery
$("#wrapper").animate({height:"280px"},1000);
Place your element within a parent div with overflow:hidden. Then, position your element beyond bounds of the parent div so that it is hidden.
#wrapper { overflow: hidden; }
#target { height: 100px; top: -100px; } /* shift element out of view */
You can then reveal it by animating to {"top":0} to get the slidedown effect that doesn't resize the height of the element.
Here's a rather crude demo: http://jsfiddle.net/7RSWZ/
Update: Here's another demo that attempts to deal better with different content sizes by dynamically setting the heights and top values. http://jsfiddle.net/7RSWZ/2/