Preserve appearance of dragged A element when using html5 draggable attribute - javascript

How can i preserve appearance of the dragged A element when using 'draggable' html5 attribute. On some browsers (Safari & Chrome) when dragging anchor, dragged helper is replaced with browser native implementation of dragged element as seen on the screenshots:
When dragging DIV
When dragging A
HTML
<div class="draggable">Draggable DIV</div>
Draggable A
CSS
$('.draggable').attr('draggable', true);
Here is the quick JSBin i assembled to demonstrate this issue http://jsbin.com/pihayeceza/1/edit
Thanks

I'm able to preserve the appearance of the dragged element by using DataTransfer.setDragImage. If I add the following code to the JavaScript in your jsbin instance, it work for me on Firefox, Chrome and Safari:
$('a.draggable').on('dragstart', function (ev) {
var dt = ev.originalEvent.dataTransfer;
// In IE browsers, setDragImage does not exist. However, the issue we are
// trying to fix does not happen in these broswers. So if setDragImage is not
// available, then just don't do anything.
if (dt.setDragImage)
dt.setDragImage(ev.target, 0, 0);
});
The dataTransfer field of the event has a DataTransfer object associated with the drag operation. You have to fetch it from the original DOM Event rather than from the jQuery Event wrapper, so ev.originalEvent.dataTransfer.
For IE browsers, setDragImage is not present but the problem reported in the question does not occur in the first place so if setDragImage is absent, we just don't call it.
A bin with the updated code.

