百度编辑器的查找和替换无法随着页面滚动定位,找到searchreplace.js,重写里面的方法
效果展示:
20250421173735
思路:
找到查找和替换的输入框,发现id名分别为findtxt和findtxt1,分别绑定change事件,并定义两套变量,分别为currentIndex 、matches和replacecurrentIndex、replacematches用于存储当前滚动到的数组位置和查找到的文本的位置的数组列表
点击下一个上一个按钮的的时候注释原来的代码,改为调用我们自己写的方法scrollToMatch,参数传递当前要定位的数组索引和类型(查找或者替换),代码如下
/**
* Created with JetBrains PhpStorm.
* User: xuheng
* Date: 12-9-26
* Time: 下午12:29
* To change this template use File | Settings | File Templates.
*/
//清空上次查选的痕迹
editor.firstForSR = 0;
editor.currentRangeForSR = null;
//给tab注册切换事件
/**
* tab点击处理事件
* @param tabHeads
* @param tabBodys
* @param obj
*/
//相关搜索变量
//当前查找的变量
let currentIndex = -1;
let matches = [];
// 当前替换的变量
let replacecurrentIndex = -1
let replacematches = []
// let highlightSpan = document.createElement('span');
// highlightSpan.style.backgroundColor = '#ff0000';
// highlightSpan.style.color = '#ffffff';
// let execFlag = false;
function clickHandler( tabHeads,tabBodys,obj ) {
//head样式更改
for ( var k = 0, len = tabHeads.length; k < len; k++ ) {
tabHeads[k].className = "";
}
obj.className = "focus";
//body显隐
var tabSrc = obj.getAttribute( "tabSrc" );
for ( var j = 0, length = tabBodys.length; j < length; j++ ) {
var body = tabBodys[j],
id = body.getAttribute( "id" );
if ( id != tabSrc ) {
body.style.zIndex = 1;
} else {
body.style.zIndex = 200;
}
}
}
/**
* TAB切换
* @param tabParentId tab的父节点ID或者对象本身
*/
function switchTab( tabParentId ) {
var tabElements = $G( tabParentId ).children,
tabHeads = tabElements[0].children,
tabBodys = tabElements[1].children;
for ( var i = 0, length = tabHeads.length; i < length; i++ ) {
var head = tabHeads[i];
if ( head.className === "focus" )clickHandler(tabHeads,tabBodys, head );
head.onclick = function () {
clickHandler(tabHeads,tabBodys,this);
}
}
}
$G('searchtab').onmousedown = function(){
$G('search-msg').innerHTML = '';
$G('replace-msg').innerHTML = ''
}
//是否区分大小写
function getMatchCase(id) {
return $G(id).checked ? true : false;
}
// 给输入框绑定change时间,用于变量初始化
$G('findtxt').onchange =function(e){
console.log(e,'input输入框时间是否改变')
currentIndex = -1; //当前
matches = [];
searchText('findtxt')
}
// 给替换绑定change事件
$G('findtxt1').onchange =function(e){
console.log(e,'替换是否改变')
replacecurrentIndex = -1; //当前
replacematches = [];
searchText('findtxt1')
}
//查找
$G("nextFindBtn").onclick = function (txt, dir, mcase) {
var findtxt = $G("findtxt").value, obj;
if (!findtxt) {
return false;
}
if (matches.length === 0) return;
currentIndex = (currentIndex + 1) % matches.length;
scrollToMatch(currentIndex,'findtxt');
// 自定义实现查找过程
// this.searchText()
// obj = {
// searchStr:findtxt,
// dir:1,
// casesensitive:getMatchCase("matchCase")
// };
// if (!frCommond(obj)) {
// var bk = editor.selection.getRange().createBookmark();
// $G('search-msg').innerHTML = lang.getEnd;
// editor.selection.getRange().moveToBookmark(bk).select();
// }
};
$G("nextReplaceBtn").onclick = function (txt, dir, mcase) {
var findtxt = $G("findtxt1").value, obj;
if (!findtxt) {
return false;
}
// obj = {
// searchStr:findtxt,
// dir:1,
// casesensitive:getMatchCase("matchCase1")
// };
// frCommond(obj);
if (replacecurrentIndex.length === 0) return;
replacecurrentIndex = (replacecurrentIndex + 1) % replacematches.length;
scrollToMatch(replacecurrentIndex,'findtxt1');
};
$G("preFindBtn").onclick = function (txt, dir, mcase) {
var findtxt = $G("findtxt").value, obj;
if (!findtxt) {
return false;
}
// obj = {
// searchStr:findtxt,
// dir:-1,
// casesensitive:getMatchCase("matchCase")
// };
// if (!frCommond(obj)) {
// $G('search-msg').innerHTML = lang.getStart;
// }
if (matches.length === 0) return;
currentIndex = (currentIndex - 1 + matches.length) % matches.length;
scrollToMatch(currentIndex,'findtxt');
};
$G("preReplaceBtn").onclick = function (txt, dir, mcase) {
var findtxt = $G("findtxt1").value, obj;
if (!findtxt) {
return false;
}
// obj = {
// searchStr:findtxt,
// dir:-1,
// casesensitive:getMatchCase("matchCase1")
// };
// frCommond(obj);
if (replacecurrentIndex.length === 0) return;
replacecurrentIndex = (replacecurrentIndex - 1 + replacematches.length) % replacematches.length;
scrollToMatch(replacecurrentIndex,'findtxt1');
};
//替换
$G("repalceBtn").onclick = function () {
var findtxt = $G("findtxt1").value.replace(/^\s|\s$/g, ""), obj,
replacetxt = $G("replacetxt").value.replace(/^\s|\s$/g, "");
if (!findtxt) {
return false;
}
if (findtxt == replacetxt || (!getMatchCase("matchCase1") && findtxt.toLowerCase() == replacetxt.toLowerCase())) {
return false;
}
obj = {
searchStr:findtxt,
dir:1,
casesensitive:getMatchCase("matchCase1"),
replaceStr:replacetxt
};
frCommond(obj);
};
//全部替换
$G("repalceAllBtn").onclick = function () {
var findtxt = $G("findtxt1").value.replace(/^\s|\s$/g, ""), obj,
replacetxt = $G("replacetxt").value.replace(/^\s|\s$/g, "");
if (!findtxt) {
return false;
}
if (findtxt == replacetxt || (!getMatchCase("matchCase1") && findtxt.toLowerCase() == replacetxt.toLowerCase())) {
return false;
}
obj = {
searchStr:findtxt,
casesensitive:getMatchCase("matchCase1"),
replaceStr:replacetxt,
all:true
};
var num = frCommond(obj);
if (num) {
$G('replace-msg').innerHTML = lang.countMsg.replace("{#count}", num);
}
};
//执行
var frCommond = function (obj) {
return editor.execCommand("searchreplace", obj);
};
function searchText(str) {
let searchValue = $G(`${str}`).value
if (!searchValue) return;
//获取编辑器内容
//获取编辑器iframe文档对象
const iframeDoc = editor.iframe.contentDocument;
const body = iframeDoc.body;
const textNodes = getTextNodes(body);
//查找所有匹配项
if(str == 'findtxt1'){
replacematches = []
} else {
matches = []
}
textNodes.forEach(node => {
const nodeText = node.nodeValue;
const regex = new RegExp(`(${searchValue})`, 'gi');
let match;
while ((match = regex.exec(nodeText)) !== null) {
if(str == 'findtxt1'){
replacematches.push({
node,
offset: match.index,
length: match[0].length
})
} else {
matches.push({
node,
offset: match.index,
length: match[0].length
})
}
}
});
console.log(matches,replacematches,'matches')
}
//获取所有文本节点
function getTextNodes(node) {
const textNodes = [];
if (node.nodeType === Node.TEXT_NODE) {
textNodes.push(node);
} else {
const children = node.childNodes;
for (let i = 0; i < children.length; i++) {
textNodes.push(...getTextNodes(children[i]));
}
}
return textNodes;
}
//定位到指定匹配项
function scrollToMatch(index,str) {
let flag
if(str =='findtxt1'){
if (replacematches.length === 0 || replacecurrentIndex < 0 || replacecurrentIndex >= replacematches.length){
flag = true
}
} else if(str =='findtxt'){
if (matches.length === 0 || currentIndex < 0 || currentIndex >= matches.length){
flag = true
}
}
if(flag) return
let iframeDoc = editor.iframe.contentDocument;
let selection = iframeDoc.getSelection();
selection.removeAllRanges();
let match = str == 'findtxt1' ?replacematches[index]:matches[index];
let range = document.createRange();
range.setStart(match.node, match.offset);
range.setEnd(match.node, match.offset + match.length);
selection.addRange(range);
// range.surroundContents(highlightSpan);
// editor.fireEvent('selectionchange');
let rect = range.getBoundingClientRect();
// let iframeWindow = editor.iframe.contentWindow;
// let body = iframeWindow.document.querySelector('body');
//计算滚动位置
let scrollTop = rect.top + editor.document.documentElement.scrollTop - 30;
editor.document.documentElement.scrollTo({
top: scrollTop,
behavior: "smooth"
});
}
switchTab("searchtab");