H5編輯器核心演算法和思想-遁地龍卷風

来源:http://www.cnblogs.com/resolvent/archive/2017/07/08/7138139.html
-Advertisement-
Play Games

代碼和特性在chrome49下測試有效。 文本渲染的本質是對文本節點的渲染,通過瀏覽器內置的對象Range可以獲得選擇的起始點、與終止點 getRangeObjec代碼如下 function getRangeObject(){ if(window.getSelection) { var select ...


代碼和特性在chrome49下測試有效。

文本渲染的本質是對文本節點的渲染,通過瀏覽器內置的對象Range可以獲得選擇的起始點、與終止點

 

var range = getRangeObject();
var start = range.startOffset,
end = range.endOffset;
var startContainer = range.startContainer;
var endContainer = range.endContainer;

getRangeObjec代碼如下

function getRangeObject(){

if(window.getSelection)
{
var selection = window.getSelection();
if(selection.rangeCount > 0)
{
return selection.getRangeAt(0);
}
}
else if(document.selection)
{
return document.selection.createRange(); 
}
return null;
};
View Code

 

  起始點始終在左面,終止點始終在右面,不受選擇方向的影響。
  只有當起始點的開頭或終止點的末尾是<br/>時,返回的不是文本節點,可以通過start,end確定br元素的位置分別是startContainer.childNodes[start],endContainer.childNodes[end-1]。返回的是文本節點start表示游標相對於起始文本節點所在的起始位置,end表示游標相對於終止文本節點所在的終止位置。

獲得下一個文本節點的演算法為

function getNextTextNode(startNode,dir = "nextSibling"){
    //記錄startNode變化之前的狀態,startNode變化後無效時便於狀態的回滾
    let unchangeNode = startNode;
    if(startNode.nodeType == 3){
        startNode = startNode[dir];
    }
    while (true){

        if(startNode == undefined){
            if(unchangeNode == undefined){
                //保護機制
                throw new Error("程式會陷入死迴圈");
                break;
            }
            /*
                startNode所在的父元素所有選中節點遍歷完畢,將sartNode指向父元素的兄弟節點
            */
            let parent = unchangeNode.parentElement;
            unchangeNode = parent;
            startNode = parent[dir];
        }
        else if(startNode.nodeType == 3){
            //文本節點則退出迴圈
            break;
        }
        else if(startNode.tagName == "BR"){
            //處理單標簽,避免不必要的迭代
            unchangeNode = startNode;
            startNode = startNode[dir];
        }
        else if(startNode.nodeType == 1){
            /*
                如果是雙標簽元素則進入
            */
            unchangeNode = startNode;

            if(dir == "previousSibling"){

                startNode = $(startNode).contents().last().get(0);
            }
            else if(dir == "nextSibling"){
                startNode = $(startNode).contents().first().get(0);
            }
            else {
                //便於錯誤的定位
                throw new Error("錯誤的遍歷方向:"+dir);
            }
        }
        else {
            //便於錯誤的定位
            throw new Error("不期待的元素類型=》"+startNode);

        }
    }
    
    return startNode;
    
}

  //上述函數用外部變數+while迴圈的方式取代遞歸,加入的保護機制減少誤用、潛在bug導致極差的體驗。
獲得起始節點和結束節點之間的所有文本節點

function getTextNodes(startTextNode,endTextNode){
    let textNodeArray = [];
    let node = startTextNode;
    while (true) {
        node = getNextTextNode(node);

        if(node == endTextNode){
            break;
        }
        textNodeArray.push(node);
    }
    
    return textNodeArray;

}

 贊賞支持


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 時間限制: 1 s 空間限制: 128000 KB 題目等級 : 大師 Master 題解 查看運行結果 時間限制: 1 s 空間限制: 128000 KB 題目等級 : 大師 Master 時間限制: 1 s 空間限制: 128000 KB 題目等級 : 大師 Master 時間限制: 1 s 時 ...
  • @WebServlet 作用 在Eclipse中創建Servlet後,Eclipse不會自動在web.xml中生成該Servlet對應的mapping信息,而是在Servlet代碼中加入註解@WebServlet。 @WebServlet 用於將一個類聲明為 Servlet,該註解將會在部署時被容器 ...
  • 一、一般介紹 STL(StandardTemplate Library),即標準模板庫,是一個具有工業強度的,高效的C++程式庫。它被容納於C++標準程式庫(C++Standard Library)中,是ANSI/ISOC++標準中最新的也是極具革命性的一部分。該庫包含了諸多在電腦科學領域里所常用 ...
  • numbers類型: 數字類型的數據有Byte,Short,Float,Int,Long,Double,這些類型在java中也都是基礎數據類型。 與java不同之處在於: Char類型已經不再是數字類型了。 在java之中基礎數據類型都對應有一個包裝類,如int,對應Integer,而在kotlin ...
  • JavaScript 是世界上最流行的,輕量級的編程語言。 這門語言可用於 HTML 和 web,更可廣泛用於伺服器、PC、筆記本電腦、平板電腦和智能手機等設備; JavaScript 被數百萬計的網頁用來改進設計、驗證表單、檢測瀏覽器、創建cookies,以及更多的應用。 系統的知識圖解: 在we ...
  • 他們可以存儲: 數組 json數據 圖片 腳本 樣式文件 ; 客戶端的存儲的兩個: 1.localStorage 沒時間限制的數據存儲() 方法有:.localStrage.getItem();localStrage.setItem();removeItem();localStrage.key()從 ...
  • JScookie 常用的3個預設函數(庫)無標題文檔記住用戶名學術或足球分析交流微信:chinamaths(進討論組) Don't hesitate to comment or add a like - Yours Bill Bill's技術博客 足球分析博客 足彩數據視頻 比爾極客日誌_博客園 比... ...
  • <?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappe ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...