I have a link, and if you drag this link then release, the link will keep his active state.
Example: http://jsfiddle.net/Ek43k/3/
<a href="javascript:void(0);" id="foo" >Drag me</a>
#foo:active{
    color:red;
}
How can I prevent this?
(Only in IE and FF)
This is a known bug in Firefox, see https://bugzilla.mozilla.org/show_bug.cgi?id=193321
The bug has had an on-and-off status with several reports; the behavior is non-standard and browser-specific.
You can build a work-around for it, but you're stuck with javascript. After much searching, I determined that unless you're running in privileged mode (i.e. your code is in an extension), you cannot directly influence the pseudo-selector states. That means you're left with adding/removing a class name:
<a href="#" onmousedown="this.className = '';" ondragend="this.className = 'inactive';" id="foo" >Drag me</a>
Try it: http://jsfiddle.net/frsRS/
If you do have privileged mode, you can use the method that Firebug employs in their CSS Panel, using inIDOMUtils.setContentState
var node = document.getElementById("foo");
var domUtil = Components.classes["@mozilla.org/inspector/dom-utils;1"].getService(Components.interfaces.inIDOMUtils);
domUtil.setContentState( node , 1);
Edit
Here is specific code for binding cross-browser delegates rather than putting the javascript inline (shown here for demonstration purposes, but generally bad practice)
function addEvent(ele, evnt, funct) {
  if (ele.addEventListener) // W3C
    return ele.addEventListener(evnt,funct,false);
  else if (ele.attachEvent)  // IE
    return ele.attachEvent("on"+evnt,funct);
}
addEvent(document.body, 'mousedown', function (e) {        
    if(e.target.tagName == 'A') e.target.style.color = '';
});
addEvent(document.body, 'dragend', function (e) {
    if(e.target.tagName == 'A') e.target.style.color = 'blue';
});
Try it: http://jsfiddle.net/HYJCQ/
This uses the element's style rather than a css class, you can swap out the methods as desired.
Another way, as suggested by Supr, is to remove and immediately re-add the element from DOM. You can accomplish this using a delegate as well:
function addEvent(ele, evnt, funct) {
  if (ele.addEventListener) // W3C
    return ele.addEventListener(evnt,funct,false);
  else if (ele.attachEvent)  // IE
    return ele.attachEvent("on"+evnt,funct);
}
addEvent(document.body, 'dragend', function (e) {
    if(e.target.tagName != 'A') return;
    var parent = e.target.parentNode;
    var sib = e.target.nextSibling;
    parent.insertBefore(
        parent.removeChild(e.target),
        sib
    );
});
Try it: http://jsfiddle.net/ymPfH/
Both methods that utilize delegation are better approaches than looping elements -- that way, the script will apply to any a tags added to the page after load (similar to how jQuery's live or on methods work).
Documentation
ondragend) - https://developer.mozilla.org/en-US/docs/Drag_and_Drop
inIDOMUtils - https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/inIDOMUtils
Detach and reattach the link from the DOM tree to disable its active state. Do this when the drag ends and you've got this:
$('a').on('dragend',function(){
    var $this   = $(this),
        $parent = $this.parent(),
        $next   = $(this.nextSibling); // $.next() doesn't include text
    $this.detach().insertBefore($next);     
});
No need to mess with your HTML or CSS or do away with :active. Seems to work in both FF and IE.
Edit: I don't usually write pure Javascript for DOM-handling so the quality of this might not be top notch, but here it is without jQuery:
(function(){
    var previousOnload = window.onload || function noop(){};
    window.onload = function (){
        // Call any previously added onload callbacks
        previousOnload();
        // Add deactivator to each <a> element
        var elements = document.getElementsByTagName('a');
        for (var i=0; i<elements.length; i++){
            elements[i].ondragend = deactivate;
        }
        function deactivate(){
            var parent   = this.parentNode,
                position = this.nextSibling;
            parent.removeChild(this);
            // Using insertBefore instead of appendChild so that it is put at the right position among the siblings
            parent.insertBefore(this, position);
        }
    };
})();
I took care of a few issues that came to mind to make it fully plug-and-play. Tested in Opera, Chrome, Firefox and Internet Explorer.
Edit 2: Inspired by Chris, another way to apply the fix is to use the ondragend attribute directly to connect the deactivator (not tested):
<head>
    <script>
        function deactivate(){
            var parent   = this.parentNode,
                position = this.nextSibling;
            parent.removeChild(this);
            // Using insertBefore instead of appendChild so that it is put at the right position among the siblings
            parent.insertBefore(this, position);
        }
    </script>
</head>
<body>
    <a href="#" ondragend="deactivate()">Drag me</a>
<body>
The downside is that it requires the ondragend attribute with javascript to be specified on each link manually/explicitly. I guess it's a matter of preference.
Final (?) Edit: See comments for delegate/live versions of these and Chris' answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With