获取类中的类时,Javascript失败


Javascript failing when getting a class within a class

我正在为我的摄影网站开发"工作安全模式"(默认情况下隐藏nudes[NSFW])。

index.php包含一系列包含:

<?php include 'images/20090820_9616/card.php';?>     
<?php include 'images/20110509_1509/card.php';?>
etc..

card.php对于所有SFW图像都是相同的(图.class除外)

<figure id="<?php echo basename(__DIR__);?>" class="Horizontal Landscape FallColor">
    <a href="<?php echo 'images/'.basename(__DIR)__).'/';?>">
        <img src="<?php echo 'images/'.basename(__DIR__).'/thumbnail.jpg';?>">
    </a>
</figure>

NSFW图像的card.php不同:

<figure id="<?php echo basename(__DIR__);?>" class="NSFW Horizontals">
    <a class="sfw_a" href="#">
        <img class="sfw_img_h" src="images/include/sfw_h.jpg">
    </a>
</figure>

不管怎样,当有人点击"关闭工作安全"按钮时,Javascript应该将第二个card.php更改为基本上与第一个一样。我大部分都在工作:

function worksafeOff() {
    var sfw = document.getElementsByClassName('NSFW');
    for (i = 0; i < sfw.length; i++) {
// I. Insert NSFW thumbnails and links
        sfw[i].getElementsByTagName('a')[0].href = '/images/' + sfw[i].id + '/';
        sfw[i].getElementsByTagName('img')[0].src = '/images/' + sfw[i].id + '/0x.jpg';
// II. Update Class of thumbnails and links to NSFW
        sfw[i].getElementsByClassName('sfw_a')[0].className = 'nsfw_a';
        sfw[i].getElementsByClassName('sfw_img_h')[0].className = 'nsfw_img_h';
        sfw[i].getElementsByClassName('sfw_img_v')[0].className = 'nsfw_img_v';
    }
    document.getElementById('NSFW_deactivateFilter').style.border = '1px solid red';
    document.getElementById('NSFW_deactivateFilter').innerHTML = 'Worksafe Mode: Off';
    document.getElementById('NSFW_deactivateFilter').setAttribute('onClick', 'worksafeOn()');
    document.getElementById('NSFW_deactivateFilter').id = 'NSFW_activateFilter';
}
function worksafeOn() {
    var nsfw = document.getElementsByClassName('NSFW');
    for (i = 0; i < nsfw.length; i++) {
// I. Remove NSFW thumbnails and links
        nsfw[i].getElementsByTagName('a')[0].href = '#';
        nsfw[i].getElementsByClassName('nsfw_img_h')[0].src = 'images/include/sfw_h.jpg';
        nsfw[i].getElementsByClassName('nsfw_img_v')[0].src = 'images/include/sfw_v.jpg';
// II. Update Class of thumbnails and links to SFW
        nsfw[i].getElementsByClassName('nsfw_a')[0].className = 'sfw_a';
        sfw[i].getElementsByClassName('nsfw_img_h')[0].className = 'sfw_img_h';
        sfw[i].getElementsByClassName('nsfw_img_v')[0].className = 'sfw_img_v';
    }
// III. Change "Worksafe Mode: Off" button to "Worksafe Mode: On" button
    document.getElementById('NSFW_activateFilter').style.border = '1px solid black';
    document.getElementById('NSFW_activateFilter').innerHTML = 'Worksafe Mode: On';
    document.getElementById('NSFW_activateFilter').setAttribute('onClick', 'worksafeOff()');
    document.getElementById('NSFW_activateFilter').id = 'NSFW_deactivateFilter';
}

这是主小提琴。CCD_ 1和CCD_。CCD_ 3也能很好地工作。但是尝试gEBCN[0]('img.class')失败并挂起该函数。在jsfiddle中,我注释了第9、10、22、23、26、27行,这样您就可以看到没有其他错误。

这里有一个简化的fork,您可以很容易地看到gEBCN[0]('a.class')在第8行工作,但gEBCN[0]('img.class')在第9行和/或第10行失败。

问题出在这两行:

    sfw[i].getElementsByClassName('sfw_img_h')[0].className = 'nsfw_img_h';
    sfw[i].getElementsByClassName('sfw_img_v')[0].className = 'nsfw_img_v';

有些元素中只有sfw_img_h,有些元素中只包含sfw_img_v。当您尝试设置不存在的元素的类时,会出现错误,函数将退出。您需要测试元素是否存在。

var imgs = sfw[i].getElementsByClassName('sfw_img_h');
if (imgs.length) {
    imgs[0].className = 'nsfw_img_h';
}
imgs = sfw[i].getElementsByClassName('sfw_img_v');
if (imgs.length) {
    imgs[0].className = 'nsfw_img_v';
}

如果您在控制台打开的情况下运行代码,您会看到错误消息,说您无法分配给gEBTN[0]('a')0的className属性。

尝试使用querySelector()函数。这将允许您使用element、class或id:获取元素

sfw[i].querySelector('.sfw_img_h')[0].className = 'nsfw_img_h';

为什么不在nsfw映像中添加数据nsfw-src和数据sfw-src?然后您可以使用该属性而不是id,反之亦然。

如@pabs123所建议的,使用querySelector或querySelectorAll:(未测试

var nsfw_images = document.querySelectorAll('[data-nsfw-src]');
for(var i in nsfw_images) {
    nsfw_images[i].src = nsfw_images[i].getAttribute('data-sfw-src');
}

您还可以添加NSFW和SFW映像,更改全局容器类(如document.docentElement),并使用样式来显示/隐藏正确的映像。比切换img src更容易。

.hide-nsfw img.nsfw, .show-nsfw img.sfw {display:none}