This problem happens because the default behavior of dragging a link with an href attribute is to create an image containing the url to be used as the drag placeholder. You can fix this by removing the href attribute, however, to get around that without having to remove the href attribute you can use mousedown/up event handlers to remove the attribute and then re-add it, leaving the anchors clickable*.
$('.draggable').attr('draggable', true).on('mousedown', function () {
if ($(this).is('a')) {
$(this).data('href', this.href);
$(this).removeAttr('href');
}
}).on('mouseup', function () {
if ($(this).is('a')) {
$(this).attr('href', $(this).data('href'));
}
}).on('click', function () {
console.log(this.href);
});
.draggable {
margin: 10px;
display: block;
width: 200px;
background: #fafafa;
color: #333;
text-decoration: none;
height: 40px;
border: 1px solid #eaeaea;
line-height: 40px;
text-align: center;
cursor: move;
border-radius: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="draggable">Draggable DIV</div>
Draggable A
*Note: stack snippets doesn't let you follow the link.

Wrap your anchor tags with a div and set draggable="false" on the anchor tag.
<div class="draggable">
Draggable A
</div>
You will need additional styling to prevent the button/link from looking blue and underlined.
.draggable a {
color: inherit;
text-decoration: inherit;
}
modified your jsbin here
http://jsbin.com/rebayif/edit

Related

How to make a css class work for only one object at a time?

I want a css class to work for only one object at a time. I want to activate it only when I hover over an object with that class. When my cursor leaves that object the class should still be activated. But when I hover over a second object with that class it should simultaneously start working for that object and stop working for the previous object.
The css I am trying to implement this way is for a set of thumbnail images and is as follows
{
box-shadow: 0 0 5px red;
}
None of the images should have this css activated by default when the page loads. How do I do it? Open to any kind of solution here css/javascript/jquery/plugin/anything elce. Can anyone help?
Use :hover:
The :hover CSS pseudo-class matches when the user designates an element with a pointing device, but does not necessarily activate it. It is generally triggered when the user hovers over an element with the cursor (mouse pointer).
REF: https://developer.mozilla.org/en/docs/Web/CSS/:hover
div:hover {
box-shadow: 0 0 5px red;
}
<div>11111</div>
<div>22222</div>
<div>33333</div>
Solution 2: use mouseover event (or hover as #abeyaz's answer), remove all active then add the active class to the current one.
The hover() function is more high level - it's built to call functions to handle both a mouseenter event and a mouseleave event. It's very convenient for a UI element that has a hover and normal state (e.g. a button.)
The mouseover() function specifically binds to the mouseover event. It's best for situations where you only care when the mouse has crossed the border into an element and you don't really care what happens if it leaves. It's also the function to call when you want to trigger the event on some element.
jQuery provides hover() as a convient way to handle common UI hovering states.
mouseover() is more for manually accessing the specific browser event.
REF: https://www.quora.com/jQuery/jQuery-What-is-the-difference-between-the-hover-and-mouseover-functions
$('div').on('mouseover', function(){
$('div').removeClass('active');
$(this).addClass('active');
})
.active {
box-shadow: 0 0 5px red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>11111</div>
<div>22222</div>
<div>33333</div>
You can do it easily using jquery as in this fiddle https://jsfiddle.net/4f1g1yxf/. You can do it easily using jquery as in fiddle below. The idea is simple; remove the class from activated one first, then add to the new one.
$(".box").hover(function(){
$(".box.activated").removeClass("activated");
$(this).addClass("activated");
});
.activated {
box-shadow: 0 0 5px red;
}
.box {
display: inline-block;
margin-right: 30px;
width: 50px;
height: 50px;
line-height: 50px;
text-align: center;
border: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">box1</div>
<div class="box">box2</div>
<div class="box">box3</div>
Try the next approach:
CSS:
.abc {
box-shadow: 0 0 5px red;
}
HTML:
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<p>hello</p><br>
<p>hello</p><br>
<p>hello</p><br>
<p>hello</p><br>
JS:
jQuery('*')
.bind('mouseover', function (event) {
var o = jQuery(this);
if (!o.find('.abc').length) {
o.addClass('abc');
}
})
.bind('mouseout', function () {
jQuery(this).removeClass('abc');
});
P.S. Instead of '*' put the proper class or element identifier to limit event scope.

jQuery hover event toggle class not triggering

I have been debugging this issue for a good while now and I am so confused to why this isn't working.
As you can see I am running the following code on JSFiddle and it seems to work without any issues at all:
$(".assistance-submit-btn").hover(function() {
$(this).children('i').toggleClass("assistance-submit-btn-mouseover");
});
.assistance-submit-btn {
font-size: 1.4rem;
font-weight:300;
padding: 10px 20px;
background: none;
border: 2px solid #333;
border-radius: 10rem;
color: #333;
margin: 25px auto 0;
display: block;
}
.assistance-submit-btn-mouseover {
transform:translate(10px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="assistance-submit-btn" value="Submit">Submit <i class="fa fa-caret-right"></i></button>
As you can see when the assistance-submit-btn element is hovered it will add a class to the i element.
This code is a direct copy from my local website that I am developing however for some reason on my local system it will not execute when the assistance-submit-btn element is hovered.
So far I have tried adding a CSS hover to the element itself just to see whether or not the element was behind another element and unable to hover.
The only difference that I can think of on my local setup is that the assistance-submit-btn element is pulled in by AJAX. Could this effect the jQuery hover event? Any suggestions to why this might be happening would be much appreciated.
Thanks
UPDATE: Forgot to mention I am getting no errors within my console.
Yes, it's because of Ajax dynamic content. Use this code:
$(document).on({
mouseenter: function () {
$(this).children('i').addClass("assistance-submit-btn-mouseover");
},
mouseleave: function () {
$(this).children('i').removeClass("assistance-submit-btn-mouseover");
}
});

How to MouseOver behind an object?

I'm trying to mouseover an image which is behind an another image.
Is there any way to render the front image like it is not there, so I can mouseover the other image behind it?
Example can be seen here:
I can't mouseover the characters which are behind the logo boundingbox.
You can set the CSS property pointer-events: none on the obstructing object... but be aware that pointer events are all or nothing; mouseovers and hovers will pass right through, but so will clicks.
Here is a description of the value, from the Mozilla Developer's Network:
none: The element is never the target of mouse events; however, mouse events may target its descendant elements if those descendants have pointer-events set to some other value. In these circumstances, mouse events will trigger event listeners on this parent element as appropriate on their way to/from the descendant during the event capture/bubble phases.
I've put together a little example. In this example, I'm using onmouseover and onmouseout, since that's what you use on your website, but you could just as easily use the CSS :hover pseudo-selector. Here's a jsfiddle version of the example, and the stack snippet is below.
.hoverable {
width: 100px;
height: 100px;
background-color: blue;
}
.obscuring {
/* this first line is the important part */
pointer-events: none;
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 100px;
background-color: red;
opacity: 0.5;
}
<div class="hoverable" onmouseover="this.style.backgroundColor = 'green'" onmouseout="this.style.backgroundColor = 'blue'"> </div>
<div class="obscuring"> </div>
You can create some invisible divs on top of the whole thing and put the hover behaviour on them. Then control the characters position with the position of the invisible divs.
Hope it makes sense.

click event on a iframe wrapped element

I may be losing my mind..
I have a div element which is holding an IFRAME. I registered a click event using javascript. That click event is not working when I am on IFRAME (grey region) but when I am clicking outside region of IFRAME (blue region), the click event is working fine.
What should I do to make this click event work even on IFRAME?
Fiddle
HTML:
<div id="main">
<iframe></iframe>
</div>
Javascript
var main = document.getElementById('main');
main.onclick = function () {
alert('hello');
}
PS: IFRAME is generating dynamically from a plugin, I can't access this code
You can add pointer-events: none; to iFrame's CSS - this way it will not capture clicks. Supported in FF, Safari, Chrome, Opera and IE11+.
Modify your fiddle:
iframe {
pointer-events:none;
width: 300px;
height: 300px;
border: 1px solid black;
background-color: grey;
}
New fiddle
Please note user will not be able to interact with iFrame this way.

jQuery fadeIn making page scroll to top / jump

jQuery is destroying me this week. I'm using fadeIn via jQuery on my portfolio site (http://www.codeisdna.com) to open up a section once it's clicked. Here's the HTML code I'm using:
<div class="project first project_name">
<div class="title">
Project Title!
<div class="date">2012</div>
</div>
<a class="expand" title="Click to expand the project." href="#project_1">Project Title!</a>
</div>
Which opens up a tab:
<div id="project_1" class="project_full pname"></div>
Using this js:
$(document).ready(function(){
$(".project").click(function() {
$("a.expand").removeClass("hovered");
$(this).find("a.expand").addClass("hovered");
$(".project_full").hide();
var selected_tab = $(this).find("a").attr("href");
$(selected_tab).fadeIn();
return false;
});
});
EDIT: Here is the CSS code for .project_full (the expanded tab -- the CSS code for .project is irrelevant):
.project_full {
display: none;
margin-top: 20px;
width: 100%;
max-height: 450px;
padding: 20px 0px;
text-align: center;
background: url(../img/code.jpg) top center no-repeat fixed #293134;
box-shadow: inset 0 0 10px rgba(0,0,0,0.5);
color: #fff;
overflow: hidden;}
.project_full .wrapper {position: relative;}
I've tried assigning a fixed height to a parent div, e.PreventDefault() doesn't work (I'm using anchor based tabs, so nothing of that sort will work), and so on. The page jumps on the first click and with each successive click. I know it jumps due to the missing content once the div is unhidden and "rehidden."
I'm wondering if HTML5 data attributes would remedy this? But then again, why would it as the anchor would still exist, albeit it being blank (#).
Hopefully someone with a lot more JS experience can help me!
Either change your handler adding preventDefault
$(".project").click(function(e) {
e.preventDefault();
$("a.expand").removeClass("hovered");
$(this).find("a.expand").addClass("hovered");
$(".project_full").hide();
var selected_tab = $(this).find("a").attr("href");
$(selected_tab).fadeIn();
return false;
});
Or change your a tag href attribute to be something like 'javascript:'
Or replace a tag with say span and let your click handler remain unchanged.
Or add name attribute to a tag (<a name='project_1'></a>) in right place as it is scrolling to this tag or beginning of the page as there is no ancor with corresponding name

Categories

Resources