用 js 的 selection range 操作选择区域内容和图片


Posted in Javascript onApril 18, 2017

先放上最后的效果,这是点击图片以前:

用 js 的 selection range 操作选择区域内容和图片

这是点击图片以后:

用 js 的 selection range 操作选择区域内容和图片

非常清晰,一目了然,就算是小白用户也明白发生了什么。挺好的。

最近在做编辑器相关的东西,遇到一个需求,用户在编辑器中插入或者粘贴的图片要支持点击以后,可以按 Backspace 键或者 Delete 键删除掉。

刚开始拿到这个需求的想法是调用编辑器自带的删除图片方法删掉图片,但后来查看源码发现这个方法是编辑器内部方法,并没有暴露出来,于是第一个思路走不通了。

第二个思路是在编辑器的顶层容器里监听 keyup 事件,然后判断是否是两个删除键,如果是就拦截,然后找到当前点击的图片,手动删掉。

实际上这也是行不通的,原因有二。首先,这个删除是没法阻止的,因为事件的监听是在顶层父元素里,这时候阻止其实是阻止掉事件在顶层容器上的效果,而不是在发生元素上的效果。所有涉及到事件冒泡的地方,在父容器上阻止效果都是不能达到目的的,只能在事件最开始发生的元素上阻止。 

然后,当按下删除键的时候,之前点击的图片已经不是点击状态了,已经拿不到了。因为取消选择在前,删除在后。

后来忽然意识到,想要的效果其实就是点击图片的时候选中图片,就像用户自己选中网页中一段内容那样选中那张图片就好了。页面上点击一个图片默认是没有效果的,我要做的仅仅是点击时候选中这个图片就可以了。这样做的好处是,当用户点击图片选中以后,如果点删除键,无论是 Backspace 还是 Delete 键都可以删除;而且如果用户不像删除,直接点击别的地方,或者按下上下左右箭头就可以取消选择,这和用户平时的操作体验是一样的,根本没有什么副作用。

selection 是 HTML5 的新接口,是 window 的一个方法,用法是 window.getSelection().

取得 selection 以后,要把当前图片加入到选取中,selection 有一个 Selection.selectAllChildren() 方法,但这个方法只能选中元素的全部子元素,而我们要选中的是 img 元素自身,img 元素也没有子元素。于是继续在 selection 的方法中看看有没有别的长的像的方法,果然,找到了 Selection.addRange() 看这长相一看就很像我们要找的人。addRange 方法需要传入一个 range 对象,range是啥呢?

平时在页面上选择东西都是鼠标咔一下框一大片,但如果在编辑器里,其实是可以选择好几个片段的,一般按住 Ctrl / Control 键就可以多处选择。我猜这个 selection 就类似于选中的所有区域,range 就类似于每一个单独的选中的片段,先这么理解。

继续往下看,发现 range 有一个 Range.selectNode() 方法,这不正是我要找的人吗?先创建一个 range 对象,let range = document.createRange()  createRange 是 document 的方法,然后讲当前图片插入 range,再把 range 插入 selection 中即可。代码如下:

let checkClickImg = function(e) {
 let target = e.target;
 if (target.nodeName.toLowerCase() === 'img') {
  // 删除之前所有的选区
  window.getSelection().removeAllRanges();
  let selection = window.getSelection();
  let range = document.createRange();
  range.selectNode(target);
  selection.addRange(range);
 }
}

这个实现方法的最大优点在于利用浏览器原生自带的功能,这样就和用户的操作习惯保持一致,不会有任何的突兀。选中的效果很明显,而且选中以后无论是删除,还是取消,都跟之前习惯一致,都很容易,更要的是这些操作不用再写代码了啊,因为是浏览器原生自带的功能。

嗯,算是比较完美了。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
setInterval与clearInterval的使用示例代码
Jan 28 Javascript
JQuery以JSON方式提交数据到服务端示例代码
May 05 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
Jun 30 Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
Sep 15 Javascript
jQuery实现弹窗居中效果类似alert()
Feb 27 Javascript
iscroll实现下拉刷新功能
Jul 18 Javascript
webpack 2.x配置reactjs基本开发环境详解
Aug 08 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
Mar 17 Javascript
AngularJS下$http服务Post方法传递json参数的实例
Mar 29 Javascript
详解微信小程序input标签正则初体验
Aug 18 Javascript
vuejs实现下拉框菜单选择
Oct 23 Javascript
vue实现下载文件流完整前后端代码
Nov 17 Vue.js
jacascript DOM节点——元素节点、属性节点、文本节点
Apr 18 #Javascript
Angularjs根据json文件动态生成路由状态的实现方法
Apr 17 #Javascript
微信小程序实战之轮播图(3)
Apr 17 #Javascript
微信小程序实战之顶部导航栏(选项卡)(1)
Jun 19 #Javascript
微信小程序实战之上拉(分页加载)效果(2)
Apr 17 #Javascript
微信小程序教程系列之新建页面(4)
Apr 17 #Javascript
微信小程序商城项目之淘宝分类入口(2)
Apr 17 #Javascript
You might like
apache+codeigniter 通过.htcaccess做动态二级域名解析
2012/07/01 PHP
深入PHP操作MongoDB的技术总结
2013/06/02 PHP
php版淘宝网查询商品接口代码示例
2014/06/17 PHP
在laravel5.2中实现点击用户头像更改头像的方法
2019/10/14 PHP
Laravel 实现添加多语言提示信息
2019/10/25 PHP
COM中获取JavaScript数组大小的代码
2009/11/22 Javascript
jQuery实现的感应鼠标悬停图片色彩渐显效果
2015/03/03 Javascript
JavaScript将当前时间转换成UTC标准时间的方法
2015/04/06 Javascript
纯javascript实现四方向文本无缝滚动效果
2015/06/16 Javascript
详解javascript事件冒泡
2016/01/09 Javascript
使用jQuery制作浮动工具栏的实例分享
2016/05/13 Javascript
js 用于检测类数组对象的函数方法
2017/05/02 Javascript
angular-ngSanitize模块-$sanitize服务详解
2017/06/13 Javascript
浅谈Vue下使用百度地图的简易方法
2018/03/23 Javascript
vue 弹框产生的滚动穿透问题的解决
2018/09/21 Javascript
vue项目中仿element-ui弹框效果的实例代码
2019/04/22 Javascript
解决layui-table单元格设置为百分比在ie8下不能自适应的问题
2019/09/28 Javascript
[11:01]2014DOTA2西雅图邀请赛 冷冷带你探秘威斯汀
2014/07/08 DOTA
[43:03]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
Python和php通信乱码问题解决方法
2014/04/15 Python
python网络编程之数据传输UDP实例分析
2015/05/20 Python
python动态网页批量爬取
2016/02/14 Python
Python标准库06之子进程 (subprocess包) 详解
2016/12/07 Python
python入门前的第一课 python怎样入门
2018/03/06 Python
Python Matplotlib库安装与基本作图示例
2019/01/09 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
使用Django简单编写一个XSS平台的方法步骤
2019/03/25 Python
keras得到每层的系数方式
2020/06/15 Python
python语言中有算法吗
2020/06/16 Python
jupyter notebook指定启动目录的方法
2021/03/02 Python
北大青鸟学生求职信
2013/09/24 职场文书
物流专业大学的自我评价
2014/01/11 职场文书
创业培训计划书
2014/05/03 职场文书
芙蓉镇观后感
2015/06/10 职场文书
解决Mysql报错 Table 'mysql.user' doesn't exist
2022/05/06 MySQL
Python使用Beautiful Soup(BS4)库解析HTML和XML
2022/06/05 Python