我对编码还很陌生,并且一直在使用textarea创建一个文本编辑器组件:https://jsfiddle.net/chrismg12/jLk70ar3/5/
我打算创建一个函数,用于选择找到的单词的所有实例。但是,我不知道如何在textarea中执行此操作。注意:这不是关于多个插入符号,而是多个选择,但是在实现多个插入符号的建议中将不胜感激。
HTML
var lNo = "";
function injectStyles(rule) {
var div = $("<div />", {
html: '­<style>' + rule + '</style>'
}).appendTo("body");
}
$.fn.selectRange = function(start, end) {
return this.each(function() {
if (typeof end == "undefined") {
end = start;
}
if (start == -1) {
start = this.value.length;
}
if (end == -1) {
end = this.value.length;
}
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end + 1);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
});
};
$.fn.selectRangeExcludingLast = function(start, end) {
return this.each(function() {
if (typeof end == "undefined") {
end = start;
}
if (start == -1) {
start = this.value.length;
}
if (end == -1) {
end = this.value.length;
}
if (this.setSelectionRange) {
this.focus();
this.setSelectionRange(start, end + 1);
} else if (this.createTextRange) {
var range = this.createTextRange();
range.collapse(true);
range.moveEnd('character', end);
range.moveStart('character', start);
range.select();
}
});
};
function getPos(str, substr, index) {
var io = str.split(substr, index).join(substr).length;
if (io >= str.length) {
return -1;
} else {
return io;
}
}
function gutterChildControl(gutter, textarea, settings) {
if (gutter.childNodes.length != $(textarea).val().split("\n").length) {
while (gutter.childNodes.length < $(textarea).val().split("\n").length) {
var gutterChild = document.createElement("div");
gutterChild.className = "gutterChild"
gutterChild.style.height = $(textarea).css('line-height');
var gutterChildLineHeight = $(textarea).css('line-height');
$(gutterChild).css('line-height', gutterChildLineHeight)
gutterChild.style.fontSize = $(textarea).css('font-size');
gutterChild.style.width = "100%";
gutterChild.style.color = settings.gFontCol;
gutterChild.style.paddingRight = `${settings.gPadding}px`;
gutterChild.style.paddingLeft = `${settings.gPadding}px`;
gutterChild.style.textAlign = settings.gFontAlign;
gutterChild.onmouseover = function() {
gutterChild.style.opacity = "0.75"
}
gutterChild.onmouseleave = function() {
gutterChild.style.opacity = "1"
}
gutterChild.onclick = function() {
if (parseInt(gutterChild.innerHTML) != 1) {
startPos = getPos($(textarea).val(), "\n", parseInt(gutterChild.innerHTML) - 1)
console.log(`startPos:${startPos}`);
endPos = getPos($(textarea).val(), "\n", parseInt(gutterChild.innerHTML))
if (endPos == -1) {
endPos = $(textarea).val().length - 1
}
console.log(`endPos:${endPos}`)
$(textarea).selectRange(startPos, endPos);
} else {
startPos = 0;
console.log(`startPos:${startPos}`)
endPos = getPos($(textarea).val(), "\n", 1)
if (endPos == -1) {
endPos = $(textarea).val().length - 1
if (endPos == -1) {
endPos = 0;
}
}
console.log(`endPos:${endPos}`)
$(textarea).selectRange(startPos, endPos);
}
}
gutter.appendChild(gutterChild);
gutterChild.innerHTML = `${gutter.childNodes.length}`
}
while (gutter.childNodes.length > $(textarea).val().split("\n").length) {
gutter.removeChild(gutter.lastChild)
}
// while(gutter.childNodes.length > $(textarea).val().split("\n").length){
// gutter.childNodes.pop;
// }
}
}
function Ventify(element, options) {
const settings = {
taCol: "#1d252c",
gCol: "#1d252c",
fSize: "22px",
gFontCol: "rgba(58,74,88,1)",
pad: 1,
gFontAlign: "center",
gPadding: 20,
...options
}
element.style.display = "flex";
element.style.flexDirection = "row";
var gutter = document.createElement("div");
var textarea = document.createElement("textarea");
gutter.className = "gutter";
gutter.classList.add("scrll")
textarea.className = "ventiEditor";
textarea.classList.add("scrll")
gutter.style.width = "100px";
gutter.style.height = "100%";
gutter.style.backgroundColor = settings.gCol;
gutter.style.overflowY = "scroll"
gutter.style.scrollbarWidth = "none";
injectStyles(".gutter::-webkit-scrollbar{width:0px;}")
injectStyles(".ventiEditor{outline:0px !important;-webkit-appearance:none;}")
textarea.style.width = "calc(100% - 100px)";
textarea.style.fontSize = settings.fSize;
textarea.style.color = settings.gFontCol;
textarea.style.overflowY = "scroll";
textarea.style.whiteSpace = "pre";
textarea.style.resize = "none";
textarea.style.height = "100%";
textarea.style.margin = "0px 0px 0px 0px"
textarea.style.border = "0px solid rgb(255,255,255)"
textarea.style.padding = "0"
$(textarea).css('line-height', `calc(${2*settings.pad}px + ${settings.fSize})`)
textarea.style.backgroundColor = settings.taCol;
textarea.spellcheck = false;
$(textarea).css("-moz-tab-size", "4");
$(textarea).css("tab-size", "4")
$('.ventiEditor:focus').css('outline', '0px !important')
$('.ventiEditor:focus').css('-webkit-appearance', 'none')
textarea.oninput = function() {
var gutter = textarea.parentElement.childNodes[0];
gutterChildControl(gutter, textarea, settings)
};
textarea.onscroll = function() {
gutter.scrollTop = textarea.scrollTop
}
$(textarea).keydown(function(e1) {
if (e1.ctrlKey) {
if (e1.keyCode >= 48 && e1.keyCode <= 57) {
lNo += e1.key;
console.log(lNo);
}
}
})
// gutter.onscroll = function(){
// if(gutter.scrollTop != textarea.scrollTop){
// textarea.scrollTop = gutter.scrollTop;
// }
// }
element.appendChild(gutter);
element.appendChild(textarea);
gutterChildControl(gutter, textarea, settings);
}
function gutterFix(textarea) {}
$(document).delegate('.ventiEditor', 'keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start) +
"\t" +
$(this).val().substring(end));
// put caret at right position again
this.selectionStart =
this.selectionEnd = start + 1;
}
});
injectStyles(".gutterChild{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}")
Ventify(document.getElementsByClassName("container")[0], {
taCol: "#1d252c",
gCol: "#1d252c",
pad: 5,
gFontCol: '#bbb'
})
html,
body {
height: 100%;
margin: 0px 0px 0px 0px;
}
.container {
height: 100%;
}
<link rel="stylesheet" href="bootstrap-4.3.1-dist/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container"></div>
答案 0 :(得分:0)
您可以设置一个空数组并将所有匹配字符串的位置推入其中。 (例如,如果要在字符串“ this
”中查找“ this and this match; so does this
”,则数组将得到[0,9,29]。)您可能希望/需要使用{{3} }
利用此信息(并知道子字符串的长度),您可以执行以下操作:
-在文本区域上覆盖div(也许使用regex和z-index: 1
)
-将每个匹配的字符串括在span元素中(有关该contenteditable="true"的更多信息),并可能给所有这些spans一个类,
-使用querySelectorAll获取包含所有这些范围的NodeList,并且
-遍历列表以更改其样式(因此
用户可以看到“选择的内容”)及其内容(假设该点是
以便用户可以进行更改。)
您可以稍后删除环绕间距,用更新后的文本更新文本区域,并删除覆盖的div。
请注意,索引数组可能不会长期有效,并且根据您对初始列表的处理方式,您可能需要向后循环遍历以保护这些值,直到不再需要它们为止。
那还是我的脑力激荡。