2016-08-13 40 views
5

我想寫一個JavaScript函數,將一個樣式對象應用於HTML元素,但只有如果該對象存在。使用hasOwnProperty()引用對象

例如,如果我有以下對象:

objMyObject { 
    "idstring": { 
     "style" : { 
      "opacity": "0.50" 
     } 
    } 
}; 

於是我就用hasOwnProperty()先檢查「風格」嘗試應用它之前就存在 - 這工作得很好。

然而,讓我們想象一下,我的對象有多種款式:

objMyObject { 
    "idstring1": { 
     "style" : { 
      "opacity": "0.50" 
     } 
    }, 

    "idstring2": { 
     "style": { 
      "opacity": "0.99" 
     } 
    }, 

    "idstring3": { 
     "style": { 
      "opacity": "0.50" 
     } 
    } 

}; 

現在,有時候這些個人風格的對象可以是相同的。以上的例子是短,但對象可以是大得多,持有多個樣式屬性,所以它會更好,如果我可以這樣做:

objMyObject { 
    "idstring1": { 
     "style" : { 
      "opacity": "0.50" 
     } 
    }, 

    "idstring2": { 
     "style": { 
      "opacity": "0.99" 
     } 
    }, 

    "idstring3": { 
     // This particular style object has the same properties as 
     // idstring1 
     "apply": "idstring1" 
    } 

}; 

所以,我可以那麼做這樣的事情:

if (objMyObject.hasOwnProperty("idstring3")) { 
    if (objMyObject.idString3.hasOwnProperty("apply")) 
     // Apply an existing, alternative style object. 
     // 
     $("#el").css(objMyObject.idstring3.apply) 
    else if (objMyObject.idstring3.hasOwnProperty("style")) 
     $("#el").css(objMyObject.idString3.style) 
} 

的問題是,要hasOwnProperty第一次調用()

if (objMyObject.hasOwnProperty("idstring3")) 

評估爲真,這是偉大的。但是,即使對象包含「樣式」或「應用」對象,後續調用也會失敗。

下面是完整的代碼,我的工作:

// JavaScript object - the "mouseout" object should apply the 
// "init" object. 
// 
var objHeader = { 
    "targetID": "header", 

    "init": { 
     "style": { 
      "backgroundColor": "#FF0000", 
      "opacity": "0.00" 
     } 
    }, 

    "load": { 
     "style": { 
      "opacity": "0.50" 
     } 
    }, 

    "mouseover": { 
     "style": { 
      "opacity": "0.99" 
     } 
    }, 

    // Here, the elApply() function should apply the "style" defined 
    // in "init". 
    // 
    "mouseout": { 
     "apply": "init" 
    } 
}; 

這裏的兩個功能我用:

// Apply a style to an object - will return false on error or true 
// on success. 
// 
// State is the object to be applied, for example: 
// 
// elApply(objHeader, "mouseout"); 
// 
// To apply the style attached to "mouseout". 
// 
function elApply(
    objElement, 
    objState 
) { 
    // Example - if elInit calls elApply(objHeader, "mouseout"); 
    // then will first look for objHeader.mouseout.apply, if that 
    // exists then it should point to another object with a style 
    // to be applied - if this is the case true is returned here 
    // and all is well. 
    // 
    if (elApply(objElement.objState, "apply")) { 
     alert("Applied 'apply' to " + objState); 
     return true; 
    } 

    // No "apply" exists, so attempt to apply a "style" 
    // object. 
    // 
    if (objElement.objState.hasOwnProperty("style")) { 
     $("#" + objElement.targetID).css(objElement.objState.style); 
     return true; 
    } 

    alert("Neither '" + objState + "' nor 'apply' exist in this object!"); 
    return false; 
} 

function elInit(
    objElement 
) { 
    $(document).ready(function() { 
     var targetID = objElement.targetID;   
     elApply(objElement, "mouseout"); 
    }); 
} 

