javascript 实现富文本框选中对齐
需求:
一个可编辑(contenteditable=true)的div,对齐选中内容,左、中,右 ,其实质是:对选中的末梢节点,找到块属性的父元素,设置text-algin:center:
MDN:
text-align
CSS属性定义行内内容(例如文字)如何相对它的块父元素对齐。text-align
并不控制块元素自己的对齐,只控制它的行内内容的对齐。
分析需求:
我们来分解一下这个需求的三个关键问题: ”选中部分“,”块元素“,"末梢元素"
1如何获取选中的部分 *
这里涉及到的Web API Document.getSelection().getRangeAt(0) 这里只处理一个选取的情况
注意:光标所在位置,光标所在节点 视为选中区域
2什么是块元素
MDN:
display:block
这个值会生成一个块级元素盒子,同时在该元素之前和之后打断(换行)。简单来说就是,这个值会将该元素变成块级元素。
除非特殊指定,诸如标题(
<h1>
等)和段落(<p>
)默认情况下都是块级的盒子。
用做链接的
<a>
元素、<span>
、<em>
以及<strong>
都是默认处于inline
状态的。
3末梢元素(没有子节点的元素)
我们操作对齐,实质是操作盒模型中的内容的对齐方式,也就是对:图片,文字 等设置对齐样式,在这里我称其为末梢节点
实现思路:
1、获取选区内的所有末梢元素(递归)
2、找到这些末梢元素的父块元素,设置其text-align:'left|center|right'
代码实现:
前端页面:一个div contenteditable="true";三个按钮:触发对齐(左,中,右)
document.querySelector("#btn_alignl").addEventListener("click", () => { Align.call(this, 'left') })
document.querySelector("#btn_alignc").addEventListener("click", () => { Align.call(this, 'center') })
document.querySelector("#btn_alignr").addEventListener("click", () => { Align('right') })
js 代码:
1、一个公共的Align方法,参数为:left|center|right
/**
* 1 通过getEndNodes(PNode,startNode,endNode, ResultNodes)获取PNode中在startNode和ResultNodes之间的所有末梢元素
* 2 遍历EndNodes,通过getBlockParent获取每一个endNode的父级block元素
* 3 设置endnode 的 blockparent.style.textAlign=left|center|right
* @param alignStr left|center|right
**/
function Align(alignStr) {
const rng = document.getSelection().getRangeAt(0)
const commonAncestor = rng.commonAncestorContainer
isStarted = false, isEnded = false
const startEndNode=getEndNodes(rng.startContainer,rng.startContainer,rng.startContainer,[])[0]
isStarted = false, isEnded = false
const endEndNode=getEndNodes(rng.endContainer,rng.endContainer,rng.endContainer,[])[0]
isStarted = false, isEnded = false
const EndNodes = getEndNodes(commonAncestor,startEndNode,endEndNode,[])
EndNodes.forEach(node => {
const blockparent = getBlockParent(node)
if (!!blockparent && blockparent.style.textAlign != alignStr) {
blockparent.style.textAlign = alignStr
}
})
}
获取选中元素的末梢节点的方法
let isStarted = false, isEnded = false
function getEndNodes(PNode,startNode,endNode, ResultNodes) {
if (PNode == startNode) { isStarted = true }
if (PNode == endNode) {
isEnded = true
ResultNodes.push(PNode)
console.log(PNode)
}
if (isStarted == true && isEnded == false && PNode.hasChildNodes()==false) { ResultNodes.push(PNode) ;console.log(PNode)}
if (PNode.hasChildNodes() && isEnded==false) {
PNode.childNodes.forEach(node => {
getEndNodes(node, startNode,endNode, ResultNodes)
});
}
// debugger
return ResultNodes
}
getBlockParent的实现--获取选中末梢节点的块父节点的实现
let blockTags = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'ul', 'ol', 'li', 'div', 'body', 'td', 'th']
// let inlineTags = ['img', 'font', 'b', 'strong', 'span', 'a']
let blockTagSet = new Map()
blockTags.forEach((v) => { blockTagSet.set(v, true) });
const source = document.querySelector('div.source');
function getBlockParent(ele) {
let result = undefined
if (ele === source) {
console.log('已找到editor的根,并没有找父级block元素');
result = undefined
} else {
switch (ele.nodeType) {
//element: 判断ele是否是块级元素,判断依据1 display:block 2 默认的块级元素
case 1: {
const disPro = ele.style.display;
if (disPro && disPro.toLowerCase().indexOf('block') > -1) {
result = ele;
} else if (blockTagSet.get(ele.tagName.toLowerCase())) { result = ele }
else { result = getBlockParent(ele.parentElement) }
break;
}
case 3: {//textNode
if (!!ele.nodeValue.trim())
result = getBlockParent(ele.parentElement)
else result = undefined
break;
}
default: {
break;
}
} //end switch
}//end if
return result
}
javascript 实现富文本框选中对齐的更多相关文章
- django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用
一.modelForm操作及验证 1.获取数据库数据,界面展示数据并且获取前端提交的数据,并动态显示select框中的数据 views.py from django.shortcuts import ...
- 常用的富文本框插件FreeTextBox、CuteEditor、CKEditor、FCKEditor、TinyMCE、KindEditor ;和CKEditor实例
http://www.cnblogs.com/cxd4321/archive/2013/01/30/2883078.html 目前市面上用的比较多的富文本编辑器有: FreeTextBox 一个有很多 ...
- Android 富文本框实现 RichEditText
Android系统自带控件没有富文本框控件,如果想写一封带格式的邮件基本上不可能,EdtiText只有默认一种格式,显示不能滿足要求,!!正好项目需要研究了一下,开发了此控件,现将一些源代码开放一下, ...
- python webdriver api-操作富文本框
操作富文本框-就是邮件正文部分,可以选字体啥的 第一种方式: 一般都是在iframe里,要切进去,一般是”html/body”,编辑之后,再切出来,然后再send_keys就完事儿 #encoding ...
- webdriver高级应用- 操作富文本框
富文本框的技术实现和普通的文本框的定位存在较大的区别,富文本框的常见技术用到了Frame标签,并且在Frame里面实现了一个完整的HTML网页结构,所以使用普通的定位模式将无法直接定位到富文本框对象. ...
- 基于bootstrap的富文本框——wangEditor【欢迎增加开发】
先来一张效果图: 01. 引言 老早就開始研究富文本框的东西,在写完<深入理解javascript原型与闭包>之后,就想着要去做一个富文本框的插件的样例. 如今网络上开源的富文本框插件许多 ...
- web轻量级富文本框编辑
前言 主要介绍squire,wangeditor富文本编辑 以及用原生js 如何实现多个关键字标识 需求 如何标记多个关键字,取消关键字 第一种方法 原生 textarea 标记 准备资料参考:张鑫旭 ...
- kindeditor富文本框,上传文件后,显示文件名称
kindeditor作为一个应用广泛富文本框,我们经常会利用到它,然而在使用的过程中,发现有的地方使用起来很不方便,例如本文要说的,用户上传文件之后,默认只有文件URL,没有文件说明,如图: 点击确定 ...
- selenium 富文本框处理
selenium 富文本框处理, 网上有用API的解决方法1:参见:http://blog.csdn.net/xc5683/article/details/8963621 群里1位群友的解决方法2:参 ...
随机推荐
- Pandas中Series与Dataframe的区别
1. Series Series通俗来讲就是一维数组,索引(index)为每个元素的下标,值(value)为下标对应的值 例如: arr = ['Tom', 'Nancy', 'Jack', 'Ton ...
- netty系列之:让TCP连接快一点,再快一点
简介 经典的TCP三次握手大家应该很熟悉了,三次握手按道理说应该是最优的方案了,当然这是对于通用的情况来说的.那么在某些特殊的情况下是不是可以提升TCP建立连接的速度呢? 答案是肯定的,这就是今天我们 ...
- pytest(7)-yield与终结函数
通过上一篇文章,我们已经知道了pytest中,可以使用Fixture来完成运行测试用例之前的一些操作如连接数据库,以及测试执行之后自动去做一些善后工作如清空脏数据.关闭数据库连接等. 我们已经学会了f ...
- 探针配置失误,线上容器应用异常死锁后,kubernetes集群未及时响应自愈重启容器?
探针配置失误,线上容器应用异常死锁后,kubernetes集群未及时响应自愈重启容器? 探针配置失误,线上容器应用异常死锁后,kubernetes集群未及时响应自愈重启容器? 线上多个服务应用陷入了死 ...
- nginx负载均衡中利用redis解决session一致性问题
关于session一致性的现象及原因不是本小作文的重点,可以另行找杜丽娘O(∩_∩)O哈哈~重点是利用redis集中存储共享session的实际操作. 一.业务场景:nginx/tomcat/redi ...
- ReentrantLock与synchronized比较分析
ReentrantLock:完成了Lock接口,是一个可重入锁,并且支持线程公正竞赛和非公正竞赛两种形式,默认情况下对错公正形式.ReentrantLock算是synchronized的补充和替代计划 ...
- sql server 数据字符串替换函数
sql server 替换函数 replace 函数参数 REPLACE(string_expression, string_pattern, string_replacement) 1.string ...
- Java刷题时常用的标准库数据结构和相应算法
目录 一.线性表(广义的数组) 1. 数组 一维数组的定义和初始化 二维数组的定义和初始化 Arrays工具类的一些常用方法 2. List接口容器 对象的构建 读写和插入删除数据 排序 反转数组 二 ...
- 【C#基础概念】虚方法virtual
目录: 一.虚方法的概念 二.虚方法的特点 三.虚方法的作用 四.虚方法的声明 五.虚方法的执行 六.虚拟类的规则 一.虚方法的概念 在C#中,虚方法就是可以被子类重写的方法,如果子类重写了虚方法,则 ...
- 给npm换源
为什么要换源? npm 官方站点 http://www.npmjs.org/ 并没有被墙,但是下载第三方依赖包的速度让人着急啊! 幸运的是,国内有几个镜像站点可以供我们使用,本人在使用 http:// ...