Javascript 如何更改childNode事件的parentNode样式属性

Javascript 如何更改childNode事件的parentNode样式属性,javascript,Javascript,嘿,伙计们,我有一个UL,就像这样: <ul id="list"> <li class="something"> <div class="btns" onclick="add(this)"> + </div> <div class="btns" onclick="sub(this)"> - </div> </li> <li class="somethi

嘿,伙计们,我有一个UL,就像这样:

<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>
整体逻辑本身可能很糟糕,所以我也愿意接受新的建议

编辑#1:添加了更多细节来解释当前情况

基本上,有一个3x3的网格,其中填充了li,背景图像使用点指示当前数量。每个li内有两个按钮,用于加和减。点击每一个按钮,背景图像应该改变以表示当前数量。。。这必须独立于不同的李的

使用getElementsByName()函数,在所有要更改的节点上设置相同的名称

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

除了与现有背景图像匹配错误外,您的代码应该可以正常工作。它不会返回与设置时相同的引用

//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

您似乎发现parentNode正常。除了设置样式对象的属性之外,还可以考虑添加和移除类。要做到这一点,一些简单的函数是:

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,' ');
}

我同意RobG的观点,使用类更合适——特别是当您决定使用框架时。在关闭的情况下,您不想使用以下其他方法:

针对计算样式进行更新-将注释版本保留在文章底部: 这种方法的主要区别在于它获取内联样式或计算版本的背景图像(例如,如果它是由类设置的)

要获取计算样式,请查看quirksmode.org。尤其是在底部

这是一个在JSFIDLE中不起作用的工具(有点累了,但我认为这与我在工作时使用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;      
    }
}

好的,我让它工作起来了,这是为以后偶然发现它的人提供的解决方案

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'来确定哪个是当前背景,并根据调用的函数进行相应的更改。这是加法函数的代码

嘿,谢谢你的超快速响应,但我不知道这将如何解决我的问题,除非你建议变量将包含一个数组,其中所有的li都将被存储。这仍然是半个答案,如何有条件地从触发事件的节点更改父节点的背景图像?我已经更新了OP,添加了对情况的简要描述
文档。getElementsByName
是一个可怕的函数,在Internet Explorer中使用会让人感到惊讶。请不要推荐使用它。@Matt-我同意
getElementsByName
在这里是不合适的(不仅仅是因为OP中的任何元素都不应该首先有一个名称),但是为什么在IE中“使用起来很傻”呢?我可能没有资格有意义地插入,但是getElementsByTagName不是更合适吗?@RobG,它在
id
s和
name
s之间交替,具体取决于哪个匹配数组的数量更大。它还忽略
div
span
标记中的
name
s。资料来源:Omg。。。你伤了我的大脑。。。英雄联盟这看起来相当复杂,我赞扬你能如此迅速地把它编造出来。。。但是,从我收集的信息来看,您正在遍历整个文档,以便将一个类(这是更改背景图像的合理选择)添加或删除到特定元素(需要ID)。。。这并不能完全解决我的问题(基于我对您的解决方案的理解)。当用户单击“+”符号时,背景应改变以反映添加的内容,依此类推。。。我没有元素的ID,其中有很多…嘿,我似乎能够理解你的代码,我同意,在某种程度上更改CSS类会更容易。但是让我们先来讨论一下您的第一个函数——如果我在这里出错,请纠正我,但是switch参数“(true)”将比较这些情况以检查它们是否为真,并相应地执行代码?如果是这样,您的第一个案例(y.indexOf(“1.png”)!=-1):-您介意解释一下吗?我似乎不明白…:-(添加了一些注释,但是是的,它将执行它找到的第一个计算结果为true的案例。indexOf搜索a子字符串(1.png)的y(主字符串)并返回主字符串中内部字符串的位置…如果找不到它,它将返回-1Ah,感谢您的解释…对我来说有意义,现在实现,将让您知道它是如何运行的…:-):-(它没有解决…发生了什么,当我在if语句中用一个条件以最基本的形式实现它时,x.parentNode.style.backgroundImage=null的值,因此1.png的索引位置是=-1…但是任何其他子字符串的索引位置也是如此…对不起,我假设您发布的原始代码是getting背景图像字符串。我在上面发布了一个新版本,展示了如何获取计算的背景图像。好的,所以我进入了我的CSS文件,并将那里的语法更改为| url(../assets/1.png)|根据您所说的,如果我选中y.backgroundImage==“url(../assets/1.png)”,从技术上讲,现在就完全是| url(../assets/1.png)|,我应该从浏览器得到肯定的响应…相反,我得到的是空的…:-(@Abhishek我只是在JavaScript中说的。当你在CSS或JavaScript中设置值时,你需要在实际url(url(“../path/file”))周围加引号,但当你在JavaScript中获得属性时,它不会带着那些引号返回。我将编辑我的示例以使其更清晰。非常感谢所有提供帮助的人,特别是WSkid和ZohoGorganZola(lol)。。。
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)';
}