-
2021-06-06 00:55:32
OS : Windows 10
browser : Chrome 83.0.4103.116
editor : Visual Studio Code 1.46.1
typesetting : Markdown
?
html
Documenthello world
hello worldhello world
?
result
?
resource
[ 教程 ] www.w3school.com.cn/html/index.asp
[ 手册 ] www.w3cschool.cn/html5_reference.html
[ 规范 ] www.runoob.com/html/html5-syntax.html
[ 平台 ] www.cnblogs.com
[ 规范-参考 ] www.w3cschool.cn/wematy
[ 统计-参考 ] tongji.baidu.com/research/site#browser
?
感恩曾经帮助过 客名利 的人。
html,xhtml和html5的发展历史及其特性,建议学习。
代码的书写是有规范的,适当地遵守规范,助人助己。
Chromium和Firefox是开源浏览器,新功能众多,建议关注。
Blink,EdgeHTML,Gecko,KHTML,Trident,WebCore,WebKit等,空闲时可以了解一下。
不同的浏览器解析代码是有差别的,要多关注兼容性问题。
更多相关内容 -
行业文档-设计装置-升降划线平台.zip
2021-09-08 12:58:50行业文档-设计装置-升降划线平台 -
行业分类-设备装置-一种模块化划线平台装置.zip
2021-08-21 13:41:33行业分类-设备装置-一种模块化划线平台装置.zip -
通达信指标公式源码小平台选股及画线.doc
2021-08-11 13:47:51通达信指标公式源码小平台选股及画线.doc -
MFC橡皮筋划线
2014-03-15 11:35:47大一实习很努力很认真做的 MFC平台 附实习报告!功能齐全!还有文件数据读取实现! 橡皮筋画线程序: 要求: 基本要求利用鼠标在视图上绘制线,能够设置线的颜色和宽度; 能够用鼠标拾取绘制的某条线,被选中的线... -
手把手教你实现web文本划线的功能
2021-08-10 00:08:19来源 |https://www.cnblogs.com/wanglinmantan/p/15106871.html开篇文本划线是目前逐渐流行的一个功能,不管你是小说阅读网站,还是卖教程的...来源 | https://www.cnblogs.com/wanglinmantan/p/15106871.html
开篇
文本划线是目前逐渐流行的一个功能,不管你是小说阅读网站,还是卖教程的的网站,一般都会有记笔记或者评论的功能,传统的做法都是在文章底部加一个评论区,优点是简单,统一。
缺点是不方便对文章的某一段或一句话进行针对性的评论,所以出现了划线及评论的需求,目前我见到的产品有划线功能的有:微信阅读APP、极客时间:
InfoQ写作平台:
等等,这个功能看似简单,实际上难点还是很多的,比如如何高性能的对各种复杂的文本结构划线、如何尽可能少的存储数据、如何精准的回显划线、如何处理重复划线、如何应对文本后续编辑的情况等等。
作为一个前端搬砖工,每当看到一个有意思的小功能时我都想自己去把它做出来,但是看了仅有的几篇相关文章之后,发现,不会????,这些文章介绍的都只是一个大概思路,看完让人感觉好像会了,但是细想就会发现很多问题,只能去看源码,看源码总是费时的,还不一定能看懂。
想要实现一个生产可用的难度还是很大的,所以本文退而求其次,单纯的写一个demo开心开心。
demo效果请点击:http://lxqnsys.com/#/demo/textUnderline。
总体思路
总体思路很简单,遍历选区内的所有文本,切割成单个字符,给每个字符都包裹上划线元素,重复划线的话就在最深层继续包裹,事件处理的话从最深的元素开始。
存储的方式是记录该划线文本外层第一个非划线元素的标签名和索引,以及字符在其内所有字符里总的偏移量。
回显的方式是获取到上述存储数据对应的元素,然后遍历该元素的字符添加划线元素。
实现
HTML结构
<div class="article" ref="article"></div>
文本内容就放在上述的div里,我从掘金小册里随便挑选了一篇文章,把它的html结构原封不动的复制粘贴进去:
显示tooltip
首先要做的是在选区上显示一个划线按钮,这个很简单,我们监听一下mouseup事件,然后获取一下选区对象,调用它的getBoundingClientRect方法获取位置信息,然后设置到我们的tooltip元素上:
document.addEventListener('mouseup', this.onMouseup) onMouseup () { // 获取Selection对象,里面可能包含多个`ranges`(区域) let selObj = window.getSelection() // 一般就只有一个Range对象 let range = selObj.getRangeAt(0) // 如果选区起始位置和结束位置相同,那代表没有选到任何东西 if (range.collapsed) { return } this.range = range.cloneRange() this.tipText = '划线' this.setTip(range)} setTip (range) { let { left, top, width } = range.getBoundingClientRect() this.tipLeft = left + (width - 80) / 2 this.tipTop = top - 40 this.showTip = true}
划线
给tooltip绑定一下点击事件,点击后需要获取到选区内的所有文本节点,先看一下Range对象的结构:
简单介绍一下:
collapsed属性表示开始和结束的位置是否相同;
commonAncestorContainer属性返回包含startContainer和endContainer的公共父节点;
endContainer属性返回包含range终点的节点,通常是文本节点;
endOffset返回range终点在endContainer内的位置的数字;
startContainer属性返回包含range起点的节点,通常是文本节点;
startContainer返回range起点在startContainer内的位置的数字;
所以目标是要遍历startContainer和endContainer两个节点之间的所有节点来收集文本节点,受限于笔者匮乏的算法和数据结构知识,只能选择一个投机取巧的方法,遍历commonAncestorContainer节点。
然后使用range对象的isPointInRange()方法来检测当前遍历的节点是否在选区范围内,这个方法需要注意的两个点地方,一个是isPointInRange()方法目前不支持IE,二是首尾节点需要单独处理,因为首尾节点可能部分在选区内,这样这个方法是返回false的。
mark () this.textNodes = [] let { commonAncestorContainer, startContainer, endContainer } = this.range this.walk(commonAncestorContainer, (node) => { if ( node === startContainer || node === endContainer || this.range.isPointInRange(node, 0) ) {// 起始和结束节点,或者在范围内的节点,如果是文本节点则收集起来 if (node.nodeType === 3) { this.textNodes.push(node) } } }) this.handleTextNodes() this.showTip = false this.tipText = ''}
walk是一个深度优先遍历的函数:
walk (node, callback = () => {}) { callback(node) if (node && node.childNodes) { for (let i = 0; i < node.childNodes.length; i++) { this.walk(node.childNodes[i], callback) } }}
获取到选区范围内的所有文本节点后就可以切割字符进行元素替换:
handleTextNodes () { // 生成本次的唯一id let id = ++this.idx // 遍历文本节点 this.textNodes.forEach((node) => { // 范围的首尾元素需要判断一下偏移量,用来截取字符 let startOffset = 0 let endOffset = node.nodeValue.length if ( node === this.range.startContainer && this.range.startOffset !== 0 ) { startOffset = this.range.startOffset } if (node === this.range.endContainer && this.range.endOffset !== 0) { endOffset = this.range.endOffset } // 替换该文本节点 this.replaceTextNode(node, id, startOffset, endOffset) }) // 序列化进行存储,获取刚刚生成的所有该id的划线元素 this.serialize(this.$refs.article.querySelectorAll('.mark_id_' + id))}
如果是首节点,且startOffset不为0,那么startOffset之前的字符不需要添加划线包裹元素,如果是尾节点,且endOffset不为0,那么endOffset之后的字符不需要划线,中间的其他所有文本都需要进行切割及划线:
replaceTextNode (node, id, startOffset, endOffset) { // 创建一个文档片段用来替换文本节点 let fragment = document.createDocumentFragment() let startNode = null let endNode = null // 截取前一段不需要划线的文本 if (startOffset !== 0) { startNode = document.createTextNode( node.nodeValue.slice(0, startOffset) ) } // 截取后一段不需要划线的文本 if (endOffset !== 0) { endNode = document.createTextNode(node.nodeValue.slice(endOffset)) } startNode && fragment.appendChild(startNode) // 切割中间的所有文本 node.nodeValue .slice(startOffset, endOffset) .split('') .forEach((text) => { // 创建一个span标签用来作为划线包裹元素 let textNode = document.createElement('span') textNode.className = 'markLine mark_id_' + id textNode.setAttribute('data-id', id) textNode.textContent = text fragment.appendChild(textNode) }) endNode && fragment.appendChild(endNode) // 替换文本节点 node.parentNode.replaceChild(fragment, node)}
效果如下:
此时html结构:
序列化存储
一次性的划线是没啥用的,那还不如在文章上面盖一个canvas元素,给用户一个自由画布,所以还需要进行保存,下次打开还能重新显示之前画的线。
存储的关键是要能让下次还能定位回去,参考其他文章介绍的方法,本文选择的是存储划线元素外层的第一个非划线元素的标签名,以及在指定节点范围内的同类型元素里的索引,以及该字符在该非划线元素里的总的字符偏移量。
描述起来可能有点绕,看代码:
serialize (markNodes) { // 选择article元素作为根元素,这样的好处是页面的其他结构如果改变了不影响划线元素的定位 let root = this.$refs.article // 遍历刚刚生成的本次划线的所有span节点 markNodes.forEach((markNode) => { // 计算该字符离外层第一个非划线元素的总的文本偏移量 let offset = this.getTextOffset(markNode) // 找到外层第一个非划线元素 let { tagName, index } = this.getWrapNode(markNode, root) // 保存相关数据 this.serializeData.push({ tagName, index, offset, id: markNode.getAttribute('data-id') }) })}
计算字符离外层第一个非划线元素的总的文本偏移量的思路是先算获取同级下之前的兄弟元素的总字符数,再依次向上遍历父元素及其之前的兄弟节点的总字符数,直到外层元素:
getTextOffset (node) { let offset = 0 let parNode = node // 遍历直到外层第一个非划线元素 while (parNode && parNode.classList.contains('markLine')) { // 获取前面的兄弟元素的总字符数 offset += this.getPrevSiblingOffset(parNode) parNode = parNode.parentNode } return offset}
获取前面的兄弟元素的总字符数:
getPrevSiblingOffset (node) { let offset = 0 let prevNode = node.previousSibling while (prevNode) { offset += prevNode.nodeType === 3 ? prevNode.nodeValue.length : prevNode.textContent.length prevNode = prevNode.previousSibling } return offset}
获取外层第一个非划线元素在上面获取字符数的方法里其实已经有了:
getWrapNode (node, root) { // 找到外层第一个非划线元素 let wrapNode = node.parentNode while (wrapNode.classList.contains('markLine')) { wrapNode = wrapNode.parentNode } let wrapNodeTagName = wrapNode.tagName // 计算索引 let wrapNodeIndex = -1 // 使用标签选择器获取所有该标签元素 let els = root.getElementsByTagName(wrapNodeTagName) els = [...els].filter((item) => {// 过滤掉划线元素 return !item.classList.contains('markLine'); }).forEach((item, index) => {// 计算当前元素在其中的索引 if (wrapNode === item) { wrapNodeIndex = index } }) return { tagName: wrapNodeTagName, index: wrapNodeIndex }}
最后存储的数据示例如下:
反序列化显示
显示就是根据上面存储的数据把线画上,遍历上面的数据,先根据tagName和index获取到指定元素,然后遍历该元素下的所有文本节点,根据offset找到需要划线的字符:
deserialization () { let root = this.$refs.article // 遍历序列化的数据 markData.forEach((item) => { // 获取到指定元素 let els = root.getElementsByTagName(item.tagName) els = [...els].filter((item) => {// 过滤掉划线元素 return !item.classList.contains('markLine'); }) let wrapNode = els[item.index] let len = 0 let end = false // 遍历该元素所有节点 this.walk(wrapNode, (node) => { if (end) { return } // 如果是文本节点 if (node.nodeType === 3) { // 如果当前文本节点的字符数+之前的总数大于offset,说明要找的字符就在该文本内 if (len + node.nodeValue.length > item.offset) { // 计算在该文本里的偏移量 let startOffset = item.offset - len // 因为我们是切割到单个字符,所以总长度也就是1 let endOffset = startOffset + 1 this.replaceTextNode(node, item.id, startOffset, endOffset) end = true } // 累加字符数 len += node.nodeValue.length } }) })}
结果如下:
删除划线
删除划线很简单,我们监听一下点击事件,如果目标元素是划线元素,那么获取一下所有该id的划线元素,创建一个range,显示一下tooltip,然后点击后把该划线元素删除即可。
// 显示取消划线的tooltipshowCancelTip (e) { let tar = e.target if (tar.classList.contains('markLine')) { e.stopPropagation() e.preventDefault() // 获取划线id this.clickId = tar.getAttribute('data-id') // 获取该id的所有划线元素 let markNodes = document.querySelectorAll('.mark_id_' + this.clickId) // 选择第一个和最后一个文本节点来作为range边界 let startContainer = markNodes[0].firstChild let endContainer = markNodes[markNodes.length - 1].lastChild this.range = document.createRange() this.range.setStart(startContainer, 0) this.range.setEnd( endContainer, endContainer.nodeValue.length ) this.tipText = '取消划线' this.setTip(this.range) }}
点击了取消按钮后遍历该id的所有划线节点,进行元素替换:
cancelMark () { this.showTip = false this.tipText = '' let markNodes = document.querySelectorAll('.mark_id_' + this.clickId) // 遍历所有划线街道 for (let i = 0; i < markNodes.length; i++) { let item = markNodes[i] // 如果还有子节点,也就是其他id的划线元素 if (item.children[0]) { let node = item.children[0].cloneNode(true) // 子节点替换当前节点 item.parentNode.replaceChild(node, item) } else {// 否则只有文本的话直接创建一个文本节点来替换 let textNode = document.createTextNode(item.textContent) item.parentNode.replaceChild(textNode, item) } } // 从序列化数据里删除该id的数据 this.serializeData = this.serializeData.filter((item) => { return item.id !== this.clickId })}
缺点
到这里这个极简划线就结束了,现在来看一下这个极简的方法有什么缺点.
首先毋庸置疑的就是如果划线字符很多,重复划线很多次,那么会生成非常多的span标签及嵌套层次,节点数量是影响页面性能的一个大问题。
第二个问题是需要存储的数据也会很大,增加存储成本和网络传输时间:
这可以通过把字段名字压缩一下,改成一个字母,另外可以把连续的字符合并一下来稍微优化一下,但是然并卵。
第三个问题是如其名,文本划线,真的是只能给文本进行划线,其他的图片上面的就不行了:
第四个问题是无法应对如果划线后文章被修改了,html结构变化了的问题。
这几个问题个个扎心,导致它只能是个demo。
稍微优化一下
很容易想到的一个优化方法是不要把字符单个切割,整块包裹不就好了吗,道理是这个道理:
replaceTextNode (node, id, startOffset, endOffset) { // ... startNode && fragment.appendChild(startNode) // 改成直接包裹整块文本 let textNode = document.createElement('span') textNode.className = 'markLine mark_id_' + id textNode.setAttribute('data-id', id) textNode.textContent = node.nodeValue.slice(startOffset, endOffset) fragment.appendChild(textNode) endNode && fragment.appendChild(endNode) // ...}
这样序列化时需要增加一个长度的字段:
let textLength = markNode.textContent.lengthif (textLength > 0) {// 过滤掉长度为0的空字符,否则会有不可预知的问题 this.serializeData.push({ tagName, index, offset, length: textLength,// ++ id: markNode.getAttribute('data-id') })}
这样序列化后的数据量会大大减少:
接下来反序列化也需要修改,字符长度不定的话就可能跨文本节点了:
deserialization () { let root = this.$refs.article markData.forEach((item) => { let wrapNode = root.getElementsByTagName(item.tagName)[item.index] let len = 0 let end = false let first = true let _length = item.length this.walk(wrapNode, (node) => { if (end) { return } if (node.nodeType === 3) { let nodeTextLength = node.nodeValue.length if (len + nodeTextLength > _offset) { // startOffset之前的文本不需要划线 let startOffset = (first ? item.offset - len : 0) first = false // 如果该文本节点剩余的字符数量小于划线文本的字符长度的话代表该文本节点还只是划线文本的一部分,还需要到下一个文本节点里去处理 let endOffset = startOffset + (nodeTextLength - startOffset >= _length ? _length : nodeTextLength - startOffset) this.replaceTextNode(node, item.id, startOffset, endOffset) // 长度需要减去之前节点已经处理掉的长度 _length = _length - (nodeTextLength - startOffset) // 如果剩余要处理的划线文本的字符数量为0代表已经处理完了,可以结束了 if (_length <= 0) { end = true } } len += nodeTextLength } }) })}
最后取消划线也需要修改,因为子节点可能就不是只有单纯的一个划线节点或文本节点了,需要遍历全部子节点:
cancelMark () { this.showTip = false this.tipText = '' let markNodes = document.querySelectorAll('.mark_id_' + this.clickId) for (let i = 0; i < markNodes.length; i++) { let item = markNodes[i] let fregment = document.createDocumentFragment() for (let j = 0; j < item.childNodes.length; j++) { fregment.appendChild(item.childNodes[j].cloneNode(true)) } item.parentNode.replaceChild(fregment, item) } this.serializeData = this.serializeData.filter((item) => { return item.id !== this.clickId })}
现在再来看一下效果:
html结构:
可以看到无论是序列化的数据还是DOM结构都已经简洁了很多。
但是,如果文档结构很复杂或者多次重复划线最终产生的节点和数据还是比较大的。
总结
本文介绍了一个实现web文本划线功能的极简实现,最初的想法是通过切割成单个字符来进行包裹,这样的优点是十分简单,缺点也很明显,产生的序列号数据很大、修改的DOM结构很复杂,在文章及demo的写作过程中经过实践,发现直接包裹整块文字也并不会带来太多问题,但是却能减少和优化很多要存储的数据和DOM结构,所以很多时候,想当然是不对的,最后想说,数据结构和算法真的很重要????。
示例代码在:https://github.com/wanglin2/textUnderline。
学习更多技能
请点击下方公众号
-
canvas动态划线(canvas跟随鼠标变幻线条...)
2018-01-02 15:59:18canvas动态划线(canvas跟随鼠标变幻线条,知乎登录页面动态线条背景动画代码) 每次被下载,所需积分就被平台自动叠加,感觉有点傻,无奈重新编辑上传,感觉可选的这个1-5积分就有点少,算了无所谓了你们能下载就好 -
用css布局价格划线_价钱中划线_价格中间贯穿删除线效果样式布局
2021-06-18 10:20:17使用css样式布局价格划线,价钱中划线效果,优惠前原价格中间使用删除线一样效果样式各大电商平台,个人商城也好,各大产品买卖也好,都会用原价格和优惠后价格形成对比,让用户产生购买下单欲望。通常会布局显示出...使用css样式布局价格划线,价钱中划线效果,优惠前原价格中间使用删除线一样效果样式
各大电商平台,个人商城也好,各大产品买卖也好,都会用原价格和优惠后价格形成对比,让用户产生购买下单欲望。通常会布局显示出原价格与优惠后价格,而原价格使用中划线(价格中间用一道横线删除线)。
优惠价格显示正常,原价格使用中划线样式
中划线在HTML标签中可以使用
删除线实现。如果要CSS样式布局,就采用text-decoration样式实现。需要对价格数字划线的时候,对其设置text-decoration:line-through即可。
这里CSS5采用HTML删除划线标签与CSS划线(中间划线)实现对促销原来价格进行中划线布局。
1、实例完成html css代码
价格划线CSS布局 CSS5.huaxian{text-decoration:line-through}
优惠价格:100元,原价:
200元优惠价格:80元,原价:220元
2、划线布局截图
html标签价格划线与CSS样式价格划线实例截图
在实际HTML布局中,无论选择CSS样式布局中划线,还是HTML标签布局中划线也好,选择不重要,重要根据需求合理选择适合布局方式,html删除线贯穿线标签和CSS贯穿线中划线样式均可使用。
作者:css5原创
-
UILabel 划线
2016-06-17 13:51:17在很多APP售卖的界面中经常看到有打折之前的价钱被添加了一条线条,本人在很多平台中找了方法,自己亲自码了几次,研究总结,分享这篇包括了所有方法,浅显易懂,和大家一起进步。(觉得有用就点击“喜欢”啦。) ...在很多APP售卖的界面中经常看到有打折之前的价钱被添加了一条线条,本人在很多平台中找了方法,自己亲自码了几次,研究总结,分享这篇包括了所有方法,浅显易懂,和大家一起进步。(觉得有用就点击“喜欢”啦。)
UILabel添加线条.png方法一:用RTLabel开源的富文本
//首先创建一个Label label = [[UILabel alloc]initWithFrame:CGRectMake(130, 300, 180, 80)]; label.font = [UIFont systemFontOfSize:35]; label.backgroundColor = [UIColor yellowColor]; [self.view addSubview:label]; //设置显示的价格 NSString *oldPrice = @"¥ 12345"; //获取字符串的长度 NSUInteger length = [oldPrice length]; //从这里开始就是设置富文本的属性 NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithString:oldPrice]; //下面开始是设置线条的风格: //第一个参数addAttribute:是设置要中线(删除线)还是下划线。 //NSStrikethroughStyleAttributeName:这种是从文本中间穿过,也就是删除线。 //NSUnderlineStyleAttributeName:这种是下划线。 //第二个参数value:是设置线条的风格:虚线,实现,点线...... //第二参数需要同时设置Pattern和style才能让线条显示。 //第三个参数range:是设置线条的长度,切记,不能超过字符串的长度,否则会报错。 [attri addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, length)]; //下列是设置线条的颜色 //第一个参数就是选择设置中线的颜色还是下划线的颜色,如果上面选择的是中线,这里就要选择中线,否则颜色设置不上去。 //第二个参数很简单,就是颜色而已。 //第三个参数:同上。 [attri addAttribute:NSStrikethroughColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, length)]; [label setAttributedText:attri];
方法一总结:方法一是最常用的,最方便的一种。
方法二:重写drawRect:(CGRect)rect方法
说明:这种方法较复杂,逼格较高。再说明一下重绘,重绘操作是在在drawRect方法中完成,但是苹果不允许直接调用drawRect方法。苹果要求我们调用UIView类中的setNeedsDisplay方法,则程序会自动调用drawRect方法进行重绘。
在UIView中,重写drawRect: (CGRect) aRect方法,可以自己定义想要画的图案.且此方法一般情况下只会画一次.也就是说这个drawRect方法一般情况下只会被调用一次.
开始讲解:首先我们要创建一个继承UIView的子类:
然后在这个子类里面重写drawRect:(CGRect)rect方法,上代码:#import "ViewSon.h" @implementation ViewSon - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, [UIColor grayColor].CGColor); CGContextFillRect(context, CGRectMake(0, CGRectGetHeight(self.frame) - 0.5, CGRectGetWidth(self.frame), 0.5)); } @end
再者,在一个界面中添加UILabel,导入那个子类的头文件添加这个子类。
label = [[UILabel alloc]initWithFrame:CGRectMake(130, 300, 180, 80)]; label.text = @" ¥258"; label.font = [UIFont systemFontOfSize:35]; [self.view addSubview:label]; ViewSon * viewson = [[ViewSon alloc]initWithFrame:CGRectMake(35,100, 65, 4)]; viewson.backgroundColor = [UIColor redColor]; [viewson setNeedsDisplay];//这句就是调用方法,程序会自动调用重写了得那个方法。 [label addSubview:viewson];
方法二的使用性很广泛,可不是单单的添加删除线和下划线,利用这种方法可以绘制出各种各样的图案。利用它添加删除线的时候,需要设置下划线添加在哪里,线条的长度也是随意的设置,并不一定需要和显示的字符串一样长。
-
行业分类-设备装置-一种调整三维测量划线机中磁栅传感器磁头位置的结构.zip
2021-08-23 18:27:12行业分类-设备装置-一种调度日班计划协同编制平台系统及编制方法.zip -
基于计算机平台的多喷头喷绘机控制系统的设计与实现
2020-10-23 09:11:16为了满足市场对新一代高速高精度喷绘机的需求,提出了一套自行设计的基于计算机平台的大幅面高速度多喷头彩色喷绘机控制系统的实现方案,介绍了控制系统的设计思想以及各控制子模块之间的层次结构和逻辑关系,深入... -
生鲜配送平台源码java-zhuguoguo:zhuguoguo
2021-06-07 01:47:29生鲜配送平台源码java 助果果开发手册 一、Java 编程规约 (一)命名风格 【强制】代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。 【强制】代码中的命名严禁使用拼音与英文混合的方式,更... -
【Web技术】1048- 手把手教你实现web文本划线的功能
2021-08-14 00:19:00来源 |https://www.cnblogs.com/wanglinmantan/p/15106871.html开篇文本划线是目前逐渐流行的一个功能,不管你是小说阅读网站,还是卖教程的... -
MySQL数据库名字能不能用中划线 ‘-’ ?
2021-01-24 22:55:14MySQL数据库名字能不能用中划线 ‘-’ ? -
【考研】考研5大分数线——国家线、院校线、自划线、单科线、录取线的区别
2022-03-06 11:09:25一般国家线出来后会迅速登上各平台(微博、知乎、抖音、B站等)热搜,你只要点进去就能看到。 以中国教育在线为例,以下网站可以查询到历年的国家线和自划线。 https://www.eol.cn/e_ky/zt/common/fsx/ 2、院校线 ... -
我手撸了一个划线翻译工具!
2020-12-08 08:30:00来源 :https://yuanlehome.github.io/20200612/这里将要介绍的是一种在 Linux 平台实现的划词翻译工具,当然在考虑自己实现一个如此功能的工具前,本... -
(gaugwell)三峡智慧工程云平台.xmind
2020-10-09 17:41:02强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束。 反例:_name / __name / $name / name_ / name$ / name__ 2.[强制]代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用... -
web文本划线的极简实现
2021-08-01 15:40:35InfoQ写作平台: 等等,这个功能看似简单,实际上难点还是很多的,比如如何高性能的对各种复杂的文本结构划线、如何尽可能少的存储数据、如何精准的回显划线、如何处理重复划线、如何应对文本后续编辑的情况 -
多所自划线985大学,复试分数线公布时间出炉!
2020-03-29 14:11:25前段时间,研招网公布了考研国家线的公布时间:官方通知:考研国家线预计4月中旬公布通知中描述,考研国家线预计将在4月中旬公布,复试工作另行通知。于是,当时小编推测,34所自主划线的大学,将... -
划线算法
2014-10-30 17:44:39划线算法: 画圆算法: -
辟谣!考研计算机专业不会单独划线!
2019-03-18 09:56:49大概一年之前,教育部出了这么一个规定: 根据《国务院学位委员会、教育部关于对工程专业... 20考研的QQ群,有各个学校的考研资料,欢迎加入 群号是 935371763 您还可以在以下平台找到我们 如果觉得有用,请点一下好看~ -
又一所985自划线大学,宣布分数线公布时间!
2020-04-03 13:38:49前几天,有两所985自主划线的大学,通知了今年复试分数线的公布时间:多所自划线985大学,复试分数线公布时间出炉!这两所大学分别是 中国科学技术大学和中国人民大学,都是自主划线的大学,往... -
【22考研】国家线/34所自划线 集合!【计算机和软件专业】
2022-03-22 00:48:04为了同学们更方便快捷的了解34所院校的自划线和国家分数线,小编在这里开了一个专区,提供给同学们计算机/软件工程等相关专业的考研分数线。什么是A类?什么是B类?可以看这篇文章... -
Qt编写地图综合应用57-跨平台(win、linux、mac、uos、kylin等)
2022-02-13 10:02:02跨平台着实花了不少的精力,为了从Qt4.7兼容到Qt6.2及后续版本,头发掉了不少,仅有的几根毛所剩无几,哎,可能这就是程序员的命,本人写Qt程序这么多年,比较喜欢支持多个Qt版本,尤其是钟情于支持任意Qt版本+任意... -
通达信缠论笔段中枢+三类买卖点选股,通达信缠论指标选出盘整股票源码.zip
2021-10-15 01:02:49通达信缠论笔段中枢+三类买卖点选股,通达信缠论指标选出盘整股票源码 -
近五年计算机考研国家线、自划线汇总!
2022-02-22 01:13:04部分转载于软科计算机类专业的学硕属于工学,专硕属于工学大类中的工程中的电子信息类。国家线总分线(学术学位)国家线总分线(专业学位)除国家线以外,还有34所高校采用自划线,以一流大学为主。... -
高通/MTK平台TP相关问题分析
2021-08-12 22:28:49在SM8350/SM7150/MT68XX/天玑1200/1100等平台遇到的一些常见TP问题 -
qt平台下免费开源字典goldenDict
2015-03-22 17:32:03qt平台下免费开源字典goldenDict -
焊接一般技术要求
2020-12-20 12:36:552019-07-20由于焊接没有进步,或者是产品的巩固度不高,也或者是在运用中难以满意用户的漂亮要求,所以在用户运用这种...有些厂家所运用的...[详细]2020-07-16杭州焊接平台生产厂家,宁波焊接铸铁平台型号尺寸-焊接平...