Получите выбранное текстовое положение и поместите элемент рядом с ним

tl; доктор

Идея состоит в том, чтобы позволить пользователю отмечать любой текст и видеть, что меню раскрывается только рядом с выбором с возможными действиями для применения к выделенному тексту.


Я должен расположить абсолютную расположенную кнопку рядом с выделенным текстом пользователя.

Я связываю событие mouseUp с Документом и получаю выделенный текст, но я в настоящее время вне идей о том, как знать, где фактический выбор расположен, не перенося его в некотором элементе, потому что выбор текста может быть через несколько элементов, и это смешало бы структуру, если я перенесу его.

24
задан vsync 21 November 2019 в 22:19
поделиться

2 ответа

Вы можете расположить диапазон маркера в конце выделения, получить его координаты с помощью jQuery, разместить кнопку в этих координатах и ​​удалить диапазон маркера.

Следующее должно помочь вам начать :

var markSelection = (function() {
    var markerTextChar = "\ufeff";
    var markerTextCharEntity = "";

    var markerEl, markerId = "sel_" + new Date().getTime() + "_" + Math.random().toString().substr(2);

    var selectionEl;

    return function(win) {
        win = win || window;
        var doc = win.document;
        var sel, range;
        // Branch for IE <= 8 
        if (doc.selection && doc.selection.createRange) {
            // Clone the TextRange and collapse
            range = doc.selection.createRange().duplicate();
            range.collapse(false);

            // Create the marker element containing a single invisible character by creating literal HTML and insert it
            range.pasteHTML('<span id="' + markerId + '" style="position: relative;">' + markerTextCharEntity + '</span>');
            markerEl = doc.getElementById(markerId);
        } else if (win.getSelection) {
            sel = win.getSelection();
            range = sel.getRangeAt(0).cloneRange();
            range.collapse(false);

            // Create the marker element containing a single invisible character using DOM methods and insert it
            markerEl = doc.createElement("span");
            markerEl.id = markerId;
            markerEl.appendChild( doc.createTextNode(markerTextChar) );
            range.insertNode(markerEl);
        }

        if (markerEl) {
            // Lazily create element to be placed next to the selection
            if (!selectionEl) {
                selectionEl = doc.createElement("div");
                selectionEl.style.border = "solid darkblue 1px";
                selectionEl.style.backgroundColor = "lightgoldenrodyellow";
                selectionEl.innerHTML = "&lt;- selection";
                selectionEl.style.position = "absolute";

                doc.body.appendChild(selectionEl);
            }

            // Find markerEl position http://www.quirksmode.org/js/findpos.html
        var obj = markerEl;
        var left = 0, top = 0;
        do {
            left += obj.offsetLeft;
            top += obj.offsetTop;
        } while (obj = obj.offsetParent);

            // Move the button into place.
            // Substitute your jQuery stuff in here
            selectionEl.style.left = left + "px";
            selectionEl.style.top = top + "px";

            markerEl.parentNode.removeChild(markerEl);
        }
    };
})();
27
ответ дан 28 November 2019 в 23:28
поделиться

Вероятно, вам следует вставить элемент с абсолютной позицией в конце "диапазона". Это работает по-разному в разных браузерах, поэтому лучше всего будет нюхать.

И раз уж вы спросили: вот как это делается в New York Times в своем файле altClickToSearch.js:

function insertButton() {

selectionButton = new Element(
        'span', {
          'className':'nytd_selection_button',
          'id':'nytd_selection_button',
          'title':'Lookup Word',
          'style': 'margin:-20px 0 0 -20px; position:absolute; background:url(http://graphics8.nytimes.com/images/global/word_reference/ref_bubble.png);width:25px;height:29px;cursor:pointer;_background-image: none;filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src="http://graphics8.nytimes.com/images/global/word_reference/ref_bubble.png", sizingMethod="image");'
        }
    )

if (Prototype.Browser.IE) {
  var tmp = new Element('div');
  tmp.appendChild(selectionButton);
  newRange = selection.duplicate();
  newRange.setEndPoint( "StartToEnd", selection);
  newRange.pasteHTML(tmp.innerHTML);
  selectionButton = $('nytd_selection_button');
}
else {
  var range = selection.getRangeAt(0);
  newRange = document.createRange();
  newRange.setStart(selection.focusNode, range.endOffset);
  newRange.insertNode(selectionButton);
}
}
2
ответ дан 28 November 2019 в 23:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: