Skip to content

Improve mouse selection blocks #14010

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 5, 2025
Merged

Improve mouse selection blocks #14010

merged 2 commits into from
Feb 5, 2025

Conversation

TCOTC
Copy link
Contributor

@TCOTC TCOTC commented Feb 3, 2025

01 改进后效果:

video.webm

02 改进后效果:

video.webm

待解决:

还有 Shift+Click 多选块的问题需要 #14012 解决:

video.webm

@TCOTC TCOTC marked this pull request as draft February 3, 2025 16:02
@TCOTC TCOTC marked this pull request as ready for review February 3, 2025 16:49
@Vanessa219 Vanessa219 merged commit 2863eec into siyuan-note:dev Feb 5, 2025
6 checks passed
@Vanessa219 Vanessa219 self-requested a review February 5, 2025 03:37
@Vanessa219 Vanessa219 added this to the 3.1.21 milestone Feb 5, 2025
@TCOTC TCOTC deleted the fix/12120 branch February 5, 2025 05:12
Vanessa219 added a commit that referenced this pull request Feb 5, 2025
@Vanessa219 Vanessa219 self-assigned this Feb 5, 2025
@88250 88250 changed the title fix: 鼠标框选块或单元格时不应选中其中的文本 Improve mouse selection blocks Feb 6, 2025
@TCOTC
Copy link
Contributor Author

TCOTC commented Feb 7, 2025

这里为啥又去掉了,选中文本再按 Esc 就是不应该有选中背景的啊

image

@Vanessa219
Copy link
Member

然后shift+右选择文本没有背景色,这个需要统一处理,否则这个 bug 有点严重。

@TCOTC
Copy link
Contributor Author

TCOTC commented Feb 8, 2025

这个要怎么复现?我这样操作没问题:

video.webm

@TCOTC
Copy link
Contributor Author

TCOTC commented Feb 8, 2025

哦不对,是右方向键。

我觉得不显示还是合理的吧,毕竟选中块之后也不应该还能选择文本。

@Vanessa219
Copy link
Member

划选后,不要用鼠标,用键盘操作。

@TCOTC
Copy link
Contributor Author

TCOTC commented Feb 9, 2025

@Vanessa219 我试了一下,选中块之后是用不了 Shift+ 选择文本的(感觉挺合理的,其他三家也不允许这样操作)

video.webm

@TCOTC
Copy link
Contributor Author

TCOTC commented Feb 19, 2025

@Vanessa219 还有个问题,表格 .table__select 用 pointer-events:none; 的方法会有什么问题吗?

@Vanessa219
Copy link
Member

Shift+→ 在块选中的情况下目前也是不可划选的。
列宽调整的线会暴露出来。

mouyase pushed a commit to mouyase/siyuan that referenced this pull request Feb 28, 2025
* fix: 鼠标框选块或单元格时不应选中其中的文本

fix siyuan-note#12120

* refactor: 表格选择单元格不灵活

fix siyuan-note#11388
mouyase pushed a commit to mouyase/siyuan that referenced this pull request Feb 28, 2025
mouyase pushed a commit to mouyase/siyuan that referenced this pull request Feb 28, 2025
@TCOTC
Copy link
Contributor Author

TCOTC commented Apr 13, 2025

这里为啥又去掉了,选中文本再按 Esc 就是不应该有选中背景的啊

image

然后shift+右选择文本没有背景色,这个需要统一处理,否则这个 bug 有点严重。

@Vanessa219 这个地方我还是不理解,能不能再解释一下?

无论是否去掉这段代码,选中块之后按 Shift+Shift+ 都是没法选择文本的吧

@Vanessa219
Copy link
Member

  1. 划选
  2. esc
  3. shift+左/右
Jietu20250413-173206-HD.mp4

@TCOTC
Copy link
Contributor Author

TCOTC commented Apr 13, 2025

选中块的情况下按 Esc 之后执行 protyle.wysiwyg.element.classList.remove("protyle-wysiwyg--hiderange"); 应该就行了?

@Vanessa219
Copy link
Member

Vanessa219 commented Apr 14, 2025

可能会有其他没有考虑到的情况,这样用户就无法看到选中的内容了。问题比较严重。

