jquery 当鼠标按下时触发文本选择(window.getSelection()在mouseup之前为空)

wlp8pajw  于 2023-08-04  发布在  jQuery
关注(0)|答案(2)|浏览(89)

似乎window.getSelection()是空的,直到mouseup发生。我可以在mouseup上获取点击的单词并选择它,但我需要在mousedown上这样做(在mouseup发生之前)。在下面的jsfiddle示例中,我正在触发mouseup(成功触发),但文本选择仍然是空的,直到物理mouseup发生。
https://jsfiddle.net/aoznge7j/1/

$(function() {
    app_init();
});

function app_init() {
    container = $('div');
    selection = false;
    word = false;
    start = false;
    end = false;

    if(window.getSelection) {
        selection = window.getSelection();
        selection.empty();
    } else {
        alert('Please update your browser to use this application.');  
    }

    container.mousedown(function(e) {
        console.log('mousedown');
        mouse_press(e);
    });

    container.mouseup(function(e) {
        console.log('mouseup');
        mouse_release(e);   
    });

}

function mouse_press(e) {
    $(e.target).trigger('mouseup'); // this triggers the mouseup but selection is empty
}

function mouse_release(e) {
    handle_selection(); //physical mouseup works
}

function handle_selection() {
    selection = window.getSelection();
    //console.log(selection);

    if(selection.isCollapsed) {
        // this is how i am selecting the clicked word, and yes i know .modify is non-standard
        selection.modify('move', 'forward', 'character');
        selection.modify('move', 'backward', 'word');
        selection.modify('extend', 'forward', 'word');

        word = selection.toString();
        start = selection.anchorOffset;
        end = selection.focusOffset;

        console.log( 'word:'+word+' start:'+start+' end:'+end );

    }
}

字符串
有没有其他方法可以在鼠标仍然按下时触发文本选择(isCollapsedtrue)?

a14dhokn

a14dhokn1#

只需在mousedown事件中调用window.getSelection()即可。但请记住,它将返回在鼠标按下之前选择的内容。

container.mousedown(function(e) {
   selection = window.getSelection();
   console.log('mousedown='+ selection);
   mouse_press(e);
});

字符串

$(function() {
	app_init();
});

function app_init() {
	container = $('div');
	selection = false;
  word = false;
  start = false;
  end = false;
  
  if(window.getSelection) {
  	selection = window.getSelection();
    selection.empty();
  } else {
  	alert('Please update your browser to use this application.');  
  }
  
  container.mousedown(function(e) {
  	 $('.result').text($('#word').text());
  });

  container.mouseup(function(e) {
  	mouse_release(e);  	
  });

}

function mouse_press(e) {
	$(e.target).trigger('mouseup');
  //container.trigger('mouseup');
  //handle_selection();
}

function mouse_release(e) {
	handle_selection();
}

function handle_selection() {
	selection = window.getSelection();

  if(selection.isCollapsed) {
    
		selection.modify('move', 'forward', 'character');
		selection.modify('move', 'backward', 'word');
		selection.modify('extend', 'forward', 'word');
    
		word = selection.toString();
    start = selection.anchorOffset;
    end = selection.focusOffset;

    
  }
}

// wrap words in i.ele
$(document).on('mouseenter', 'p',  function() {
    var $this = $(this);
    var word = $this.text().replace(/\b(\w+)\b/g, "<i class='ele'>$1</i>");
    $this.html( word );
});
// unwrap on mouseleave
$(document).on('mouseleave', 'p',  function() {
    $(this).find('i.ele').contents().unwrap().end().end().html()

});

// bind to each span
$(document).on('mouseenter', 'p i.ele',  function() {
    var word = $(this).css('background-color','#ffff66').text();
    $('#word').text(word);
});
 
$(document).on('mouseleave', 'p i.ele',  function() {     
    $('#word').text('');
    $(this).css('background-color',''); 
});

x

div {
   border: 1px dotted orange;
   padding: 1em;
}
p {
  font-size: 1.5em;
  font-family: sans-serif;
}
.result {
  border: 1px #ccc solid;
  padding: 3px 10px;
  height: 30px;
}
i.ele {
  font-style: normal;
}
#word {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <p>
    This is some type of testing test.
  </p>
  <p class="result"></p>
  mousedown word: <span id="word"></span>
</div>

的字符串
编辑:现在使用mousemove显示拖动鼠标时高亮显示的文本。您可能需要展开代码段以查看结果。
编辑2:现在检测悬停的单词,并在鼠标按下时捕获它。

eagi6jfj

eagi6jfj2#

如果它可以异步发生,那么你可以像下面这样做:

element.addEventListener('mousedown', ()=>{
    setTimeout(putYourSelectionHandlerHere);
});

字符串
这与同步运行处理程序的行为非常相似,但由于在同步执行mousedown处理程序期间,我们还没有访问选择对象的信息,因此我们需要触发一个异步回调,以便在选择对象更新后获得选择对象的信息。我通过调用setTimeout来做到这一点。
注意:我猜,在回调函数有机会触发之前,可能会发生mouseup事件。我真的不确定,因为我不知道(或不关心)下一个事件循环,setTimeout事件或用户mouseup事件中的优先级。但只要这不是一个真正的问题,这将工作。下面是一个在OP代码中实现的可运行片段:

$(function() {
  app_init();
});

function app_init() {
  container = $('div');
  selection = false;
  word = false;
  start = false;
  end = false;
  
  if(window.getSelection) {
    selection = window.getSelection();
    selection.empty();
  } else {
    alert('Please update your browser to use this application.');  
  }
  
  container.mousedown(function(e) {
    setTimeout(handle_selection);
  });
}

function handle_selection() {
  selection = window.getSelection();
  //console.log(selection);

  if(selection.isCollapsed) {

    selection.modify('move', 'forward', 'character');
    selection.modify('move', 'backward', 'word');
    selection.modify('extend', 'forward', 'word');

    word = selection.toString();
    start = selection.anchorOffset;
    end = selection.focusOffset;
  }
}

x

div {
   border: 1px dotted orange;
   padding: 1em;
}
p {
  font-size: 1.5em;
  font-family: sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <p>
    This is some type of testing test.
  </p>
</div>

的字符串
很抱歉,我迟了5年才给出这个答案。我敢肯定,自从这个问题被问到以来,每个人都已经离开很久了。我希望它能帮助某人!:)

相关问题