var topClick = function() {
child = this.parentNode.parentNode.parentNode.parentNode;
child.parentNode.removeChild(child);
var theFirstChild = document.querySelector(".m-ctt .slt");
data[child.getAttribute("data-id")].rank = 5;
insertBlogs();
};
如您所见,我的代码中有一部分是这样的:
this.parentNode.parentNode.parentNode.parentNode;
是否有另一种优化代码的方法(不使用jQuery)?
答案 0 :(得分:33)
您可以使用非递归辅助函数,例如:
ckim@stph45:~/test/rtn5_fpga] make clean
at Makefile.inc RTEMS_API = @RTEMS_API@
rm -f a.out core mon.out gmon.out
rm -f -r
rm -f -r a.out *.o *.BAK Depends-o-optimize.tmp
rm -f -r o-optimize o-debug
rm -f -r o-optimize
rm -f init.c system.h config.h
ckim@stph45:~/prj/abts/rtems-qt/applications/sieve/rtn5_fpga] make
at Makefile.inc RTEMS_API = @RTEMS_API@
test -d o-optimize || mkdir o-optimize
ln -s ../src/init.c init.c
sparc-ab-rtems-gcc --pipe -B/some/dir/path/lib/ -specs bsp_specs -qrtems -Wall -I../../include -qnolinkcmds -T ../../lib/linkcmds.abtn5 -O4 -mtune=v8 -msoft-float -fcommon -DTARGET_ALDEBARAN -c -o o-optimize/init.o init.c
init.c:15:20: fatal error: system.h: No such file or directory
#include "system.h"
^
compilation terminated.
make: *** [o-optimize/init.o] Error 1
答案 1 :(得分:26)
您可以使用递归辅助函数,例如:
function getNthParent(elem, n) {
return n === 0 ? elem : getNthParent(elem.parentNode, n - 1);
}
var child = getNthParent(someElement, 4);
答案 2 :(得分:8)
根据您对原始问题的评论,您的总体目标是:
有一个博客列表。每个博客都有一个像“编辑”和“删除”的按钮。当我点击这样的按钮时,我想找到它的博客元素。
我认为解决您遇到的问题的最佳方法(而不是回答您提出的问题 - 抱歉!)是以不同的方式解决问题。
根据你的评论,你说你有这样的事情:
<ul id="blog-list">
<li class="blog-item">
<a href="blog1.com">
Boats galore!
</a>
<span class="blog-description">
This is a blog about some of the best boats from Instagram.
</span>
<span class="blog-button delete-button">
Delete
</span>
<span class="blog-button edit-button">
Edit
</span>
</li>
<li class="blog-item">
<a href="blog2.com">
Goats galore!
</a>
<span class="blog-description">
A blog about the everyday adventures of goats in South Africa.
</span>
<span class="blog-button delete-button">
Delete
</span>
<span class="blog-button edit-button">
Edit
</span>
</li>
<li class="blog-item">
<a class="blog-link" href="blog3.com">
Totes galore!
</a>
<span class="blog-description">
A blog about containers and bags, and the owners who love them.
</span>
<span class="blog-button delete-button">
Delete
</span>
<span class="blog-button edit-button">
Edit
</span>
</li>
</ul>
您的目标是为每个click
项目的button
元素添加blog-link
个事件处理程序。
所以,让我们将这个目标从普通英语翻译成伪代码:
for each `blog-link` `b`
delete_button.onclick = delete_handler(`b`);
edit_button.onclick = edit_handler(`b`);
工作示例:http://jsfiddle.net/vbt6bjwy/10/
<script>
function deleteClickHandler(event, parent) {
event.stopPropagation();
parent.remove();
}
function editClickHandler(event, parent) {
event.stopPropagation();
var description = parent.getElementsByClassName("blog-description")[0];
description.innerHTML = prompt("Enter a new description:");
}
function addClickHandlers() {
var bloglistElement = document.getElementById("blog-list");
var blogitems = bloglistElement.getElementsByClassName("blog-item");
blogitems.forEach(function(blogitem){
var deleteButtons = blogitem.getElementsByClassName("delete-button");
deleteButtons.forEach(function(deleteButton){
deleteButton.onclick = function(event) {
return deleteClickHandler(event, blogitem);
}
});
var editButtons = blogitem.getElementsByClassName("edit-button");
editButtons.forEach(function(editButton){
editButton.onclick = function(event) {
return editClickHandler(event, blogitem);
}
});
});
}
HTMLCollection.prototype.forEach = Array.prototype.forEach;
addClickHandlers();
</script>
您选择实施解决方案的方式是有效的,但我认为我会给您一个不同的方式来查看相同的问题。
在我看来,blog
实体的内部标记不应该知道周围HTML的结构或属性,以便edit
和delete
按钮起作用。
您的原始解决方案必须从父项链上的每个button
向后工作,直到它找到它假设的正确父元素为基础,基于像硬编码向上移动的脆弱方法N
父元素链中的时间。如果我们能够使用普通的JavaScript元素选择来绝对确定我们选择的内容,那会不会更好?这样,无论HTML结构如何变化,只要类和ID保持一致,我们的JavaScript就不会破坏。
此解决方案迭代blog-item
元素中的每个#blog-list
:
blogitems.forEach(function(blogitem){ ... });
在forEach
循环中,我们抓取包含.delete-button
和.edit-button
元素的数组。在每个元素上,我们将适当的事件处理程序添加到onclick
属性:
deleteButtons.forEach(function(deleteButton){
deleteButton.onclick = function(event) {
return deleteClickHandler(event, blogitem);
}
});
对于数组中的每个deleteButton元素,我们为事件处理程序onclick
分配一个匿名函数。创建这个匿名函数允许我们创建一个闭包。
这意味着每个deleteButton.onclick
函数都会单独“记住”它所属的blogitem
。
查看有关闭包的SO问题/答案以获取更多信息:How do JavaScript closures work?
我们引入HTMLCollection.prototype.forEach...
行,为所有forEach
个对象提供HTMLCollection
功能。像getElementsByClassName
这样的函数会返回HTMLCollection
个对象。它在大多数情况下的行为与数组完全相同,但默认情况下它不允许我们使用forEach
。关于兼容性的注意事项:您当然可以使用标准的for
循环,因为forEach
并非在所有浏览器中都可用(主要是旧版IE浏览器)。我更喜欢forEach
成语。
最终结果是代码稍微长一些,因为问题的范围比实际问题要宽一些。优点是此代码更灵活,并且不会被HTML结构的更改破坏。
答案 3 :(得分:2)
var topClick = function(event){
console.log(event);
child = this.parentNode.parentNode.parentNode.parentNode;
child.parentNode.removeChild(child);
var theFirstChild = document.querySelector(".m-ctt .slt");
data[child.getAttribute("data-id")].rank = 5;
insertBlogs();
};
惊喜!我通过console.log打印事件。 并在事件中找到这样的数组:
我找到了我想要的元素:
function(event){
console.log(event.path[4]);
child = event.path[4];
}
它有效!多么神奇!也许事件代理是另一种方式! 谢谢大家的回答! 下次问问题之前,我会先考虑一下! :d