比如拖拽,同步,回调,刷新等(没有测试过,但点比较多)

@TCOTC
Copy link
Contributor Author

TCOTC commented Apr 14, 2025

可以先把能想到的情况都解决了,之后遇到特殊情况再继续改进。我觉得应该不会很严重,鼠标划一下还是点一下就可以恢复选择文本的背景色了。

@Vanessa219
Copy link
Member

这是高频功能,不能忽视。

@TCOTC
Copy link
Contributor Author

TCOTC commented Apr 15, 2025

那不用 CSS,用操作文本选区的方案行不行,我用 AI 生成了一个示例(有BUG,但能表达我的意思):


要实现在鼠标从第一个段落(1)划选到第二个段落(2)时取消选区,并在移回第一个段落时恢复选区,可以通过以下步骤实现:

方法说明

  1. 监听选区变化:使用 selectionchange 事件检测用户划选行为。
  2. 保存和清除选区:当选区跨越两个段落时,保存当前选区并清除。
  3. 恢复选区:当鼠标移回第一个段落时,恢复之前保存的选区。

实现代码

<p id="p1">111111111111111111</p>
<p id="p2">222222222222222222</p>

<script>
let savedRange = null; // 保存选区的变量

// 检查节点是否在指定元素内
function isInElement(node, elementId) {
  const element = document.getElementById(elementId);
  return element.contains(node);
}

// 监听选区变化
document.addEventListener('selectionchange', () => {
  const selection = document.getSelection();
  if (!selection.rangeCount) return;

  const range = selection.getRangeAt(0);
  const startInP1 = isInElement(range.startContainer, 'p1');
  const endInP2 = isInElement(range.endContainer, 'p2');

  // 如果选区从p1开始并在p2结束,保存并清除
  if (startInP1 && endInP2) {
    savedRange = range.cloneRange();
    selection.removeAllRanges();
  }
});

// 鼠标移入p1时恢复选区
document.getElementById('p1').addEventListener('mouseenter', () => {
  if (savedRange) {
    const selection = document.getSelection();
    selection.removeAllRanges();
    selection.addRange(savedRange);
    savedRange = null; // 恢复后清空
  }
});
</script>

关键点解释

  1. 保存选区:当用户划选跨越两个段落时,利用 cloneRange() 保存当前选区,随后清除。
  2. 选区恢复:鼠标移回第一个段落时,将保存的选区重新应用到当前选择。
  3. 事件监听selectionchange 监听所有选区变化,mouseenter 处理移回恢复。

注意事项

  • 实时性selectionchange 可能频繁触发,但现代浏览器处理高效。
  • 兼容性:确保浏览器支持 Selection API(主流浏览器均支持)。
  • 用户交互:此实现依赖用户在拖选过程中移回,松开鼠标后恢复需另处理。

通过这种方式,用户划选到第二个段落时会立即清除选区,移回第一个段落时自动恢复,提供流畅的交互体验。

@Vanessa219
Copy link
Member

试了一下,不行。无法上下拖拽滚动了。

@TCOTC
Copy link
Contributor Author

TCOTC commented Apr 17, 2025

那看来没有很完美的方法了,直接用这个 CSS 怎么样?应该能解决大部分问题

.protyle-wysiwyg--select ::selection,
.protyle-wysiwyg--hl ::selection {
    background-color: transparent;
}
.protyle-wysiwyg--select + [data-node-id] ::selection,
.protyle-wysiwyg--hl + [data-node-id] ::selection {
    background-color: transparent;
}

@Vanessa219
Copy link
Member

这个是不是以前说过,但是没有用,还记得为什么不?

@TCOTC
Copy link
Contributor Author

TCOTC commented Apr 17, 2025

因为没有其他的完美的方案,所以我现在能接受这个 CSS 了,至少用了比不用更好

#12120 1楼:

image

Vanessa219 added a commit that referenced this pull request Apr 18, 2025
@Vanessa219
Copy link
Member

改了一下再看看吧。

@TCOTC
Copy link
Contributor Author

TCOTC commented Apr 18, 2025

还有这个也需要修改一下:#14012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants