admin管理员组文章数量:1410730
I am new to javascript.I am trying to make an simple toggle up div With user selection direction ill place the toggle div.After some googling I found one working fiddle But not as expected See the below screenshot to see the difference
When I select Some text on the front of the paragraph It works fine Like this
But when I selected some text from bottom paragraph It is not Working as expected
JsFiddle
Actually I am working in React version Fiddle is in Jquery
This is my code
import React from 'react'
import {render} from 'react-dom';
export default class App extends React.Component{
constructor(props){
super(props);
this.state = {
display:'none' ,
top:'',
bottom:'',
left:'',
right:'',
diplayForDown:'none'
};
this.handleOnMouseDown = this.handleOnMouseDown.bind(this)
this.onMounseUp = this.onMounseUp.bind(this)
this.onMouseDwn = this.onMouseDwn.bind(this)
this.triggerAlltime = this.triggerAlltime.bind(this)
}
handleOnMouseDown(){
let sel = window.getSelection && window.getSelection();
let r = sel.getRangeAt(0).getBoundingClientRect();
let relative=document.body.parentNode.getBoundingClientRect();
console.log('Relative ',relative);
if(!sel.isCollapsed){
console.log(sel,r);
let display = 'block';
let top = (r.bottom - relative.top - 80)+'px';
let bottom = r.bottom+'px';
let left =( r.left)+'px';
let right = (r.right)+'px';
console.log('This is Height',r.bottom-r.top);
let selectionHeight = r.bottom - r.top;
if(selectionHeight => 22.22){
this.setState({
display,
top:top,
bottom,
left,
right
})
}else{
this.setState({
display,
top,
bottom,
left,
right
})
}
}else{
this.setState({
display:'none'
})
}
console.log('Slected')
}
onMounseUp(e){
e.preventDefault()
let sel = window.getSelection && window.getSelection();
if(!sel.isCollapsed){
console.log('Moved Up')
}
}
onMouseDwn(e){
let sel = window.getSelection && window.getSelection();
if(!sel.isCollapsed){
console.log('Moved Down')
}
}
getSelectionHtml() {
let html = "";
if (typeof window.getSelection != "undefined") {
let sel = window.getSelection();
if (sel.rangeCount) {
let container = document.createElement("div");
for (let 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;
}
}
console.log('html',html)
return html;
}
lastCharRTL(txt) {
return /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]$/.test(txt);
}
triggerAlltime(e){
// console.log('Some Thinms')
if(!window.getSelection().isCollapsed){
//find the Direction Of Slelection
let sel = window.getSelection();
console.log(sel)
let range = document.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
let backwards = range.collapsed;
range.detach();
// get selection rects
let rects = sel.getRangeAt(0).getClientRects();
let n = rects.length - 1;
let display = 'block';
console.log(this.lastCharRTL(this.getSelectionHtml()))
if (this.lastCharRTL(this.getSelectionHtml()))
this.setState({
display:'none',
diplayForDown:'none',
top: rects[n].top + 10,
left: rects[n].left - 10
})
else if (backwards)
this.setState({
display,
diplayForDown:'none',
top: rects[0].top + -68,
left: rects[0].left
})
else
this.setState({
display:'none',
diplayForDown:'block',
top: rects[n].top + 40,
left: rects[n].right+-160
})
}else{
this.setState({
display:'none',
diplayForDown:'none',
})
}
}
render(){
return(
<div className="container">
<div className="CenterCon">
<div contentEditable="true" onMouseUp={this.triggerAlltime} onMouseDown={this.triggerAlltime} onKeyUp={this.triggerAlltime} onKeyDown={this.triggerAlltime} className="Edithis" >
<p>Test</p>
</div>
</div>
<div style={{top: this.state.top, bottom: this.state.bottom, left:this.state.left, right:this.state.right, display: this.state.display}} className="Toggle">
<ul>
<li>B</li>
<li>U</li>
<li>H</li>
<li>"</li>
</ul>
<div className="triangle">
</div>
</div>
{/*DownWard Toggle*/}
<div style={{top: this.state.top, bottom: this.state.bottom, left: this.state.left, right: this.state.right, display: this.state.diplayForDown}} className="ToggleForDownWardSelection">
<div className="triangle-bottom" />
<ul>
<li>B</li>
<li>U</li>
<li>H</li>
<li>li</li>
</ul>
</div>
</div>
)
}
}
render(<App/>,document.getElementById('app'));
I am new to javascript.I am trying to make an simple toggle up div With user selection direction ill place the toggle div.After some googling I found one working fiddle But not as expected See the below screenshot to see the difference
When I select Some text on the front of the paragraph It works fine Like this
But when I selected some text from bottom paragraph It is not Working as expected
JsFiddle
Actually I am working in React version Fiddle is in Jquery
This is my code
import React from 'react'
import {render} from 'react-dom';
export default class App extends React.Component{
constructor(props){
super(props);
this.state = {
display:'none' ,
top:'',
bottom:'',
left:'',
right:'',
diplayForDown:'none'
};
this.handleOnMouseDown = this.handleOnMouseDown.bind(this)
this.onMounseUp = this.onMounseUp.bind(this)
this.onMouseDwn = this.onMouseDwn.bind(this)
this.triggerAlltime = this.triggerAlltime.bind(this)
}
handleOnMouseDown(){
let sel = window.getSelection && window.getSelection();
let r = sel.getRangeAt(0).getBoundingClientRect();
let relative=document.body.parentNode.getBoundingClientRect();
console.log('Relative ',relative);
if(!sel.isCollapsed){
console.log(sel,r);
let display = 'block';
let top = (r.bottom - relative.top - 80)+'px';
let bottom = r.bottom+'px';
let left =( r.left)+'px';
let right = (r.right)+'px';
console.log('This is Height',r.bottom-r.top);
let selectionHeight = r.bottom - r.top;
if(selectionHeight => 22.22){
this.setState({
display,
top:top,
bottom,
left,
right
})
}else{
this.setState({
display,
top,
bottom,
left,
right
})
}
}else{
this.setState({
display:'none'
})
}
console.log('Slected')
}
onMounseUp(e){
e.preventDefault()
let sel = window.getSelection && window.getSelection();
if(!sel.isCollapsed){
console.log('Moved Up')
}
}
onMouseDwn(e){
let sel = window.getSelection && window.getSelection();
if(!sel.isCollapsed){
console.log('Moved Down')
}
}
getSelectionHtml() {
let html = "";
if (typeof window.getSelection != "undefined") {
let sel = window.getSelection();
if (sel.rangeCount) {
let container = document.createElement("div");
for (let 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;
}
}
console.log('html',html)
return html;
}
lastCharRTL(txt) {
return /[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]$/.test(txt);
}
triggerAlltime(e){
// console.log('Some Thinms')
if(!window.getSelection().isCollapsed){
//find the Direction Of Slelection
let sel = window.getSelection();
console.log(sel)
let range = document.createRange();
range.setStart(sel.anchorNode, sel.anchorOffset);
range.setEnd(sel.focusNode, sel.focusOffset);
let backwards = range.collapsed;
range.detach();
// get selection rects
let rects = sel.getRangeAt(0).getClientRects();
let n = rects.length - 1;
let display = 'block';
console.log(this.lastCharRTL(this.getSelectionHtml()))
if (this.lastCharRTL(this.getSelectionHtml()))
this.setState({
display:'none',
diplayForDown:'none',
top: rects[n].top + 10,
left: rects[n].left - 10
})
else if (backwards)
this.setState({
display,
diplayForDown:'none',
top: rects[0].top + -68,
left: rects[0].left
})
else
this.setState({
display:'none',
diplayForDown:'block',
top: rects[n].top + 40,
left: rects[n].right+-160
})
}else{
this.setState({
display:'none',
diplayForDown:'none',
})
}
}
render(){
return(
<div className="container">
<div className="CenterCon">
<div contentEditable="true" onMouseUp={this.triggerAlltime} onMouseDown={this.triggerAlltime} onKeyUp={this.triggerAlltime} onKeyDown={this.triggerAlltime} className="Edithis" >
<p>Test</p>
</div>
</div>
<div style={{top: this.state.top, bottom: this.state.bottom, left:this.state.left, right:this.state.right, display: this.state.display}} className="Toggle">
<ul>
<li>B</li>
<li>U</li>
<li>H</li>
<li>"</li>
</ul>
<div className="triangle">
</div>
</div>
{/*DownWard Toggle*/}
<div style={{top: this.state.top, bottom: this.state.bottom, left: this.state.left, right: this.state.right, display: this.state.diplayForDown}} className="ToggleForDownWardSelection">
<div className="triangle-bottom" />
<ul>
<li>B</li>
<li>U</li>
<li>H</li>
<li>li</li>
</ul>
</div>
</div>
)
}
}
render(<App/>,document.getElementById('app'));
Share
Improve this question
edited Feb 2, 2017 at 15:35
Nane
asked Feb 2, 2017 at 15:27
NaneNane
4336 gold badges39 silver badges82 bronze badges
3
- 2 What browser are you in because this fiddle correctly adds the toggle div for me in both directions.. jsfiddle/vCwwN/2 - works for me in GC and FF – Zze Commented Feb 9, 2017 at 4:56
- It will work .But try it Select the last line of the content see what happens if it work pls post the screenshot @Zze – Nane Commented Feb 9, 2017 at 13:11
- @Alex.S was right in his ment on your answer. I didn't see the issue, because I didn't have to scroll to get to the bottom paragraph. Glad you found your solve. – Zze Commented Feb 9, 2017 at 20:37
5 Answers
Reset to default 3const isBackwards = () => {
const selection = window.getSelection();
let range = document.createRange();
range.setStart(selection.anchorNode, selection.anchorOffset);
range.setEnd(selection.focusNode, selection.focusOffset);
let backwards = range.collapsed;
range.detach();
return backwards;
}
At Last I find the answer,I fixed it apply simple style to the contentEditable div And It it is Working like a Charm.I don't know why it is working But i doubt window API
<div contentEditable="true" style={{height:'100vh',overflow:'auto'}} onMouseUp={this.triggerAlltime} onMouseDown={this.triggerAlltime} onKeyUp={this.triggerAlltime} onKeyDown={this.triggerAlltime} className="Edithis" >
<p>Test</p>
</div>
The issue is that the #pointer
is set to absolute position, but when the content is long and scrollable, the top distance is calculated from top of window rather than top of the content.
Adding height: 100vh
would solve this problem, but you may see two scroll bars in some cases.
Another way is to add window.pageYOffset
when calculating the top
of pointer div.
if (backwards) {
$('#pointer').css({top: rects[0].top + window.pageYOffset + 10, left: rects[0].left - 10}).show();
} else {
$('#pointer').css({top: rects[n].top + window.pageYOffset + 10, left: rects[n].right}).show();
}
Here is DEMO
There is no way to do that. Probably you can check mouse press and unpress events locations and determine initial/end positions to determine whether it was forward or backward selection.
To answer the question in the title - checking if selection was forward or backwards:
window.getSelection() returns a Selection object and in the documentation you can read the following:
- Selection.anchorNode: Returns the Node in which the selection begins.
However, when you call Selection.getRangeAt(0) on this Selection object, you get instead the selection as Range. Range does not have anchor (and focus) but instead startContainer and endContainer.
- Range.startContainer: Returns the Node within which the Range starts.
- Range.endContainer: Returns the Node within which the Range ends.
Basically the anchordNode is always the Node where the selection started by the user while startContainer is always the first Node in the DOM tree of the selection. So:
- If the anchorNode and the anchorOffset of the selection corresponds with the startContainer and startOffset of the Range, you have (normal) forward selection
- If the anchorNode and the anchorOffset of the selection corresponds with the endContainer and endOffset of the Range, you have backwards selection
(do check in the beginning off course if the selection is collapsed or not)
本文标签: jqueryHow to find a user selection weather forward or backward in javascriptStack Overflow
版权声明:本文标题:jquery - How to find a user selection weather forward or backward in javascript? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744905695a2631606.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论