Dragula on drag the nested image doesn't stay styled - javascript

Codepen here:
http://codepen.io/jasonsawtelle/pen/jqbeXd
//HTML
<div id="drag_container">
<div><img src="http://placehold.it/200x200/ffcc00/ffffff"/></div>
<div><img src="http://placehold.it/200x200/99cc00/ffffff"/></div>
<div><img src="http://placehold.it/200x200/333333/ffffff"/></div>
<div><img src="http://placehold.it/200x200/ff0000/ffffff"/></div>
</div>
//SCSS
//Dragula
.gu-mirror{position:fixed!important;margin:0!important;z-index:9999!important;opacity:.8;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";filter:alpha(opacity=80)}.gu-hide{display:none!important}.gu-unselectable{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.gu-transit{opacity:.2;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";filter:alpha(opacity=20)}
// Example
#drag_container{
display: flex;
div{
img{
height: 100px;
}
}
}
//JS
dragula([document.querySelector('#drag_container')])
It's a basic setup and Dragula is working, but when I drag a div, the contained, css resized image is popping to full-size during the drag event.

I am not sure if this is the right solution. First of all, redefining rules for .gu-mirror breaks single responsibility principle of the .gu-mirror clas. It's job was not to style in a a manner specifict to the element.
One problem might be that by default, that object when dragged it's attached to body elements and it looses some styling if that style was defined based on parents (which is not the case when is's attached to body container. There is an option mirrorContainer where you can set so the dragged element won't loose its styling

You should set .gu-mirror img to width: 100px; to achieve what you want. See the CodePen for the result.
.gu-mirror is the div added by the Dragula plugin to mirror the selected element to drag somewhere else.

Related

Hide parent element on dragstart event

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/

How to combine jQuery SlimScroll and sortableUI?

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.

Jquery: Hide and show a div when image is hover

I wonder if someone can help me find a solution to an effect hover to an image in my blog.
The idea was when I hover an image, you see a div with the image information, link project name, date,...
What i have done is, assign two classes do the div information, class show and class hide, and at the beginning it apears with a class hide.
Then with jQuery/JavaScript when the img:hover it remove the class hide and add a class show.
the problem is, when i do hover to a image, appears the information of all images.
I am wonder if some can help me to make just appear the information of the image that the mouse are hover.
My HTML:
<div id="content">
<img src="images/1.jpg" alt="Projecto 1" height="290" width="220" />
<div class="information hide">
<h2>Titulo</h2>
<p>Lorem Ipsun</p>
Read More
</div>
</div>
<div id="content">
<img src="images/1.jpg" alt="Projecto 1" height="290" width="220" />
<div class="information hide">
<h2>Titulo</h2>
<p>Lorem Ipsun</p>
Read More
</div>
</div>
My CSS:
body div.information {
background: rgba(219, 49, 49, 0.52);
width: 220px;
height: 290px;
position: relative;
top: -290px;
}
/* HOVER EFFECT */
.hide {
display: none;
}
.show {
display: block;
}
My JavaScript:
$('img').hover(function() {
$('.information').addClass("mostrar");
$('.information').removeClass("hide");
});
And by the way, if some one can tell me, how to hide the information again when the image is not hover, I appreciate to.
What about something simpler:
$("div.content > img").hover(function() {
$(this).next(".information").show(); //hover in
}, function() {
$(this).next(".information").hide(); //hover out
});
This way, using jquery .show and .hide you don't need to use the css which you created for the hover effect, since these jquery's functions already take care of the attributes.
If you don't need to support IE7 and lower, you can do this with just CSS using the adjacent sibling combinator selector, no JavaScript required:
img + div.information {
display: none;
}
img:hover + div.information {
display: block;
}
That says: "Hide div.information when it's immediately after an img" but "Show div.information when it's immediately after a hovered img". The latter rule being both later in the CSS and (I think) more specific, it wins when the image is hovered and not when it isn't.
Live example - Works in modern browsers, including IE8 and higher.
the problem is, when i do hover to a image, appears the information of all images.
I believe this is because you're referencing the generic information class, not the id of a single div. Instead, use the adjacent sibling reference to get only the information for the image you're hovering. You could use the :nth-child() selector.
$("#content:nth-child(1)")
Also, you shouldn't have multiple divs with the same id.
$(this).parent().find('.information').addClass("mostrar")
.removeClass("hide");
This will grab the parent of the individual img which is being hovered, search within the parent and find the .information specific to that img.
Try this:
$('img').hover(function(){
$(this).siblings('.information').removeClass('hide').addClass('mostrar').addClass('show');
}, function(){
$(this).siblings('.information').removeClass('show').removeClass('mostrar').addClass('hide');
});
Try this
$('img').hover(function() {
$('.information').addClass("hide")
$(this).next().addClass("mostrar").removeClass("hide");
}, function(){
$('.information').addClass("hide").removeClass("mostrar")
});

toggle jquery - issue

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.

jQuery code for sliding div (accordion)

I am looking for some good jQuery, XHTML & CSS code to achieve the effect as seen in the following image:
http://i48.tinypic.com/a3o4sn.jpg
Obviously this is a static image, what is supposed to happen is the text and the transparent background is hidden, and when you put your mouse over the image it slides up into view and down again onmouseout.
I think this is an accordion, can anyone point me in the right direction (or maybe you've seen another site that does this)?
Your may be interested in this great resource: Sliding Boxes and captions
DEMO
I've recently used a jquery plugin that does something quite similar.
You may find the plugin does all you need, or look at the source to see how the slide-in effect is achieved (although, of course, there's more than one way to do just about anything).
The plug-in is called Showcase
Its home page has more info and demo and tutorials
Finally, as an added demo, here's the site where I used it.
HTH
My approach to this effect is to have a div with overflow: hidden and the transparent black div with a top margin that puts it "outside" the container." Using .hover() you can tell the black div to slide up when the mouse is over the container div, and to slide away again when the mouse leaves.
Markup:
<div id='container'>
<div id='slider'>Some Text</div>
</div>
Styles:
div#container {
height: 100px;
width: 100px;
overflow: hidden;
}
div#slider {
width: 100px;
height: 40px;
margin-top: 100px;
background: black;
}
And your script:
$('#container').hover (
function () {
$('#slider').css('margin-top', '60px'),
$('#slider').css('margin-top', '100px');
);
I forget if you have to put the 60px in quotes or not, or if you have to pass 60 as an int, play around with it, but hopefully this gets you started.

Categories