为什么el.style.backgroundImage在这个功能上下文中不起作用?

时间:2012-10-21 19:22:48

标签: javascript

我为这个问题写了一个答案:New background according to url,我在回答中发布的代码是检查URL是否存在特定字符串,如果存在,则更改背景图像给定元素。

原来如此!我是我,我以为我会尝试避免使用jQuery,并使用以下内容来寻找更传统的vanilla JavaScript方法:

var images = {
    'halloween' : '/images/newbackground.jpg',
    'christmas' : '/images/xmasbackground.jpg'
};

var url = document.location.href,
    elem = document.getElementById('elementThatYouWantToStyle');

for (var keyword in images){
    if (images.hasOwnProperty(keyword) && url.indexOf(keyword) !== -1) {
        elem.style.backgroundImage = images[keyword];
    }
}

Source

然后我认为我会转换为功能性方法,所以它变成了这个:

var images = {
    'halloween': 'http://davidrhysthomas.co.uk/img/dexter.png',
    'christmas': 'http://davidrhysthomas.co.uk/img/mandark.png'
};

function setBG(el, map, url) {
    if (!el || !map) {
        return false;
    }
    else {
        var url = url || document.location.href,
            el = el.nodeType == 1 ? el : document.getElementById(el);
        for (var keyword in map) {
            if (map.hasOwnProperty(keyword) && url.indexOf(keyword) !== -1) {
                el.style.backgroundImage = encodeURIComponent(map[keyword]);
            }
        }
    }
}

setBG('one', images, 'http://some.domain.com/with/halloween.jpg');
setBG(document.getElementById('two'), images, 'http://some.domain.com/with/christmas.jpg');

JS Fiddle demo

现在,如果我在console.log()循环中向if评估中添加for...in,则表明我们正在进入循环,而控制台suggests that I have an accurate reference to the DOM node, the images object, the URL (as passed into the function) and am getting the correct value from the object

然而,我尝试设置el.style.backgroundImage属性的以下行工作(无论我是否将map[keyword]包装在encodeURIComponent()或者虽然我只是链接到我所做的尝试。所以:我的逻辑中明显的缺陷是什么?为什么el.style.backgroundImage没有设置?< / p>

(顺便说一句JS Lint,在JS Fiddle,似乎对此感到高兴(除了重新定义现有变量(urlel)以便有一个回退/默认值)。

2 个答案:

答案 0 :(得分:5)

除非您将其包含在backgroundImage中,否则该网址不是有效的url()值。

el.style.backgroundImage = 'url(' + map[keyword] + ')';

Fiddle

<小时/> 此外,您不应该encodeURIcomponent整个网址,否则它甚至会对协议的:/进行编码,从而产生404(由于现在缺少协议)被解释为相对URL:

  

获取http://fiddle.jshell.net/_display/http%3A%2F%2Fdavidrhysthomas.co.uk%2Fimg%2Fdexter.png 404(未找到)

相反,为了更安全地编码完整URI,您可以使用encodeURI

el.style.backgroundImage = 'url("' + encodeURI(map[keyword]) + '")';

Fiddle

注意: MDN提到encodeURI在使用GET请求的不同浏览器中可能无法正常工作,即包含查询字符串的网址。我不能重现那个问题。


同样如@jfriend00所述,var之前的url关键字是不必要的,因为它已经属于函数范围,因为它被声明为形式参数。阅读更多:JavaScript Scoping and Hoisting

答案 1 :(得分:5)

您声明已将url定义为参数var url的本地变量url,您还需要使用url(http:/xxxx)形式。

更改为此内容(已在var前删除了url并在网址周围添加了url()):

function setBG(el, map, url) {
    if (!el || !map) {
        return false;
    }
    else {
        url = url || document.location.href;
        el = el.nodeType == 1 ? el : document.getElementById(el);
        for (var keyword in map) {
            if (map.hasOwnProperty(keyword) && url.indexOf(keyword) !== -1) {
                el.style.backgroundImage = 'url(' + map[keyword] + ')';
            }
        }
    }
}