2014-01-09 68 views
1

我知道可以可以使用querySelector反查詢選擇符是否存在?

var element = document.querySelector(".myclass") 

在文檔中找到的元素,但不存在一個逆querySelector使得:

var selector = document.inverseQuerySelector(element); 
Assert.AreEqual(element, document.querySelector(selector)); 

inverseQuerySelector的返回選擇器總是唯一標識指定的元件?

+0

儘量 「不」,因爲在這個問題中簡要顯示答案:http://stackoverflow.com/questions/10777684/how-to-use-queryselectorall-only-for-elements-that-have-a-specific-attribute-set – BrianHall

回答

2

不,因爲有很多可以選擇相同元素的選擇器(可能是無限的)。

對於函數是不可逆的(即使在數學),它的映射必須是1到1,情況並非如此。

順便說一句,因此,你可以創建一些可能只有在某些情況下。例如:

function inverseForElementWithUniqueId(element){ 
    return '#' + element.id; 
} 

var selector = inverseForElementWithUniqueId(element); 
Assert.AreEqual(element, document.querySelector(selector)); //True 

(代碼這的確看起來可能微不足道)

但正如所說,因爲理論的,這隻會在的情況下的一個子集工作。

但是,它的工作只是有時

+0

也許inverseQuerySelector是一個壞名字。我想我所有的後面都可以生成一個選擇器,它唯一地標識文檔中的給定元素,而不是任何可能的選擇器的反轉。 – Tom

+1

鑑於此,我擴展了答案 –

+0

您可以基於類,id和dom位置構建完整的查詢,但我不明白這會如何受益 – Aidiakapi

1

您可以創建一個能夠在所有情況下工作。有兩種方式:

  1. 使用第n個孩子(這是使用指數)

的溶液如下:

function getMyPathByIndex(element){ 

     if(element == null) 
      return ''; 

     if(element.parentElement == null) 
      return 'html' 

     return getMyPathByIndex(element.parentElement) + '>' + ':nth-child(' + getMyIndex(element) + ')'; 

    } 

function getMyIndex(element){ 

     if(element == null) 
      return -1; 
     if(element.parentElement == null) 
      return 0; 

     let parent = element.parentElement; 

     for(var index = 0; index < parent.childElementCount; index++) 
      if(parent.children[index] == element) 
       return index + 1; 

} 

例如,元件

<a id="y" class="vote-up-off" title="This answer is useful">up vote</a> 

您只需在控制檯輸入得到此頁面這個元素:

document.querySelector('a[title="This answer is useful"]'); 

有它獨特querySelector

HTML>:第n個孩子(2)>:第n柴爾德(5)>:第n個孩子(1)>:第n個孩子(1)>:第n個孩子(3)>:第n個孩子(2)>:第n個孩子(6)>:第n個孩子(1)>:第n孩子(1)>:第n孩子(1)>:第n孩子(1)>:第n孩子(1)>:第n孩子(2)

  1. 使用了「人類可讀」的方式屬性:
    1. 獲取的元素(只有明確的屬性)的屬性。
    2. 獲取元素的整個路徑。
    3. 使用多個屬性選擇器統一所有功能。

之前使用相同的Elemen有它獨特querySelector

HTML>身體> DIV> DIV> DIV> DIV> DIV> DIV> TABLE> TBODY> TR> TD > DIV>一個[ID = 「Y」] [類= 「表決向上客」] [標題= 「這 答案是有用的」]

測試如果溶液是正確由:

// e is an element and e must exist inside the page 
document.querySelector(getMyPathByIndex(e)) === e && 
document.querySelectorAll(getMyPathByIndex(e)).length === 1 

的代碼解決方案是如下:

function convertAttributesToQuerySelector(element){ 

    var tagName = element.tagName.toLowerCase(); 
    var result = tagName; 

    Array.prototype.slice.call(element.attributes).forEach(function(item) { 
    if(element.outerHTML.contains(item.name)) 
    result += '[' + item.name +'="' + item.value + '"]'; 

}); 

    return result; 
    //["a[id="y"]", "a[class="vote-up-off"]", "a[title="This answer is useful"]"] 

} 

function getMyPath(element){ 

    if(element.parentElement.tagName == 'HTML') 
    return 'html'; 

    return getMyPath(element.parentElement) + '>' + element.parentElement.tagName.toLowerCase() ; 
    //"html>body>div>div>div>div>div>div>table>tbody>tr>td>div" 

} 

function myUniqueQuerySelector(element){ 

    var elementPath = getMyPath(element); 
    var simpleSelector = convertAttributesToQuerySelector(element); 

    return elementPath + '>' + simpleSelector; 

} 

您可以隨時測試,如果該解決方案是正確的通過:

// e is an element and e must exist inside the page 
document.querySelector(myUniqueQuerySelector(e)) === e && 
document.querySelectorAll(myUniqueQuerySelector(e)).length === 1