当firefox双击所选文本时如何删除结束空间

时间:2014-04-26 04:15:33

标签: javascript firefox

Firefox双击下一个空格的所选文本。如何使用javascript删除屏幕上的结束空间。 非常感谢你。

6 个答案:

答案 0 :(得分:3)

这里的解决方案确实删除了在Windows浏览器中双击时选择的尾随空格字符,稍微模仿了Firefox:config setting layout.word_select.eat_space_to_next_word设置为“false”。

是“在屏幕上,而不是变量”。

在Chrome 60.0.3112.113,Firefox 55.0.3,IE8和IE Edge(14)中测试过。 它仍然有时可见,因为选择从那个额外的空间缩小,但没有什么可以做的。

适用于任意文本和输入/ textareas(需要完全不同的方法)。

使用jQuery

(function() {
var lastSelEvent = null;
var lastSelInputEvent = null;
var lastDblClickEvent = null;
var selchangeModTs = null;

$(document).on('selectstart selectionchange', function (e) //not input/textarea case
{
    fixEventTS(e);
    lastSelEvent = e;

    if (( selchangeModTs != null) && (new Date().getTime() - selchangeModTs < 50)) //without this we get infinite loop in IE11+ as changing selection programmatically apparently generates event itself...
        return;

    handleSelEvent(e);
});

$(document).on('select', function (e) //input/textarea
{
    fixEventTS(e);
    lastSelInputEvent = e;
    handleSelEvent(e);
});

$(document).on('dblclick',function(e)
{
    fixEventTS(e);
    lastDblClickEvent = e;
    handleSelEvent(e);
});

function fixEventTS(e)
{
    if (typeof e.timeStamp == 'undefined') //IE 8 no timestamps for events...
    {
        e.timeStamp = new Date().getTime();
    }
}

function handleSelEvent(e)
{
    if (lastDblClickEvent===null)
        return;

    if ( ((e.type==='selectstart') || (e.type==='selectionchange') || (e.type==='dblclick')) && (lastSelEvent != null) && (Math.abs(lastDblClickEvent.timeStamp - lastSelEvent.timeStamp) < 1000) ) // different browsers have different event order so take abs to be safe...
    {
        switch (lastSelEvent.type)
        {
            case 'selectstart':
                setTimeout(handleSelChange,50); //IE8 etc fix, selectionchange is actually only change, not selection "creation"
            break;
            case 'selectionchange':
                handleSelChange();
            break;
        }
    }

    if ( ((e.type==='select') || (e.type==='dblclick')) && (lastSelInputEvent != null) && (Math.abs(lastDblClickEvent.timeStamp - lastSelInputEvent.timeStamp) < 1000) ){
        handleSel(lastSelInputEvent);
    }
}

function handleSel(e)
{
    //right whitespace
    while (/\s$/.test(e.target.value.substr(e.target.selectionEnd - 1, 1)) && e.target.selectionEnd > 0) {
        e.target.selectionEnd -= 1;
    }
    //left whitespace
    while (/\s$/.test(e.target.value.substr(e.target.selectionStart, 1)) && e.target.selectionStart > 0) {
        e.target.selectionStart += 1;
    }
}

function handleSelChange() {
    var sel = null;

    if (typeof window.getSelection == 'function') // modern browsers
        sel = window.getSelection();
    else if (typeof document.getSelection == 'function')
        sel = document.getSelection();

    if (sel && !sel.isCollapsed) {
        var range = sel.getRangeAt(0); //have to use range instead of more direct selection.expand/selection.modify as otherwise have to consider selection's direction in non-doubleclick cases
        if (range.endOffset > 0 && (range.endContainer.nodeType===3) && (range.endContainer.textContent != ''/*otherwise rightside pictures get deleted*/))
        {
            //right whitespaces
            while ( /[\s\S]+\s$/.test(range.endContainer.textContent.substr(0,range.endOffset)) ) { //have to use instead of range.toString() for IE11+ as it auto-trims whitespaces there and in selection.toString()
                selchangeModTs = new Date().getTime();
                range.setEnd(range.endContainer, range.endOffset - 1);
            }
        }

        if ((range.startContainer.nodeType===3) && (range.startContainer.textContent != '') && (range.startOffset < range.startContainer.textContent.length)) {
            //left whitespaces
            while (/^\s[\s\S]+/.test(range.startContainer.textContent.substr(range.startOffset))) {
                selchangeModTs = new Date().getTime();
                range.setStart(range.startContainer, range.startOffset + 1);
            }
        }
        selchangeModTs = new Date().getTime();
        sel.removeAllRanges(); //IE11+ fix, in Firefox/Chrome changes to range apply to selection automatically
        sel.addRange(range);
    }
    else if (typeof document.selection != 'undefined') //IE 10 and lower case
    {
        var range = document.selection.createRange();
        if (range && range.text && range.text.toString()) {
            while ((range.text != '') && /[\s\S]+\s$/.test(range.text.toString())) {
                selchangeModTs = new Date().getTime();
                range.moveEnd('character', -1);
                range.select();
            }
            while ((range.text != '') && /^\s[\s\S]+/.test(range.text.toString())) {
                selchangeModTs = new Date().getTime();
                range.moveStart('character', 1);
                range.select();
            }
        }
    }
}

})();

