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:参 ...
随机推荐
- 帆软报表(finereport)控件背景色更改
setTimeout(function() { $('.fr-trigger-btn-up').css({ "background-color": "#003399&qu ...
- Solution -「BZOJ 3331」压力
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),令 \(u\) 到 \ ...
- vue methods中的函数调用时带括号与不带括号的区别
@click='getList(id)',但是为什么有时候明明没有传参的需要,却要加上()呢? 百思不得其解,于是去查阅了相关的资料,意思就是,当不加括号直接调用这个函数是可以直接获取到这个事件对象的 ...
- CentOS7安装及配置 Zabbix全步骤,超详细教程
服务器太多,还在不同的平台和账户,监控不便 整个 Zabbix 监控,开始吧 一.关闭防火墙并开机不启动 sudo setenforce 0 sudo sed -i "s/SELINUX=e ...
- [LeetCode]1512. 好数对的数目
给你一个整数数组 nums . 如果一组数字 (i,j) 满足 nums[i] == nums[j] 且 i < j ,就可以认为这是一组 好数对 . 返回好数对的数目. 示例 1: 输入:nu ...
- python数据结构:链表
链表与列表.数组这线性结构不同之处在于其在首末两端增删的话比较方便 单链表: 但是链表查找和删除的话都是需要从第一个开始从头查找 因此查找和删除的复杂度都为O(n) 双链表: 相比单链表来说,每个节点 ...
- Renix软件如何发送CRC错误的报文——网络测试仪实操
我们在日常使用Renix软件时,有时候需要发送CRC错误的报文,那么如何操作呢?接下来为你详细介绍一下操作步骤. 1.打开Renix软件,连接机框并预约测试端口: 2.添加流模板 3.给P1设置CRC ...
- 都在用神器,只有你还在死磕excel做分析
一.excel数据分析工具_EXCE弱点 EXCEL一直是非常流行的个人计算机数据处理工具,它可以处理多种多样的数据,操作非常简单,支持丰富的函数.统计图表,在工作中更是非常得力的生产力工具.然而随着 ...
- 【C# 线程】数据槽 LocalDataStoreSlot简称DataSlot
背景 为了确保在线程中声明特定类型的变量,在每个线程中的值都是唯一的,不受到其他线程对该变量读写的影响.也就是俗称的线程本地存储 (TLS),可用于存储对线程和应用程序域唯一的数据. 例如:主线程中声 ...
- JAVA只要掌握内部类,多继承和单继承都不是问题
摘要:如果实现java的多继承,其实很简单,关键是对于内部类的特征的掌握,内部类可以继承一个与外部类无关的类,保证了内部类天然独立性,根据这个特性从而实现一个类可以继承多个类的效果. 本文分享自华为云 ...