2016-08-25 7 views
3

何らかの理由で、pasteEventを処理するときにmyTextArea.selectionStartが正常に動作しますが、ドロップイベントを処理すると間違っています。ドロップイベントのターゲットカーソル位置をテキスト領域に取得するにはどうすればよいですか?たとえば、ユーザーがテキストエリアのコンテンツの先頭または最後にテキストをドラッグ/ドロップするかどうかを知りたいとします。テキスト領域の値を変更できないとします(例のように)。私は便宜のために私の例ではjQueryを使用しました。それは問題の一部ではありません。ドロップイベントを処理するときにカーソルインデックスを見つける方法は?

編集:明らかにされていない可能性があります。あなたは(テキストエリアにフォーカスする前に)コードスニペットを実行した場合は、テキスト領域の最後にドラッグアンドドロップテキストは、それが0として落下位置を報告する代わりに、予想される18

$('#x').on('drop', function(event){ 
 
    $('#y').html(event.target.selectionStart); 
 
    return false; 
 
}); 
 

 
$('#x').on('paste', function(event){ 
 
    $('#z').html(event.target.selectionStart); 
 
    return false; 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div>Try drag/dropping this text before and after existing text, then try with copy/paste</div> 
 
<textarea id="x">some existing text</textarea> 
 
<div>The drop position was <span id="y"></span></div> 
 
<div>The paste position was <span id="z"></span></div>

+1

私は質問が表示されません。あなたのコードは正常に動作し、ドロップアンドペーストイベントの位置を表示します。 –

+0

コードを実行して「既存のテキスト」の最後にテキストをドロップすると、「ドロップ位置は0」と表示されます(テキストエリアにはまだフォーカスがないと仮定します)。 @TobiasK。テキストエリアの終わりにフォーカスし、テキストを先頭にドラッグすると、誤った番号が報告されます。 – AlexMA

+0

@TobiasK。私は "再現するステップ"で質問を更新しました – AlexMA

答えて

2

私はこの夜、あなたの問題をハックする方法を少し考えました。私の現在の解決策はここにあります:

あなたはドロップアンドペーストイベントをキャンセルしますが、私はそれらを起こさせます。その後、私は古い文字列と新しい文字列の違いを計算し、これで、あなたは変更の位置を得ることができます:)

あなたのケースで動作します。

let drop_event = 'drop'; 
 
let paste_event = 'paste'; 
 
let events = [drop_event, paste_event]; 
 
var old_val = $('#x').val(); 
 
var current_event = ''; 
 
var cursor_pos = 0; 
 
var sel_len = 0; 
 

 
// iterate through each event 
 
$.each(events, function(key, value) { 
 
    $('#x').on(value, function(event){ 
 
    // saving old value and the current event 
 
    old_value = $('#x').val(); 
 
    current_event = value; 
 
    }); 
 
}); 
 

 

 
$('#x').on('input', function(event){ 
 
    // position, where the string change starts 
 
    cursor_pos = event.target.selectionStart; 
 
    if (current_event == drop_event){ 
 
    // drop events are eays 
 
    $('#y').html(cursor_pos); 
 
    } else { 
 
    // substract the length of change 
 
    $('#z').html(cursor_pos - diff_string($('#x').val(), old_val)); 
 
    } 
 
    // set old string value 
 
    $('#x').val(old_val); 
 
}); 
 

 
/* 
 
* Calculates the difference between two strings, 
 
* iff one string is substring of the other string 
 
* @param a first string 
 
* @param b second string 
 
* @return differnce as int 
 
*/ 
 
function diff_string(a, b){ 
 
    var len = a.length > b.length ? b.length : a.length; 
 
    var index = 0; 
 
    while (a.charAt(index) == b.charAt(index)) 
 
    index += 1; 
 
    a = a.substr(index); 
 
    b = b.substr(index); 
 
    var diff = a.length > b.length ? a.indexOf(b) : b.indexOf(a); 
 
    diff = diff == 0 ? a.length + b.length : diff; 
 
    return diff; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div>Try drag/dropping this text before and after existing text, then try with copy/paste</div> 
 
<textarea id="x">123456789 some existing text</textarea> 
 
<div>The drop position was <span id="y"></span></div> 
 
<div>The paste position was <span id="z"></span></div>

+1

それは巧妙な考えです。私たちはこれに頼らなければならないのは残念ですが、うまくいきます。私は最終的にドロップイベントにあなたのために(イミクリティカルな)プロパティが含まれていることを期待しています。 – AlexMA

関連する問題