JavaScript:拖动选择标记,因此可以扩展或缩小当前选择

时间:2013-10-29 08:58:18

标签: javascript html5

我有以下工作代码:http://jsfiddle.net/henrichro/Z75wS/

当用户选择某些文字时,会出现左右标记,就像在iPhone上一样。也可以向后选择。代码主要基于此处https://stackoverflow.com/a/15369695/621639找到的解决方案,当然改变了一点,将jQuery转换为JS,因为我的主要目标是用JavaScript编写所有内容,而不是使用任何库。

我需要的是使标记可拖动,这样我就可以扩展或缩小选择。

当前的JavaScript代码:

function applySelectionMarkers() {

    if( !window.getSelection().isCollapsed ) {

        var sel = window.getSelection();
        var range = document.createRange();
        range.setStart( sel.anchorNode, sel.anchorOffset );
        range.setEnd( sel.focusNode, sel.focusOffset );
        var backwards = range.collapsed;
        range.detach();

        var rects = sel.getRangeAt(0).getClientRects();
        var n = rects.length - 1;

        //console.log(rects);

        var lineHeight = getLineHeight( edit );

        var markerRight = document.getElementById( "markerRight" );
        var markerRightWidth = markerRight.offsetWidth;

        var markerLeft = document.getElementById( "markerLeft" );
        var markerLeftWidth = markerLeft.offsetWidth;


        if ( markerRightWidth == 0 ) {
            markerRightWidth = 10;
        }

        if ( markerLeftWidth == 0 ) {
            markerLeftWidth = 10;
        }

        if ( lastCharRTL( getSelectionHtml() ) ) {

            markerLeft.style.top = ( rects[0].top + lineHeight ) + "px";
            markerLeft.style.left = ( rects[0].left - markerLeftWidth ) + "px";
            markerLeft.style.display = "block";

            markerRight.style.top = ( rects[n].top + lineHeight ) + "px";
            markerRight.style.left = ( rects[n].left - markerRightWidth ) + "px";
            markerRight.style.display = "block";

            //alert( "one" + markerLeftWidth );

        } else if ( backwards ) {

            markerLeft.style.top = ( rects[n].top + lineHeight ) + "px";
            markerLeft.style.left = rects[n].right + "px";
            markerLeft.style.display = "block";

            markerRight.style.top = ( rects[0].top + lineHeight ) + "px";
            markerRight.style.left = ( rects[0].left - markerRightWidth ) + "px";
            markerRight.style.display = "block";

            //alert( "two" + markerRightWidth );

        } else {

            markerLeft.style.top = ( rects[0].top + lineHeight ) + "px";
            markerLeft.style.left = ( rects[0].left - markerLeftWidth ) + "px";
            markerLeft.style.display = "block";

            markerRight.style.top = ( rects[n].top + lineHeight ) + "px";
            markerRight.style.left = rects[n].right + "px";
            markerRight.style.display = "block";

            //alert( "three" + markerLeftWidth );
        }
    } else {
        markerLeft.style.display = "none";
        markerRight.style.display = "none";
    }
}

function getSelectionHtml() {
    var html = "";
    if ( typeof window.getSelection != "undefined" ) {
        var sel = window.getSelection();
        if ( sel.rangeCount ) {
            var container = document.createElement( "div" );
            for ( var i = 0, len = sel.rangeCount; i < len; ++i ) {
                container.appendChild( sel.getRangeAt(i).cloneContents() );
            }
            html = container.innerHTML;
        }
    } else if ( typeof document.selection != "undefined" ) {
        if ( document.selection.type == "Text" ) {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
}

function lastCharRTL( txt ) {
    return /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]$/.test(txt);
}

// line height in selectie ca putem adauga la markerLeft top attribute
function getLineHeight( element ){
    var temp = document.createElement( element.nodeName );
    temp.setAttribute( "style","margin:0px;padding:0px;font-family:"+element.style.fontFamily+";font-size:"+element.style.fontSize );
    temp.innerHTML = "test";
    temp = element.parentNode.appendChild( temp );
    var ret = temp.clientHeight;
    temp.parentNode.removeChild( temp );
    return ret;
}

document.onmouseup = function() {
    applySelectionMarkers();
}

function KeyPress(e) {
    var evtobj = window.event ? event : e;
    if ( evtobj.keyCode == 65 && evtobj.ctrlKey ) {
        console.log(evtobj.keyCode);
        applySelectionMarkers();
    }
}

document.onkeydown = KeyPress;

其他学分:

https://stackoverflow.com/a/5222955/621639https://stackoverflow.com/a/4515470/621639

更新:在拖动其中一个标记时播放:

window.onload = function() {
    draggable( 'markerLeft' );
}

var dragObj = null;

function draggable( id ) {
    var obj = document.getElementById( id );
    obj.style.position = "absolute";
    obj.onmousedown = function() {
        dragObj = obj;
    }
}

document.onmouseup = function(e) {
    dragObj = null;
}

document.onmousemove = function(e) {
    var x = e.pageX;
    var y = e.pageY;
    if( dragObj == null )
        return;
    dragObj.style.left = x + "px";
    dragObj.style.top = y + "px";
}

但是当我拖动左标记(红色)时,整个选择消失。

0 个答案:

没有答案