2011-05-11 20 views
0

嗨,我有一個UL像這樣:如何改變parentNode風格上childNode事件屬性

<ul id="list"> 
    <li class="something"> 
     <div class="btns" onclick="add(this)"> + </div> 
     <div class="btns" onclick="sub(this)"> - </div> 
    </li> 
    <li class="something new"> 
     <div class="btns" onclick="add(this)"> + </div> 
     <div class="btns" onclick="sub(this)"> - </div> 
    </li> 
</ul> 

CSS明智的,一流的「東西」包含背景圖像。

我想在這裏實現什麼,是當加()或子()的調用函數,進行呼叫改變元素的parentNode的background-image屬性...

所以這樣,我不必爲每個元素製作ID,並且可以重複使用相同的函數...

我所擁有的是類似這樣的東西,但它不起作用(而是代碼我寫的是錯的):

function add(x) 
{ 
    var y = x.parentNode.style; 

    if (y.backgroundImage == 'url("../assets/1.png")' 
    { 
     y.backgroundImage = 'url("../assets/2.png")'; 
    } else if (y.backgroundImage == 'url("../assets/2.png")' 
     y.backgroundImage = 'url("../assets/3.png")'; 
    ... 
    ... so on so forth... 
} 

整體邏輯本身可能是p OOR,所以我願意接受新的建議太...

編輯#1:增加了更多的細節來解釋目前的情況......

從本質上講,有其填充了李的一個3x3的網格,背景圖像使用點指示當前數量。每個裏面都有兩個按鈕,用於添加和減少。點擊每一個,背景圖像應該改變以表示當前數量...並且這必須獨立於不同的li完成...

回答

1

我同意RobG使用類更適合 - 尤其是如果你決定使用框架。在關閉情況下,你不希望這裏有一些其他的方法:

更新了計算樣式 - 留下評論版在後期底部: 在這其中的主要區別是,它得到的內聯樣式或計算版本的背景圖像(例如,如果它是由類設置的)。

要獲得計算樣式,請查看quirksmode.org。特別是getstyles page的底部。

這是一個fiddle不工作在jsfiddle(有點累了,但我認爲它與我在工作中使用IE6 ...),但工作正常,如果你在一個正常的設置本地進行。

function add(x) { 
    var parent = x.parentNode; 
    var y = parent.currentStyle['backgroundImage'] || document.defaultView.getComputedStyle(parent,null).getPropertyValue('backgroundImage'); 
    switch(true) 
    { 
     case (y.indexOf("1.png")!=-1): 
      parent.style.backgroundImage = 'url("http://www.wskidmore.com/2.png")'; 
      break; 
     case (y.indexOf("2.png")!=-1): 
      parent.style.backgroundImage = 'url("http://www.wskidmore.com/3.png")'; 
      break; 
     case (y.indexOf("3.png")!=-1): 
      parent.style.backgroundImage = 'url("http://www.wskidmore.com/1.png")'; 
      break; 
    } 
} 

過時的,但評論邏輯。

function add(x) { 
     var y = x.parentNode.style.backgroundImage; 
    // using indexOf will avoid the possible quote issue and possibly other odd browser quirks 
    // switch true means it will do the first case it finds that evaluates to true 
    switch(true) 
    { 
     // indexof means it looks through your string for the given substring 
     // and returns the position so, "abc".indexOf("b") returns 1 (its 0 based) 
     // if it doesnt find it anywhere it returns -1 
     // so for our switch, it looks inside the backgroundImage string 
     // url("../assets/x.png") no-repeat 50% 50% 
     // or whatever it may be for the part "1.png" 
     // if it finds it, it will return 5, or 8, or whatever the position is 
     // if not it returns -1 
     // so when this gets evaluated we check for "not -1" 
     case (y.indexOf("1.png")!=-1): 
      // if this case is true, then everything between the : and break; 
      // will be performed, then it exits the switch 
      y = 'url("../assets/2.png")'; 
      break;  
     case (y.indexOf("2.png")!=-1): 
      y = 'url("../assets/3.png")'; 
      break;  
     case (y.indexOf("3.png")!=-1): 
      y = 'url("../assets/4.png")'; 
      break;  
    } 
} 
+0

嘿,我似乎能夠理解你的代碼,我同意,在一定程度上改變CSS類會更容易。但讓我們先談談你的第一個函數 - 糾正我,如果我在這裏錯了,但開關參​​數'(真)'將比較案件,以檢查它們是否是真實的,並據此執行代碼?如果是這樣,你的第一個案例(y.indexOf(「1.png」)!= - 1): - 你是否介意解釋這一點?我似乎沒有得到它... :-( – Abhishek 2011-05-11 07:02:15

+1

添加了一些評論,但是是的,它會執行第一個案件,它發現評估爲真。indexOf搜索y(主字符串)的子字符串(1。 png)並返回主字符串內部字符串的位置...如果它沒有找到它,它會返回-1 – WSkid 2011-05-11 07:11:27

+0

啊,感謝您的解釋......對我有意義,現在執行,會讓你知道它是如何去... :-) – Abhishek 2011-05-11 07:24:00

0

使用getElementsByName()函數,設置相同的名稱on所有你想改變的節點。

function add(x) { 
    var elements = document.getElementsByName("somename"); 
    /* Iterate over the array and set the .style.* elements as needed */ 
} 

http://www.w3schools.com/jsref/met_doc_getelementsbyname.asp

+0

嘿,感謝您的超快反應,但我不明白這是如何解決我的問題,除非你建議變量將包含一個數組,其中所有的李將被存儲。這仍然只是一個答案,我如何有條件地從觸發事件的節點更改父節點的背景圖像?我已經更新了操作系統以包含對情況的簡要描述。 – Abhishek 2011-05-11 03:14:23

+0

'document.getElementsByName'是一個可怕的函數,並且在Internet Explorer中使用時非常煩人。請不要使用它。 – 2011-05-11 03:22:01

+0

@Matt - 我同意'getElementsByName'在這裏不合適(不僅因爲OP中沒有任何元素應該有名字),而且爲什麼在IE中使用「stupefying」呢? – RobG 2011-05-11 04:49:41

0

您的代碼應該工作正常,但你匹配現有的背景圖像錯誤。它不會返回與您設置相同的引用。

//When setting the url property, you need to wrap the actual URI in double quotes 
//and then wrap the whole thing in single quotes to indicate to JS that it's a string 
y.backgroundImage = 'url("../assets/1.png")'; //set background image 

//y.backgroundImage now has a value of 'url(../assets/1.png)'  

//Here you try to match the value of y.backgroundImage against the string you 
//originally stored in it, but that won't work 
y.backgroundImage == 'url("../assets/1.png")'; //false 

//The backgroundImage property returns a string that has the quotes stripped 
//out of the inside of the URL definition 
y.backgroundImage == "url(../assets/1.png)"; //true 
+0

好吧,所以我進入我的CSS文件,並改變了語法,網址(../ assets/1.png)|在技​​術上,現在,根據你所說的,如果我檢查y.backgroundImage ==「url(../ assets/1.png)」,我應該從瀏覽器得到積極的迴應...相反,我得到的是null ... :-( – Abhishek 2011-05-11 07:08:02

+1

@Abhishek我只是在談論JavaScript。當你在CSS或JavaScript中設置值時,你需要在實際url(url(「。 ./path/file「)),但是當你在JavaScript中獲得這個屬性時,它不會帶着這些引號回來,我會編輯我的例子來更清楚。 – 2011-05-11 12:58:01

+0

啊,謝謝你的解釋... :-) – Abhishek 2011-05-12 02:18:39

0

您似乎在找到parentNode ok。除了設置樣式對象的屬性之外,還可以考慮添加和刪除類。一些簡單的功能是:

var yourLib = { 
    dom: {}, 
    util: {} 
}; 

/* Check if an element has a particular class name 
*/ 
yourLib.dom.hasClassName = function(el, cName) { 
    if (typeof el == 'string') el = document.getElementById(el); 

    var re = new RegExp('(^|\\s+)' + cName + '(\\s+|$)'); 
    return el && re.test(el.className); 
} 

/* Add a class name if element doesn't already have it 
*/ 
yourLib.dom.addClassName = function(el, cName) { 

    if (typeof el == 'string') el = document.getElementById(el); 

    if (!yourLib.dom.hasClassName(el, cName)) { 
     el.className = yourLib.util.trim(el.className + ' ' + cName); 
    } 
} 

/* Remove a class name if element has it 
*/ 
yourLib.dom.removeClassName = function(el, cName) { 

    if (typeof el == 'string') el = document.getElementById(el); 

    if (util.dom.hasClassName(el, cName)) { 
     var re = new RegExp('(^|\\s+)' + cName + '(\\s+|$)','g'); 
     el.className = yourLib.util.trim(el.className.replace(re, '')); 
    } 
} 

/* Remove leading and trailing whitespace and reduce 
** multiple intermediate whitespaces to a single space 
*/ 
yourLib.util.trim = function(s) { 
    return s.replace(/(^\s+)|(\s+$)/g,'').replace(/\s+/g,' '); 
} 
+0

Omg ...你打破了我的大腦......大聲笑......這看起來相當複雜,我讚揚你能夠快速烹飪它......但是,從我所收集的,你是遍歷整個文檔,添加或刪除一個類(這是一個公平的替代更改背景圖像)到一個特定的元素(ID需要)...這並不完全解決我的問題(基於我的undefined rstanding您的解決方案)。當用戶點擊'+'符號時,背景應該改變以反映添加,等等......我沒有元素的ID,並且有很多'em'... – Abhishek 2011-05-11 06:21:48

0

好了,我懂了工作,這裏是爲誰以後在此絆倒的解決方案...

function add(x) 
{ 
    var y = x.parentNode.style.backgroundImage; 
    if ((y == '') || (y.indexOf("3_0.png") != -1)) 
     x.parentNode.style.backgroundImage = 'url(../_assets/3_1.png)'; 
    else if (y.indexOf("3_1.png") != -1) 
     x.parentNode.style.backgroundImage = 'url(../_assets/3_2.png)'; 
    else if (y.indexOf("3_2.png") != -1) 
     x.parentNode.style.backgroundImage = 'url(../_assets/3_3.png)'; 
    else if (y.indexOf("3_-3.png") != -1) 
     x.parentNode.style.backgroundImage = 'url(../_assets/3_-2.png)'; 
    else if (y.indexOf("3_-2.png") != -1) 
     x.parentNode.style.backgroundImage = 'url(../_assets/3_-1.png)'; 
    else if (y.indexOf("3_-1.png") != -1) 
     x.parentNode.style.backgroundImage = 'url(../_assets/3_0.png)'; 
} 

基本上,WSkid的幫助(謝謝!)我用「的indexOf」以確定哪個是當前背景,並相應地根據調用哪個函數而改變。這是添加功能的代碼。

+0

非常感謝所有幫助過的人,特別是WSkid和ZohoGorganZola(哈哈)...... – Abhishek 2011-05-12 02:20:11