基于ueditor编辑器的功能开发之重写ueditor的查找和替换功能,支持滚动定位

百度编辑器的查找和替换无法随着页面滚动定位,找到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");

内容概要:本文深入探讨了AMESim仿真平台在电动汽车(EV)热泵空调系统设计与优化中的应用。首先介绍了AMESim的基础建模方法,如构建制冷循环模型中的压缩机、蒸发器冷凝器等组件,并详细解释了各部件的工作原理及其参数设定。接着重点阐述了EV热泵空调系统的特殊之处,即不仅能够制冷还可以在冬季提供高效的制热功能,这对于提高电动汽车在寒冷条件下的续航里程乘坐舒适性非常重要。文中给出了几个具体的案例,包括通过改变压缩机运行频率来进行性能优化,以及针对低温环境下热泵系统的控制策略,如四通阀切换逻辑、电子膨胀阀开度调节等。此外,还讨论了热泵系统与其他子系统(如电池温控)之间的协同工作方式,强调了系统集成的重要性。最后分享了一些实用的经验技巧,例如如何避免仿真过程中可能出现的问题,怎样评估系统的整体性能等。 适合人群:从事汽车工程、暖通空调(HVAC)领域的研究人员技术人员,特别是关注新能源汽车热管理系统的专业人士。 使用场景及目标:适用于希望深入了解电动汽车热泵空调系统特性的工程师们,旨在帮助他们掌握基于AMESim进行系统建模、仿真分析的方法论,以便更好地指导实际产品研发。 阅读建议:由于涉及到较多的专业术语技术细节,建议读者具备一定的机械工程背景知识,同时配合官方文档或其他参考资料一起研读,以加深理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值