Подтвердить что ты не робот

Отключить постоянное активное состояние

У меня есть ссылка, и если вы перетащите эту ссылку и отпустите, ссылка сохранит его активное состояние.

Пример: http://jsfiddle.net/Ek43k/3/

<a href="javascript:void(0);" id="foo" >Drag me</a>

#foo:active{
    color:red;
}

Как я могу предотвратить это?

(Только в IE и FF)

4b9b3361

Ответ 1

Отсоедините и снова подключите ссылку из дерева DOM, чтобы отключить ее активное состояние. Сделайте это, когда закончится перетаскивание, и вы получили это:

$('a').on('dragend',function(){
    var $this   = $(this),
        $parent = $this.parent(),
        $next   = $(this.nextSibling); // $.next() doesn't include text
    $this.detach().insertBefore($next);     
});

Не нужно связываться со своим HTML или CSS или удалять :active. Кажется, работает как в FF, так и в IE.


Изменить: Я обычно не пишу чистый Javascript для обработки DOM, поэтому качество этого может быть не самым высоким, но здесь это без 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);
        }
    };

})();

Я позаботился о нескольких проблемах, которые приходили на ум, чтобы полностью включить plug-and-play. Протестировано в Opera, Chrome, Firefox и Internet Explorer.


Изменить 2: Вдохновленный Крисом, еще один способ применить исправление - использовать атрибут ondragend непосредственно для подключения deactivator (не проверен):

<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>

Недостатком является то, что для каждого ссылки вручную/явно требуется атрибут ondragend с javascript для каждой ссылки. Думаю, это вопрос предпочтения.


Финал (?) Изменить: См. комментарии для делегатов/живые версии этих и ответ Криса.

Ответ 2

Это известная ошибка в Firefox, см. https://bugzilla.mozilla.org/show_bug.cgi?id=193321

У ошибки был статус "on-off-off" с несколькими отчетами; поведение нестандартно и зависит от браузера.

Вы можете создать для него обход, но вы застряли в javascript. После долгих поисков я решил, что если вы работаете в привилегированном режиме (т.е. Ваш код находится в расширении), вы не можете напрямую влиять на состояния псевдоселектора. Это означает, что вам осталось добавить/удалить имя класса:

<a href="#" onmousedown="this.className = '';" ondragend="this.className = 'inactive';" id="foo" >Drag me</a>

Попробуйте: http://jsfiddle.net/frsRS/

Если у вас do есть привилегированный режим, вы можете использовать метод, который Firebug использует в своей панели CSS, используя 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

Вот конкретный код для связывания делегатов с несколькими браузерами вместо того, чтобы помещать javascript inline (показано здесь для демонстрационных целей, но, как правило, плохая практика)

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';
});

Попробуйте: http://jsfiddle.net/HYJCQ/

Это использует стиль элемента, а не класс css, вы можете поменять методы по своему желанию.

Другой способ, предложенный Supr, заключается в удалении и немедленном добавлении элемента из DOM. Вы можете выполнить это, используя делегат:

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
    );
});

Попробуйте: http://jsfiddle.net/ymPfH/

Оба метода, которые используют делегирование, лучше подходят, чем элементы цикла. Таким образом, script будет применяться к любым тегам a, добавленным на страницу после загрузки (аналогично методам jQuery live или on работа).

Documentation

Ответ 3

Если jQuery является вариантом, я думаю, что этот код работает, по крайней мере, в FF: http://jsfiddle.net/Ek43k/89/

HTML

<a href="#" id="foo" class="inactive" >Drag me</a>

CSS

.inactive:active{color:red;}
.active:active{color:blue;}

JQuery

$('body').on('mousedown', 'a.inactive', function() {
    $(this).on('mousemove', function() {
        $(this).removeClass().addClass('active');
    });
});

$('body').on('mousedown', 'a.active', function() {
    $(this).removeClass().addClass('inactive');
});

Ответ 4

просто добавьте этот CSS:

#foo:hover {
    color: green;
}