鍍金池/ 問(wèn)答/HTML5  HTML/ 一個(gè)大的DOM結(jié)構(gòu),里面的元素node是否有唯一且穩(wěn)定的標(biāo)示,可以在刷新后再選中

一個(gè)大的DOM結(jié)構(gòu),里面的元素node是否有唯一且穩(wěn)定的標(biāo)示,可以在刷新后再選中它?

如題,我們需要做一個(gè)針對(duì)網(wǎng)頁(yè)的筆記系統(tǒng)。
用戶劃選時(shí),我們可以獲得起始點(diǎn)的node,直接操作顯示高亮。

我們遇到的難題是:當(dāng)用戶離開(kāi)后,再次打開(kāi)這個(gè)頁(yè)面時(shí),我們?nèi)绾味ㄎ换厝ミ@個(gè)節(jié)點(diǎn)node。(已知:網(wǎng)頁(yè)的節(jié)點(diǎn)不會(huì)變化,因?yàn)槲覀兙彺娴模?/p>

PS:我們不能給網(wǎng)頁(yè)上的節(jié)點(diǎn)添加id之類(lèi)的東西

回答
編輯回答
淚染裳
我們遇到的難題是:當(dāng)用戶離開(kāi)后,再次打開(kāi)這個(gè)頁(yè)面時(shí),我們?nèi)绾味ㄎ换厝ミ@個(gè)節(jié)點(diǎn)node。(已知:網(wǎng)頁(yè)的節(jié)點(diǎn)不會(huì)變化,因?yàn)槲覀兙彺娴模?/blockquote>

結(jié)構(gòu)不變的情況下,XPATH 就是標(biāo)識(shí)啊, jQuery 的 selector 也一樣。

2017年9月19日 13:38
編輯回答
心癌

可以存在session里,然后在js中獲取這個(gè)session的值,進(jìn)行后續(xù)的操作,如高亮等

2017年1月6日 17:45
編輯回答
負(fù)我心

花了點(diǎn)時(shí)間實(shí)現(xiàn)了下,隨便找了幾個(gè)網(wǎng)頁(yè)測(cè)試,暫時(shí)沒(méi)發(fā)現(xiàn)問(wèn)題。
首先打開(kāi)網(wǎng)頁(yè)A,執(zhí)行下面的代碼:

let sel = window.getSelection();
let range = sel.getRangeAt(0);
let startNode = range.startContainer;
let endNode = range.endContainer;

//startContainer是不是文本節(jié)點(diǎn),是的話存儲(chǔ)父節(jié)點(diǎn)的信息
if (startNode.nodeType == 3) {
  var startIsText = true;
  var startFlag = startNode.parentNode;
  startNode = startNode.nodeValue;
} else {
  var startIsText = false;
  var startFlag = startNode;
}
if (endNode.nodeType == 3) {
  var endIsText = true;
  var endFlag = endNode.parentNode;
  endNode = endNode.nodeValue;
} else {
  var endIsText = false;
  var endFlag = endNode;
}

let startOffset = range.startOffset; 
let endOffset = range.endOffset; 

let startTagName = startFlag.nodeName;
let startHTML = startFlag.innerHTML;

let endTagName = endFlag.nodeName;
let endHTML = endFlag.innerHTML;

//這個(gè)是要存儲(chǔ)到數(shù)據(jù)庫(kù)的信息
let rInfo = {
  startNode,
  startOffset,
  startIsText,
  startTagName,
  startHTML,

  endNode,
  endOffset,
  endIsText,
  endTagName,
  endHTML  
};
//存在localStorage里測(cè)試
window.localStorage.setItem("r", JSON.stringify(rInfo));

然后關(guān)閉網(wǎng)頁(yè)A,再重新打開(kāi),執(zhí)行下面的代碼:

//根據(jù)tabName和innerHTML定位到相應(yīng)節(jié)點(diǎn)
function findEle(tagName, innerHTML) {
  let list = document.getElementsByTagName(tagName);
  for (let i = 0; i < list.length; i++) {
    if (list[i].innerHTML == innerHTML) {
      return list[i];
    }
  }
}

//重新顯示選中區(qū)域的函數(shù)
function show({startNode,startIsText,startOffset,endNode,endIsText,endOffset},sP,eP) {
  var s, e;
  //判斷原來(lái)的選區(qū)是不是由文本節(jié)點(diǎn)開(kāi)始,分開(kāi)處理
  if (startIsText) {
    let childs = sP.childNodes;
    for (let i = 0; i < childs.length; i++) {
      if (childs[i].nodeType == 3 && childs[i].nodeValue == startNode)
        s = childs[i];
    }
  } else {
    s = startNode;
  }
  //判斷原來(lái)的選區(qū)是不是由文本節(jié)點(diǎn)結(jié)束,分開(kāi)處理
  if (endIsText) {
    let childs = eP.childNodes;
    for (let i = 0; i < childs.length; i++) {
      if (childs[i].nodeType == 3 && childs[i].nodeValue == endNode)
        e = childs[i];
    }
  } else {
    e = startNode;
  }
  //重新構(gòu)造選區(qū)并顯示
  let range = document.createRange();
  range.setStart(s, startOffset);
  range.setEnd(e, endOffset);

  let sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
}

function use(obj) {
  //定位開(kāi)始節(jié)點(diǎn)
  let sP = findEle(obj.startTagName, obj.startHTML);
  //定位結(jié)束節(jié)點(diǎn)
  let eP = findEle(obj.endTagName, obj.endHTML);
  show(
    obj,
    sP,
    eP
  );
}
//獲取localStorage里存儲(chǔ)的選區(qū)數(shù)據(jù)
let a = window.localStorage.getItem("r");
//調(diào)用函數(shù)顯示
use(JSON.parse(a));

大概就是這樣,求采納

2017年1月2日 20:00