我如何对来自鼠标点击而不是键盘操作的光标 activity 进行操作?
How can I act on cursor activity originating from mouse clicks and not keyboard actions?
我想在用户通过鼠标单击将光标移动到另一个位置时执行某些操作,但在通过键盘操作完成时不执行此操作(箭头、pageup/pagedown、home/end) .
- 我不能只听
cursorActivity
因为它会触发键盘和鼠标操作。
- 我不确定我是否可以收听
mousedown
,因为它可能是不是光标位置更改(例如选择、拖动)的开始。
捕捉那些由鼠标引起的光标移动的最佳方法是什么?
您可以收听这些事件:
- 鼠标按下
- cursorActivity
- 按键
- 变更前
如果满足以下条件,则通过鼠标单击移动了光标:
cursorActivity
事件在 mousedown
事件后触发
- 两个事件之间没有按下移动键
- 两次活动内容没有变化
- 没有选择文本
var movedByMouse = false;
var editor = CodeMirror(document.body);
editor.on("mousedown", function () {
movedByMouse = true;
});
editor.on("cursorActivity", function () {
if (movedByMouse) {
movedByMouse = false;
if (!editor.getSelection()) {
console.log("Moved by mouse");
}
}
});
editor.on("keydown", function () {
if (isMovementKey(event.which)) {
movedByMouse = false;
}
});
editor.on("beforeChange", function () {
movedByMouse = false;
});
function isMovementKey(keyCode) {
return 33 <= keyCode && keyCode <= 40;
};
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.min.js"></script>
所有鼠标事件(我知道的):
- 点击
- 上下文菜单
- ondbclick
- 鼠标按下
- onmouseenter
- onmouseleave
- onmousemove
- 鼠标悬停
- onmouseout
- onmouseup
所以,基本上,javascript AFAIK 中没有解决您的问题的方法。但是,您可以采用第二个建议并跟踪事件,并根据事件选择是否执行您的操作。
var editorElement = document.body;
var codeMirror = CodeMirror(editorElement);
var mouseEvents = [
'click',
'contextmenu',
'dbclick',
'mousedown',
'mouseenter',
'mouseleave',
'mousemove',
'mouseover',
'mouseout',
'mouseup'
];
var mouseEventsLog = [];
var lastCursorPosition = null;
var doAction = function() {
var previousEvent = mouseEventsLog[mouseEventsLog.length - 2];
var lastEvent = mouseEventsLog[mouseEventsLog.length - 1];
if (((previousEvent === 'mousedown' && lastEvent === 'mouseup') || lastEvent === 'click') &&codeMirror.getSelection().length <= 0) {
if (codeMirror.getCursor() !== lastCursorPosition) {
console.log('Cursor changed by clicking.');
}
}
lastCursorPosition = codeMirror.getCursor();
};
for (var i = 0; i < mouseEvents.length; i++) {
editorElement.addEventListener(mouseEvents[i], function(event) {
mouseEventsLog.push(event.type);
if (event.type == 'mouseup') {
doAction();
}
}, false);
}
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="http://codemirror.net/mode/javascript/javascript.js"></script>
<link href="https://codemirror.net/lib/codemirror.css" rel="stylesheet"/>
注:我试过组合cursorActivity
和鼠标事件,但是cursorActivity
先于它们执行?我实际上不确定那里发生了什么 =D
您可以使用钩子连接到 CodeMirror,并定义您自己的事件,当光标从编辑器上单击鼠标改变时触发
CodeMirror.defineInitHook(function (editor) {
editor.cursorDidChange = false;
$(editor.getWrapperElement()).on({
mousedown : function() {
if (editor.cursorDidChange) CodeMirror.signal(editor, 'cursorClick');
},
mouseup : function() {
editor.cursorDidChange = false;
}
});
editor.on('cursorActivity', function(e) {
if (e.isSelection) editor.cursorDidChange = true;
});
editor.on('beforeSelectionChange', function(e, range) {
var start = range.ranges[0].anchor, end = range.ranges[0].head;
e.isSelection = range.origin == '*mouse' && start.line == end.line && start.ch == end.ch;
})
});
如果这两个事件在短时间内彼此发生,这将使用一个标志和一个计时器来捕获这两个事件,因为点击处理程序会在 cursorActivity 处理程序之后立即触发。
下面是一个工作示例,说明如何将新定义的事件与 CodeMirror 一起使用:
/* Create Hook */
CodeMirror.defineInitHook(function (editor) {
editor.cursorDidChange = false;
$(editor.getWrapperElement()).on({
mousedown : function() {
if (editor.cursorDidChange) CodeMirror.signal(editor, 'cursorClick');
},
mouseup : function() {
editor.cursorDidChange = false;
}
});
editor.on('cursorActivity', function(e) {
if (e.isSelection) editor.cursorDidChange = true;
});
editor.on('beforeSelectionChange', function(e, range) {
var start = range.ranges[0].anchor, end = range.ranges[0].head;
e.isSelection = range.origin == '*mouse' && start.line == end.line && start.ch == end.ch;
})
});
/* -------------- */
/* Create an editor to test it */
var $this = $('.code').eq(0),
$code = $this.html(),
$unescaped = $('<div/>').html($code).text();
$this.empty();
var editor = CodeMirror($this.get(0), {
value : $unescaped,
mode : 'javascript',
lineNumbers : true,
readOnly : false
});
/* Lets test out the new event */
editor.on('cursorClick', function() {
$('<div />', {text : 'Cursor moved when clicked !'}).appendTo('#result')
.show(1).delay(1000).fadeOut(function() {
$(this).remove();
});
});
body {background: #eee;}
.code {margin: 10px 0;}
#result {color: green;}
.CodeMirror {height: auto!important;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="https://codemirror.net/mode/javascript/javascript.js"></script>
<link href="https://codemirror.net/lib/codemirror.css" rel="stylesheet"/>
<!-- EDITOR -->
<div class="code">test.fn = test.prototype = {
display : function() {}
console.log("Move cursor by clicking");
console.log("Move cursor with keys");
},
pushStack: function( elems ) {
// This is just pseudocode to have something to test
}
return false;
}</div>
<!-- EDITOR END -->
<div id="result"></div>
我想在用户通过鼠标单击将光标移动到另一个位置时执行某些操作,但在通过键盘操作完成时不执行此操作(箭头、pageup/pagedown、home/end) .
- 我不能只听
cursorActivity
因为它会触发键盘和鼠标操作。 - 我不确定我是否可以收听
mousedown
,因为它可能是不是光标位置更改(例如选择、拖动)的开始。
捕捉那些由鼠标引起的光标移动的最佳方法是什么?
您可以收听这些事件:
- 鼠标按下
- cursorActivity
- 按键
- 变更前
如果满足以下条件,则通过鼠标单击移动了光标:
cursorActivity
事件在mousedown
事件后触发- 两个事件之间没有按下移动键
- 两次活动内容没有变化
- 没有选择文本
var movedByMouse = false;
var editor = CodeMirror(document.body);
editor.on("mousedown", function () {
movedByMouse = true;
});
editor.on("cursorActivity", function () {
if (movedByMouse) {
movedByMouse = false;
if (!editor.getSelection()) {
console.log("Moved by mouse");
}
}
});
editor.on("keydown", function () {
if (isMovementKey(event.which)) {
movedByMouse = false;
}
});
editor.on("beforeChange", function () {
movedByMouse = false;
});
function isMovementKey(keyCode) {
return 33 <= keyCode && keyCode <= 40;
};
<link href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.20.2/codemirror.min.js"></script>
所有鼠标事件(我知道的):
- 点击
- 上下文菜单
- ondbclick
- 鼠标按下
- onmouseenter
- onmouseleave
- onmousemove
- 鼠标悬停
- onmouseout
- onmouseup
所以,基本上,javascript AFAIK 中没有解决您的问题的方法。但是,您可以采用第二个建议并跟踪事件,并根据事件选择是否执行您的操作。
var editorElement = document.body;
var codeMirror = CodeMirror(editorElement);
var mouseEvents = [
'click',
'contextmenu',
'dbclick',
'mousedown',
'mouseenter',
'mouseleave',
'mousemove',
'mouseover',
'mouseout',
'mouseup'
];
var mouseEventsLog = [];
var lastCursorPosition = null;
var doAction = function() {
var previousEvent = mouseEventsLog[mouseEventsLog.length - 2];
var lastEvent = mouseEventsLog[mouseEventsLog.length - 1];
if (((previousEvent === 'mousedown' && lastEvent === 'mouseup') || lastEvent === 'click') &&codeMirror.getSelection().length <= 0) {
if (codeMirror.getCursor() !== lastCursorPosition) {
console.log('Cursor changed by clicking.');
}
}
lastCursorPosition = codeMirror.getCursor();
};
for (var i = 0; i < mouseEvents.length; i++) {
editorElement.addEventListener(mouseEvents[i], function(event) {
mouseEventsLog.push(event.type);
if (event.type == 'mouseup') {
doAction();
}
}, false);
}
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="http://codemirror.net/mode/javascript/javascript.js"></script>
<link href="https://codemirror.net/lib/codemirror.css" rel="stylesheet"/>
注:我试过组合cursorActivity
和鼠标事件,但是cursorActivity
先于它们执行?我实际上不确定那里发生了什么 =D
您可以使用钩子连接到 CodeMirror,并定义您自己的事件,当光标从编辑器上单击鼠标改变时触发
CodeMirror.defineInitHook(function (editor) {
editor.cursorDidChange = false;
$(editor.getWrapperElement()).on({
mousedown : function() {
if (editor.cursorDidChange) CodeMirror.signal(editor, 'cursorClick');
},
mouseup : function() {
editor.cursorDidChange = false;
}
});
editor.on('cursorActivity', function(e) {
if (e.isSelection) editor.cursorDidChange = true;
});
editor.on('beforeSelectionChange', function(e, range) {
var start = range.ranges[0].anchor, end = range.ranges[0].head;
e.isSelection = range.origin == '*mouse' && start.line == end.line && start.ch == end.ch;
})
});
如果这两个事件在短时间内彼此发生,这将使用一个标志和一个计时器来捕获这两个事件,因为点击处理程序会在 cursorActivity 处理程序之后立即触发。
下面是一个工作示例,说明如何将新定义的事件与 CodeMirror 一起使用:
/* Create Hook */
CodeMirror.defineInitHook(function (editor) {
editor.cursorDidChange = false;
$(editor.getWrapperElement()).on({
mousedown : function() {
if (editor.cursorDidChange) CodeMirror.signal(editor, 'cursorClick');
},
mouseup : function() {
editor.cursorDidChange = false;
}
});
editor.on('cursorActivity', function(e) {
if (e.isSelection) editor.cursorDidChange = true;
});
editor.on('beforeSelectionChange', function(e, range) {
var start = range.ranges[0].anchor, end = range.ranges[0].head;
e.isSelection = range.origin == '*mouse' && start.line == end.line && start.ch == end.ch;
})
});
/* -------------- */
/* Create an editor to test it */
var $this = $('.code').eq(0),
$code = $this.html(),
$unescaped = $('<div/>').html($code).text();
$this.empty();
var editor = CodeMirror($this.get(0), {
value : $unescaped,
mode : 'javascript',
lineNumbers : true,
readOnly : false
});
/* Lets test out the new event */
editor.on('cursorClick', function() {
$('<div />', {text : 'Cursor moved when clicked !'}).appendTo('#result')
.show(1).delay(1000).fadeOut(function() {
$(this).remove();
});
});
body {background: #eee;}
.code {margin: 10px 0;}
#result {color: green;}
.CodeMirror {height: auto!important;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="https://codemirror.net/mode/javascript/javascript.js"></script>
<link href="https://codemirror.net/lib/codemirror.css" rel="stylesheet"/>
<!-- EDITOR -->
<div class="code">test.fn = test.prototype = {
display : function() {}
console.log("Move cursor by clicking");
console.log("Move cursor with keys");
},
pushStack: function( elems ) {
// This is just pseudocode to have something to test
}
return false;
}</div>
<!-- EDITOR END -->
<div id="result"></div>