Javascript 在 class 中获取 class 失败
Javascript failing when getting a class within a class
我正在为我的摄影网站制作 "worksafe mode"(裸体 [NSFW] 默认隐藏)。
index.php 包含一系列包含:
<?php include 'images/20090820_9616/card.php';?>
<?php include 'images/20110509_1509/card.php';?>
etc..
card.php 对于所有 SFW 图像都是相同的(figure.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>
无论如何,当有人单击 "Turn Worksafe Off" 按钮时,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';
}
这是the main jsfiddle。 gEBTN[0]('a')
和 gEBTN[0]('img')
都可以正常工作。 gEBCN[0]('a.class')
也很完美。但是尝试 gEBCN[0]('img.class')
失败并挂起函数。在 jsfiddle 中,我注释掉了第 9、10、22、23、26、27 行,这样您就可以看到没有其他错误。
这里是 a simplified fork,您可以很容易地看到 gEBCN[0]('a.class')
在第 8 行工作,但 gEBCN[0]('img.class')
在第 9 行失败 and/or 10.
尝试使用 querySelector()
函数。这将允许您使用 element, class 或 id:
获取元素
sfw[i].querySelector('.sfw_img_h')[0].className = 'nsfw_img_h';
为什么不在 NSFW 图像中添加 data-nsfw-src 和 data-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 图像,更改全局容器 class(如 document.documentElement),并使用样式 show/hide 正确的图像。然后切换 img src.
更容易
.hide-nsfw img.nsfw, .show-nsfw img.sfw {display:none}
问题出在这两行:
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
。当您尝试设置不存在的元素的 class 时,您会收到错误消息并且函数退出。您需要测试元素是否存在。
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';
}
如果您 运行 在控制台打开的情况下编写代码,您会看到错误提示您无法分配给 undefined
的 className
属性 .
我正在为我的摄影网站制作 "worksafe mode"(裸体 [NSFW] 默认隐藏)。
index.php 包含一系列包含:
<?php include 'images/20090820_9616/card.php';?>
<?php include 'images/20110509_1509/card.php';?>
etc..
card.php 对于所有 SFW 图像都是相同的(figure.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>
无论如何,当有人单击 "Turn Worksafe Off" 按钮时,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';
}
这是the main jsfiddle。 gEBTN[0]('a')
和 gEBTN[0]('img')
都可以正常工作。 gEBCN[0]('a.class')
也很完美。但是尝试 gEBCN[0]('img.class')
失败并挂起函数。在 jsfiddle 中,我注释掉了第 9、10、22、23、26、27 行,这样您就可以看到没有其他错误。
这里是 a simplified fork,您可以很容易地看到 gEBCN[0]('a.class')
在第 8 行工作,但 gEBCN[0]('img.class')
在第 9 行失败 and/or 10.
尝试使用 querySelector()
函数。这将允许您使用 element, class 或 id:
sfw[i].querySelector('.sfw_img_h')[0].className = 'nsfw_img_h';
为什么不在 NSFW 图像中添加 data-nsfw-src 和 data-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 图像,更改全局容器 class(如 document.documentElement),并使用样式 show/hide 正确的图像。然后切换 img src.
更容易.hide-nsfw img.nsfw, .show-nsfw img.sfw {display:none}
问题出在这两行:
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
。当您尝试设置不存在的元素的 class 时,您会收到错误消息并且函数退出。您需要测试元素是否存在。
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';
}
如果您 运行 在控制台打开的情况下编写代码,您会看到错误提示您无法分配给 undefined
的 className
属性 .