所以它的工作原理是這樣的:

  1. elInit()函數調用elApply(objElement,「mouseout」);
  2. 「鼠標移開」屬性存在,且elApply()功能評估objElement.hasOwnProperty( 「鼠標移出」)真正
  3. 檢查是否objElement.mouseout.apply存在,但顯然objElement.mouseout不確定,儘管早些時候hasOwnProperty()調用暗示「鼠標移開」存在。

希望這是明確的,任何想法?這不是什麼大不了的事情,如果對象不重複,我可以重新使用已定義的對象。

也許我的邏輯/實現或hasOwnProperty()的理解有一個根本的缺陷?如果是這樣,有沒有辦法讓父對象中的同級對象以這種方式相互引用?

非常感謝。

+0

那不是一個遞歸問題? – PHPglue

+0

可能是,遞歸是我加入了試圖解決最初的問題。也許我應該重新考慮這個......我認爲這個問題可能是因爲「應用」不是一個實際的對象,而是一個字符串......但它仍然是一個對象的行爲,所以想到也許是一個怪癖hasOwnProperty()方法。多謝。 – Nunchy

+0

如果正在調用遞歸函數,不管發生什麼,在這種情況下發生,你有一個無限循環問題。 – PHPglue

回答

2

我建議事先在對象中填充所有缺失的樣式。你的elStyle()函數變得更簡單,因爲它不再需要關心apply屬性。

從技術上講,將樣式從一個元素複製到另一個元素只是對對象引用的副本。所以,這是一個便宜的操作。

此代碼中do{} while()循環的原因是支持應用「鏈」(如我的示例中的mouseout0 > mouseout > init)。如果沒有遇到這種情況,您可以安全地將其刪除。

var objHeader = { 
 
    "targetID": "header", 
 

 
    "init": { 
 
     "style": { "backgroundColor": "#FF0000", "opacity": "0.75" } 
 
    }, 
 
    "load": { 
 
     "style": { "opacity": "0.50" } 
 
    }, 
 
    "mouseover": { 
 
     "style": { "opacity": "0.99" } 
 
    }, 
 
    "mouseout0": { 
 
     "apply": "mouseout" 
 
    }, 
 
    "mouseout": { 
 
     "apply": "init" 
 
    } 
 
}; 
 

 
function populateStyle(o) { 
 
    var success; 
 
    
 
    do { 
 
    success = false; 
 

 
    Object.keys(o).filter(
 
     function(k) { 
 
     return o[k].hasOwnProperty('apply'); 
 
     } 
 
    ).forEach(
 
     function(k) { 
 
     if(o.hasOwnProperty(o[k].apply) && o[o[k].apply].hasOwnProperty('style')) { 
 
      o[k].style = o[o[k].apply].style; 
 
      delete o[k].apply; 
 
      success = true; 
 
     } 
 
     } 
 
    ); 
 
    } while(success); 
 
} 
 

 
function elStyle(objElement, state) { 
 
    if(objElement.hasOwnProperty(state) && objElement[state].hasOwnProperty('style')) { 
 
    $('#' + objElement.targetID).css(objElement[state].style); 
 
    } 
 
    else { 
 
    // error: style undefined 
 
    } 
 
} 
 

 
populateStyle(objHeader); 
 
elStyle(objHeader, 'mouseout0');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="header">Hello World</div>

+0

我不得不同意......也許過於複雜的東西應該很簡單。欣賞示例代碼,也...非常好。多謝。 – Nunchy

+0

很高興幫助!我不會說你過分複雜。但性能方面,最好從一開始就擺脫複雜的部分。 – Arnauld

0

請刪除大寫字母'S',並在下面的代碼中做小's'。

(objMyObject.idString3.hasOwnProperty( 「應用」)) 與

替換(objMyObject.idstring3.hasOwnProperty( 「應用」))

因爲JavaScript是大小寫敏感的。

我認爲這會有所幫助。

+0

對不起 - 這只是幫助解釋問題的示例代碼 - 我使用的真實代碼會在OP的後面進一步發佈。對於cunfusion很抱歉。 – Nunchy