リンクがあります。このリンクをドラッグして放すと、リンクはアクティブな状態を維持します。
例: http://jsfiddle.net/Ek43k/3/
<a href="javascript:void(0);" id="foo" >Drag me</a>
#foo:active{
color:red;
}
どうすればこれを防ぐことができますか?
(IE、FFのみ)
リンクがあります。このリンクをドラッグして放すと、リンクはアクティブな状態を維持します。
例: http://jsfiddle.net/Ek43k/3/
<a href="javascript:void(0);" id="foo" >Drag me</a>
#foo:active{
color:red;
}
どうすればこれを防ぐことができますか?
(IE、FFのみ)
これは Firefox の既知のバグです。https://bugzilla.mozilla.org/show_bug.cgi?id= 193321 を参照してください。
バグは、いくつかのレポートでオンとオフのステータスを持っています。動作は非標準であり、ブラウザ固有です。
回避策を構築することはできますが、javascript に行き詰まっています。よく調べた結果、特権モードで実行していない限り (つまり、コードが拡張機能内にある場合)、疑似セレクターの状態に直接影響を与えることはできないと判断しました。つまり、クラス名を追加/削除する必要があります。
<a href="#" onmousedown="this.className = '';" ondragend="this.className = 'inactive';" id="foo" >Drag me</a>
試してみてください: http://jsfiddle.net/frsRS/
特権モードを使用している場合は、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);
編集
これは、JavaScript をインラインに配置するのではなく、クロスブラウザー デリゲートをバインドするための特定のコードです (ここではデモンストレーション目的で示されていますが、一般的には悪い習慣です)。
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/
委任を利用する両方の方法は、要素をループするよりも優れたアプローチです。そうすればa
、ロード後にページに追加されたすべてのタグにスクリプトが適用されます (jQuerylive
またはon
メソッドの動作と同様)。
ドキュメンテーション
ondragend
) - https://developer.mozilla.org/en-US/docs/Drag_and_DropinIDOMUtils
- https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/inIDOMUtilsDOMツリーからリンクを切り離して再接続し、アクティブな状態を無効にします。ドラッグが終了し、これを取得したときにこれを実行します。
$('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の両方で動作するようです。
編集:私は通常、DOM処理用の純粋なJavascriptを記述しないため、これの品質は一流ではない可能性がありますが、ここでは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);
}
};
})();
完全にプラグアンドプレイにするために頭に浮かんだいくつかの問題に対処しました。Opera、Chrome、Firefox、InternetExplorerでテスト済み。
編集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の属性を各リンクで手動/明示的に指定する必要があることです。好みの問題だと思います。
最終(?)編集:これらのデリゲート/ライブバージョンとクリスの回答についてはコメントを参照してください。
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');
});
このCSSを追加するだけです:
#foo:hover {
color: green;
}