Firefox双击带有下一个空格的选定文本。如何使用javascript删除屏幕上的结尾空间。
非常感谢。
最佳答案
以下解决方案确实删除了Windows浏览器中双击时选择的尾随空白字符,从而在某种程度上模拟了Firefox的about:config设置layout.word_select.eat_space_to_next_word设置为“false”。
是否“在屏幕上而不是变量中”。
已在Chrome 60.0.3112.113,Firefox 55.0.3,IE8和IE Edge(14)中进行测试。
它仍然有时可见从多余的空间,但没有选择收缩,可说来完成。
适用于任意文本和输入/文本区域(需要完全不同的方法)。
使用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支持和limitint即可仅删除doubleclick,则可以大大简化该操作,并且只需要处理selectchange和select相应函数的事件即可。(但实际上您无法使用键盘选择东西)
编辑:
使用Rangy lib(https://github.com/timdown/rangy)Core + TextRange进行非输入元素选择修整比我的基本尝试好得多,我的基本尝试只有在endContainer恰好是文本节点时才起作用。选择修整的基本 Action 是
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
关于javascript - Firefox双击所选文本时如何删除末尾空间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23306561/