需求:

一个可编辑(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 实现富文本框选中对齐的更多相关文章

  1. django(7)modelform操作及验证、ajax操作普通表单数据提交、文件上传、富文本框基本使用

    一.modelForm操作及验证 1.获取数据库数据,界面展示数据并且获取前端提交的数据,并动态显示select框中的数据 views.py from django.shortcuts import ...

  2. 常用的富文本框插件FreeTextBox、CuteEditor、CKEditor、FCKEditor、TinyMCE、KindEditor ;和CKEditor实例

    http://www.cnblogs.com/cxd4321/archive/2013/01/30/2883078.html 目前市面上用的比较多的富文本编辑器有: FreeTextBox 一个有很多 ...

  3. Android 富文本框实现 RichEditText

    Android系统自带控件没有富文本框控件,如果想写一封带格式的邮件基本上不可能,EdtiText只有默认一种格式,显示不能滿足要求,!!正好项目需要研究了一下,开发了此控件,现将一些源代码开放一下, ...

  4. python webdriver api-操作富文本框

    操作富文本框-就是邮件正文部分,可以选字体啥的 第一种方式: 一般都是在iframe里,要切进去,一般是”html/body”,编辑之后,再切出来,然后再send_keys就完事儿 #encoding ...

  5. webdriver高级应用- 操作富文本框

    富文本框的技术实现和普通的文本框的定位存在较大的区别,富文本框的常见技术用到了Frame标签,并且在Frame里面实现了一个完整的HTML网页结构,所以使用普通的定位模式将无法直接定位到富文本框对象. ...

  6. 基于bootstrap的富文本框——wangEditor【欢迎增加开发】

    先来一张效果图: 01. 引言 老早就開始研究富文本框的东西,在写完<深入理解javascript原型与闭包>之后,就想着要去做一个富文本框的插件的样例. 如今网络上开源的富文本框插件许多 ...

  7. web轻量级富文本框编辑

    前言 主要介绍squire,wangeditor富文本编辑 以及用原生js 如何实现多个关键字标识 需求 如何标记多个关键字,取消关键字 第一种方法 原生 textarea 标记 准备资料参考:张鑫旭 ...

  8. kindeditor富文本框,上传文件后,显示文件名称

    kindeditor作为一个应用广泛富文本框,我们经常会利用到它,然而在使用的过程中,发现有的地方使用起来很不方便,例如本文要说的,用户上传文件之后,默认只有文件URL,没有文件说明,如图: 点击确定 ...

  9. selenium 富文本框处理

    selenium 富文本框处理, 网上有用API的解决方法1:参见:http://blog.csdn.net/xc5683/article/details/8963621 群里1位群友的解决方法2:参 ...

随机推荐

  1. Java用n种方法编写实现双色球随机摇号案例

    方法清单 规则 实现方式一 实现方式二 实现方式三 实现方式四 实现方法五 之前我用JavaScript编写过一个实现双色球随机摇号的案例, 点击此处查看,今天我再用Java语言来实现这一效果. 规则 ...

  2. Pandas中Series与Dataframe的区别

    1. Series Series通俗来讲就是一维数组,索引(index)为每个元素的下标,值(value)为下标对应的值 例如: arr = ['Tom', 'Nancy', 'Jack', 'Ton ...

  3. 抓取并解密HTTPS流量

    WireShark   Wireshark解密TLS数据流,从网上已有资料来看,主要是两种方式:一是服务端私钥直接解密,二是使用SSLKEYLOGFILE获取握手过程中的会话密钥信息进行解密.   这 ...

  4. Spring容器变化之SmartLifecycle,LifecycleProcesso接口详述

    Spring Boot run方法启动后相应的服务也随之启动,这个操作很妙.使用者都不用关心什么服务怎么启动,不管多少个服务怎么启动只要符合Spring Boot的启动规则都可以使用其run方法同一启 ...

  5. CentOS8系统上Zookeeper安装启动

    下载Zookeeper安装包,下载地址为:https://zookeeper.apache.org/releases.html.注意选择bin的gz包,否则安装不成功,提示找不到相应的类. 一.单机模 ...

  6. [源码解析] NVIDIA HugeCTR,GPU版本参数服务器--- (5) 嵌入式hash表

    [源码解析] NVIDIA HugeCTR,GPU版本参数服务器--- (5) 嵌入式hash表 目录 [源码解析] NVIDIA HugeCTR,GPU版本参数服务器--- (5) 嵌入式hash表 ...

  7. python-利用random模块生成测试数据封装方法总结

    1.前言: 在测试中经常有需要用到参数化,我们可以用random模块,faker模块生成测试数据,也可以用到pymysql,此文主要针对random模块生成任意个数的随机整数,随机字符串,随机手机号, ...

  8. IDEA如何快速生成get和set方法

    方法一:1.鼠标右击"Generate"2.点击"Getter and Setter",3.将定义的字段全部选中,点击OK.方法二:使用alt+insert 快 ...

  9. centos7云服务器安装nginx记录

    nginx作为一个web和反向服务器,应用广泛,尤其适合学习c/c++的人进行使用学习,今天就对这个我听了很多的nginx进行了一次安装配置,主要是针对菜鸟教程中的安装引导进行的个人试验.主要的关注点 ...

  10. go面试集锦1

    目录 1.go优缺点 2.go中常量是怎么实现 3.go的值传递和引用 4.go struct能不能比较 5.go协程线程安全吗 6.go中关键字 7.make和new区别 8.defer 9.生产者 ...