4

window.getSelection() コードを使用しているときに、テキストを選択した後に小さな画像を表示するにはどうすればよいですか?

私が見つけた最も類似したものは、ユーザーのテキスト選択の隣に要素を配置するにはどうすればよいですか? しかし、それを適切に機能させることはできないようです:-sこれにちょっと慣れていないことも役に立ちません。

それを行うにはいくつかの簡単なコードが必要です。選択したテキストの近くにある限り、画像がどこに表示されるかは問題ではありません

-編集-

コメントで言ったように、アイデアは、選択したテキストの近くにボタン (最初に画像を考えましたが、ボタンの方が良い) を表示し (選択が行われた後)、選択されたものを引用するリンクを表示することです。ボタンが表示されなくなりました。

これは、テキスト選択を終了するときにマウス座標を引っ張って、表示するボタンのスタイルに x、y 座標を追加することで可能でしょうか?

-編集-

その座標のアイデアを念頭に置いて、私が望んでいたように動作させました。このhttp://motyar.blogspot.pt/2010/02/get-user-selected-text-with-jquery-and.htmlを見つけて、それで私はこれを思いつきました:

function getSelected() {
if (window.getSelection) {
    return window.getSelection();
}
else if (document.getSelection) {
    return document.getSelection();
}
else {
    var selection = document.selection && document.selection.createRange();
    if (selection.text) {
        return selection.text;
    }
    return false;
}
return false;
}

$(document).ready(function() {
var blank = '',
    selectionImage;
$('#mensagem').mouseup(function(e) {
    var selection = getSelected();

    if (!selectionImage) {
        selectionImage = $('<button>').attr({
            type: 'button',
            title: 'Citar Texto seleccionado',
            id: 'quote-place'

        }).html("Citar").css({
            "color": "red"
        }).hide();

        $(document.body).append(selectionImage);

    }
    $("#quote-place").click(function quote() {
        var txt = '';
        if (window.getSelection) {
            txt = window.getSelection();
        }
        else if (document.getSelection) {
            txt = document.getSelection();
        }
        else if (document.selection) {
            txt = document.selection.createRange().text;
        }
        else {
            return;
        }
        document.aform.selectedtext.value = txt;

    }).mousedown(function() {

        if (selectionImage) {
            selectionImage.fadeOut();
        }
    });

    selectionImage.css({
        top: e.pageY - 30,
        //offsets
        left: e.pageX - 13 //offsets
    }).fadeIn();
});
});​

http://jsfiddle.net/ordhor/2Gc8c/

<div>ボタンが表示され続けるテキストを選択せず​​にクリックすると、問題が発生します。テキストを選択したときにのみ表示されるはずで、修正方法がわかりません...

4

2 に答える 2

2

imageそれが挿入したい画像要素であるとしましょう。<span>テキストノードの位置を計算できないため、選択したテキストの後にプレースホルダー要素を配置するという考え方です。したがって、このCSSから始めます。

.place-holder {position: relative;}
.quote-image {
    position: absolute;
    top: 0;
    left: 0;
}

プレースホルダークラスは<span>要素用であり、position配置する画像のプロパティは、幅をゼロに保つために絶対的に配置されます<span>

次に、選択が行われたかどうかを確認します。残念ながら、選択が行われたときに発生する標準イベントはありません。イベントは、onselectテキストフィールドで選択が行われた場合にのみ発生し、選択がキャンセルされた場合でも発生しません。

ただし、選択は通常、マウスとキーボードのイベントを使用して行われるため、それらを聞いて、選択が行われたかどうかを確認できます。

var prevRng;
function checkSelection() {
    var s = getSelection(), r = s.rangeCount && s.getRangeAt(0);
    if (prevRng) {
        if (!r || r.endContainer !== prevRng.endContainer
                || r.endOffset !== prevRng.endOffset) {
            // The selection has changed or been cleared
            selectionClear();
        }
    }
    if (r) setPlaceHolder(r);
}
document.addEventListener("mouseup", checkSelection);
// mousedown usually clears the selection
document.addEventListener("mousedown", checkSelection);
// You can use the keyboard to extend the selection, or select all (Ctrl+A)
document.addEventListener("keyup", checkSelection);

prevRngは、行われた選択を格納するための関数スコープ内の変数です。これで、作業コードを作成できます。

function setPlaceHolder(range) {
    if (range.startContainer === range.endContainer
            && range.startOffset === range.endOffset) {
        // The selection is clear
        prevRng = null;
        return;
    }
    prevRng = range;
    var endc = range.endContainer, span = document.createElement("span");
    span.className = "place-holder";
    span.appendChild(image);
    if (endc.nodeType === Node.TEXT_NODE) { // Node.TEXT_NODE === 3
        var p1 = endc.nodeValue.substring(0, range.endOffset),
            p2 = endc.nodeValue.substring(range.endOffset);
        endc.nodeValue = p1;
        if (p2)
            endc.parentNode.insertBefore(document.createTextNode(p2),
                    endc.nextSibling);
    }
    endc.parentNode.insertBefore(image, endc.nextSibling);
}

function selectionClear() {
    if (!prevRng) return;
    var endc = prevRng.endContainer;
    if (endc.nextSibling.className === "place-holder") {
        endc.parentNode.removeChild(endc.nextSibling);
        if (endc.nodeType === Node.TEXT_NODE
                && endc.nextSibling.nodeType === Node.TEXT_NODE) {
            // Joining previously divided text nodes
            endc.nodeValue += endc.nextSibling.nodeValue;
            endc.parentNode.removeChild(endc.nextSibling);
        }
    }
}

編集:私はあなたの質問を誤解したようです。選択後に画像を挿入したいと思いました...では、実際にいつ選択が行われるのか知りたいですか?

編集2:リクエストに一致するように多かれ少なかれすべてを変更しました。

于 2012-05-27T11:34:59.793 に答える