wordpress 多站点迁移,wordpress文章摘要显示,最新网络营销方式有哪些,大连建设学校官网代码编辑组件 文章说明核心代码运行演示源码下载 文章说明 拖了很久#xff0c;总算是自己写了一个简单的代码编辑组件#xff0c;虽然还有不少的bug#xff0c;真的很难写#xff0c;在写的过程中感觉自己的前端技术根本不够用#xff0c;好像总是方案不够好#xff1b;… 代码编辑组件 文章说明核心代码运行演示源码下载 文章说明 拖了很久总算是自己写了一个简单的代码编辑组件虽然还有不少的bug真的很难写在写的过程中感觉自己的前端技术根本不够用好像总是方案不够好目前写出了这个效果等待后续学习别的现有产品再慢慢补充 采用div的设置可编辑属性 contenteditable“true”然后结合 highlight的代码高亮效果还不错最开始相加的代码输入提示以为不难实现但是真的写起来总是没有办法很好的实现那个输入面板的位置控制索性就暂时不加输入提示然后搜索功能也是有不小的难点目前仍然存在着一些bug待修复但是可以先作为小demo试用一下 目前算是完成第一阶段虽然组件的功能不是很完善但是基本的代码高亮和搜索功能也有了算是差强人意啦 核心代码 输入组件 script setup
import {onMounted, reactive} from vue;
import Search from /components/Search.vue;
import hljs from highlight.js;
import highlight.js/styles/idea.css;
import {useSearchStore} from /stores/search;
import {appendDom} from /utils;const data reactive({lineNumber: [1],language: html
});const search useSearchStore();function refresh() {const height inputElem.scrollHeight;const number Math.ceil(height / 21);if (number ! data.lineNumber.length) {data.lineNumber [];for (let i 0; i number; i) {data.lineNumber.push(i 1);}}if (search.showSearch) {search.search(false);}
}let leftLineNumberContainer;
let rightInputArea;
let inputElem;function syncScroll(event) {if (event.target leftLineNumberContainer) {rightInputArea.scrollTo({top: event.target.scrollTop,});}if (event.target rightInputArea) {leftLineNumberContainer.scrollTo({top: event.target.scrollTop,});}
}function inputFocus() {inputElem.focus();const range document.createRange();range.selectNodeContents(inputElem);range.collapse(false);const sel window.getSelection();sel.removeAllRanges();sel.addRange(range);if (!leftLineNumberContainer) {leftLineNumberContainer document.getElementsByClassName(left-line-number-container)[0];}if (!rightInputArea) {rightInputArea document.getElementsByClassName(right-input-area)[0];}leftLineNumberContainer.scrollTo({top: rightInputArea.scrollHeight,});rightInputArea.scrollTo({top: rightInputArea.scrollHeight,});
}onMounted(() {inputElem document.getElementsByClassName(input-elem)[0];rightInputArea document.getElementsByClassName(right-input-area)[0];search.rightInputArea rightInputArea;search.inputElem inputElem;search.language data.language;search.refresh refresh;inputFocus();
});function getPasteData(event) {const clipData event.clipboardData || window.clipboardDataconst value clipData.getData(text/plain);let highlightedCode hljs.highlight(value, {language: data.language}).value;const container document.createElement(span);container.innerHTML highlightedCode;function wrapTextNodesInSpan(element) {for (let i 0; i element.childNodes.length; i) {const child element.childNodes[i];if (child.nodeType Node.TEXT_NODE) {const span document.createElement(span);span.textContent child.nodeValue;element.insertBefore(span, child);element.removeChild(child);} else if (child.nodeType Node.ELEMENT_NODE) {wrapTextNodesInSpan(child);}}}wrapTextNodesInSpan(container);appendDom(rightInputArea, container);refresh();
}function keydown(event) {search.keydown(event);if (event.key Tab) {event.preventDefault();appendContent( );}if (event.ctrlKey) {return;}if (event.key Enter || event.key Backspace || event.key Delete) {setTimeout(() {refresh();}, 10);return;}if (isAlphaNumeric(event.key)) {event.preventDefault();appendContent(event.key);refresh();}
}function isAlphaNumeric(key) {return /^[a-zA-Z0-9]$/.test(key);
}function appendContent(content) {const span document.createElement(span);span.textContent content;appendDom(rightInputArea, span, false);
}
/scripttemplatediv classeditor-containerSearch/div styledisplay: flex :style{ height: search.showSearch ? calc(100% - 30px) : 100% }div classleft-line-number-container scrollsyncScroll($event)template v-for(item, index) in data.lineNumber :keyindexp{{ item }}/p/template/divdiv classright-input-area scrollsyncScroll($event) click.selfinputFocusdiv classinput-elem :contenteditable!search.showSearch keydownkeydown($event)paste.preventgetPasteData($event)/div/div/div/div
/templatestyle langscss
* {padding: 0;margin: 0;box-sizing: border-box;
}.hljs-tag {background-color: transparent !important;
}.hljs-attribute, .hljs-number, .hljs-regexp, .hljs-link {font-weight: normal;color: #3931c5;
}.hljs-section, .hljs-name, .hljs-literal, .hljs-keyword, .hljs-selector-tag, .hljs-type, .hljs-selector-id, .hljs-selector-class {font-weight: normal;color: #3931c5;
}.editor-container {width: 100vw;height: 100vh;background-color: #ffffff;padding-left: 200px;.left-line-number-container {min-width: 60px;background-color: #f2f2f2;border: 1px solid #d4d4d4;padding: 4px 4px 230px;overflow: auto;::-webkit-scrollbar {height: 0;width: 0;}p {width: fit-content;color: #adadad;font-size: 14px;line-height: 1.5;font-family: JetBrains Mono, sans-serif;word-spacing: 0.2rem;text-align: right;}}.right-input-area {flex: 1;border: 1px solid #d4d4d4;border-left: none;padding: 4px 4px 230px;overflow: auto;position: relative;cursor: default;#default-cursor {width: 0;height: 0;display: inline-block;}::-webkit-scrollbar {height: 10px;width: 10px;}::-webkit-scrollbar-thumb {background-color: #e2e2e2;border-radius: 0;}::-webkit-scrollbar-track {background-color: transparent;}.input-elem {border: none;outline: none;height: fit-content;min-width: 100%;font-size: 14px;color: #080808;min-height: 21px;line-height: 21px;font-family: JetBrains Mono, sans-serif;word-spacing: 0.2rem;white-space: pre;word-break: break-all;::selection {background-color: #a6d2ff;}.highlight-item {background-color: #ffe959;}.current-highlight-item {background-color: #a6d2ff;}pre {font-family: JetBrains Mono, sans-serif;::selection {background-color: #a6d2ff;}}}}
}
/style搜索组件 script setup
import {useSearchStore} from /stores/search;const search useSearchStore();function changeCase() {search.caseSelected !search.caseSelected;search.search();
}function changeWord() {search.wordSelected !search.wordSelected;search.search();
}function close() {search.currentIndex 1;search.showSearch false;search.recover();
}function last() {search.beginSearch true;if (search.currentIndex 1) {search.currentIndex search.searchResult.length;} else {search.currentIndex--;}search.search();
}function next() {search.beginSearch true;if (search.currentIndex search.searchResult.length) {search.currentIndex 1;} else {search.currentIndex;}search.search();
}
/scripttemplatediv v-showsearch.showSearch classsearch-container click.stopinput v-modelsearch.searchText inputsearch.search idinput/div :classsearch.caseSelected ? active-case : classcase clickchangeCaseCc/divdiv :classsearch.wordSelected ? active-word : classword clickchangeWordW/divdiv classresulttemplate v-if!search.beginSearch || search.searchResult.length 0{{ search.searchResult.length }}results/templatetemplate v-ifsearch.beginSearch search.searchResult.length 0{{search.currentIndex}}/{{ search.searchResult.length }}/template/divdiv classlast clicklast↑/divdiv classnext clicknext↓/divdiv classclose clickclose×/div/div
/templatestyle langscss scoped
.search-container {width: 100%;height: 30px;border: 1px solid #d1d1d1;border-bottom: none;display: flex;align-items: center;user-select: none;input {border: none;outline: none;width: 350px;height: 28px;margin: 10px;}.case, .word {background-color: #ffffff;color: #bfc5c8;width: 25px;height: 25px;padding: 3px;margin-right: 4px;display: flex;justify-content: center;align-items: center;font-size: 14px;font-weight: 600;font-family: JetBrains Mono, sans-serif;border-radius: 5px;cursor: default;:hover {background-color: #dfdfdf;color: #899399;}}.active-case, .active-word {background-color: #dae4ed;color: #40b6e0;:hover {background-color: #dfdfdf;color: #44b7e0;}}.result {font-size: 12px;font-family: JetBrains Mono, sans-serif;margin: 0 20px;width: 70px;height: 28px;display: flex;justify-content: center;align-items: center;}.last, .next {width: 22px;height: 22px;display: flex;justify-content: center;align-items: center;font-size: 18px;color: #6e6e6e;:hover {background-color: #dfdfdf;border-radius: 5px;cursor: default;}}.close {margin-left: auto;margin-right: 5px;width: 22px;height: 22px;display: flex;justify-content: center;align-items: center;font-size: 18px;color: #bec4c6;:hover {background-color: #dfdfdf;border-radius: 5px;cursor: default;}}
}
/style运行演示 Java代码编辑 HTML代码编辑 源码下载 代码编辑组件