如果您不需要旧的IE支持&amp;限制到doubleclick-only删除它可以大大简化,只需要处理selectchange并选择事件到各自的功能。(但实际上你不能用键盘选择东西)

编辑: 使用Rangy lib(https://github.com/timdown/rangy)Core + TextRange进行非输入元素选择修剪比我的基本尝试更好,只有当endContainer恰好是文本节点时才有效。选择修剪的基本动作是

rangy.getSelection().trim()

最小包括

Rangy实施另外支持三击全线选择修剪

(function() {
var lastSelEvent = null;
var lastSelInputEvent = null;
var lastDblClickEvent = null;
var selchangeModTs = null;
var tripleclickFixBound = false;
var selStartTimout = null;

$(document).on('selectstart selectionchange', function (e) //non-inputs
{
    fixEventTS(e);
    lastSelEvent = e;

    if ( ( selchangeModTs != null) && (new Date().getTime() - selchangeModTs < 50) ) //ie11+ fix otherwise get self-loop with our selection changes generating this event
        return;

    handleSelEvent(e);
});

if ('onselect' in document.documentElement) {
    $(document).on('select', function (e) //input/textarea
    {
        fixEventTS(e);
        lastSelInputEvent = e;
        handleSelEvent(e);
    });
}

$(document).on('click',function(e){
    if (typeof e.originalEvent.detail !== 'undefined')
    {
        multiclickHandlerfunction(e);
    }
    else
    {
        fixEventTS(e);
        if (!tripleclickFixBound) {

            $(document).on('dblclick', function (e) {
                fixEventTS(e);
                selchangeModTs = null;
                lastDblClickEvent = e;
                handleSelEvent(e);
            });
            tripleclickFixBound=true;
        }
        if ( (lastDblClickEvent != null) && (e.timeStamp - lastDblClickEvent.timeStamp < 300))
        {
            lastDblClickEvent = e;
            selchangeModTs = null;
            handleSelEvent(e);
        }
    }

});

function multiclickHandlerfunction(e) {
    if (e.originalEvent.detail === 2 || e.originalEvent.detail === 3) {
        fixEventTS(e);
        selchangeModTs = null;
        lastDblClickEvent = e;
        handleSelEvent(e);
    }
}

function fixEventTS(e)
{
    if (typeof e.timeStamp == 'undefined') //IE 8
    {
        e.timeStamp = new Date().getTime();
    }
}

function handleSelEvent(e)
{
    if (lastDblClickEvent===null)
        return;

    if ( ((e.type==='selectstart') || (e.type==='selectionchange') || (e.type==='dblclick') || (e.type==='click')) && (lastSelEvent != null) && (Math.abs(lastDblClickEvent.timeStamp - lastSelEvent.timeStamp) < 1000) ) // different order of events in different browsers...
    {
        switch (lastSelEvent.type)
        {
            case 'selectstart':
            case 'selectionchange':
                clearTimeout(selStartTimout);
                selStartTimout = setTimeout(handleSelChange,(/msie\s|trident\/|edge\//i.test(window.navigator.userAgent)?150:0));
            break;
        }
    }

    if ( ((e.type==='select') || (e.type==='dblclick') || (e.type==='click')) && (lastSelInputEvent != null) && (Math.abs(lastDblClickEvent.timeStamp - lastSelInputEvent.timeStamp) < 1000) )
    {
        handleSel(lastSelInputEvent);
    }
}

function handleSel(e)
{
    if (typeof(e.target.selectionEnd) != 'undefined') {
        //left whitespace
        while (/\s$/.test(e.target.value.substr(e.target.selectionEnd - 1, 1)) && e.target.selectionEnd > 0) {
            e.target.selectionEnd -= 1;
        }
        //right whitespace
        while (/^s/.test(e.target.value.substr(e.target.selectionStart - 1, 1)) && e.target.selectionStart > 0) {
            e.target.selectionStart += 1;
        }
    }
}

function handleSelChange() {
    var sel = rangy.getSelection();
    if (sel && !sel.isCollapsed) {
        selchangeModTs = new Date().getTime();
        sel.trim();
    }
    else if (typeof document.selection != 'undefined') //IE 10- input/textArea case
    {
        var range = document.selection.createRange();

        if (range && range.text && range.text.toString()) {
            while ((range.text != '') && /[\s\S]+\s$/.test(range.text.toString())) {
                selchangeModTs = new Date().getTime();
                range.moveEnd('character', -1);
                range.select();
            }
            while ((range.text != '') && /^\s[\s\S]+/.test(range.text.toString())) {
                selchangeModTs = new Date().getTime();
                range.moveStart('character', 1);
                range.select();
            }
        }
    }
}

})($,window);

CodePen demo

答案 1 :(得分:1)

我尝试过的一件事是使用range.setEnd()并使用选择焦点和锚点以及偏移量(但为-1)。

请原谅缺乏对浏览器兼容性的检查。

var selection = window.getSelection();
var range = selection.getRangeAt(0);
var selected = range.toString();
if (!selection.isCollapsed) {
    if (/\s+$/.test(selected)) {
        if (selection.focusOffset > selection.anchorOffset) {
            range.setEnd(selection.focusNode, selection.focusOffset - 1);
        } else {
            range.setEnd(selection.anchorNode, selection.anchorOffset - 1);
        }
    }
}

我不确定它是否可以在IE / Edge中运行,但Chrome似乎对此感到满意。

答案 2 :(得分:0)

Javascript有一个trim()方法可以修剪尾部(结束)和前导空格。

e.g。

var str = "       Hello World!        ";
str = str.trim(); // returns "Hello World"

参考:http://www.w3schools.com/jsref/jsref_trim_string.asp

答案 3 :(得分:0)

您必须使用Windows计算机。所以你看到了这个问题。它在ubuntu机器上不存在。 此外,如果您需要使用Js删除尾随空格

尝试这样的事情。

document.ondblclick = function () {
    var sel = (document.selection && document.selection.createRange().text) ||
         (window.getSelection && window.getSelection().toString());
    var selection = window.getSelection();
    $('#new_word').text(sel.trim());
};

检查此jsFiddle http://jsfiddle.net/shinde87sagar/FvkwV/

答案 4 :(得分:0)

感谢@James Bellaby

它对于我使用Chrome 83而言是有效的,这是用于从所选范围中删除前导和尾随空格的代码。

function PlayVideo() {
    var video = document.getElementById('video');
    var videoSrc = "http://host.net:826/live/hello/413.m3u8";
    if (Hls.isSupported()) {
        // The following hlsjsConfig is required for live-stream
        var hlsjsConfig = {
            "maxBufferSize": 0,
            "maxBufferLength": 30,
            "liveSyncDuration": 30,
            "liveMaxLatencyDuration": Infinity
        }
        var hls = new Hls(hlsjsConfig);
        hls.loadSource(videoSrc);
        hls.attachMedia(video);
        hls.on(Hls.Events.MANIFEST_PARSED, function () {
            video.play();
        });
    } 
    else if (elementId.canPlayType('application/vnd.apple.mpegurl')) {
        elementId.src = videoSrc;
        elementId.addEventListener('loadedmetadata', function () {
            elementId.play();
        });
    }
}

答案 5 :(得分:0)

只需将文本放在标签内即可解决问题