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();
};
Run Code Online (Sandbox Code Playgroud)
如您所见,我的代码中有一部分是这样的:
this.parentNode.parentNode.parentNode.parentNode;
Run Code Online (Sandbox Code Playgroud)
有没有其他方法来优化代码(不使用jQuery)?
han*_*aad 32
您可以使用非递归辅助函数,例如:
function nthParent(element, n) {
while(n-- && element)
element = element.parentNode;
return element;
}
Run Code Online (Sandbox Code Playgroud)
mad*_*ox2 27
您可以使用递归辅助函数,例如:
function getNthParent(elem, n) {
return n === 0 ? elem : getNthParent(elem.parentNode, n - 1);
}
var child = getNthParent(someElement, 4);
Run Code Online (Sandbox Code Playgroud)
根据您对原始问题的评论,您的总体目标是:
有一个博客列表.每个博客都有一个像"编辑"和"删除"的按钮.当我点击这样的按钮时,我想找到它的博客元素.
我相信解决您遇到的问题的最佳方法(而不是回答您提出的问题 - 抱歉!)是以不同的方式解决问题.
根据你的评论,你说你有这样的事情:
<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>
Run Code Online (Sandbox Code Playgroud)
您的目标是为每个项目click的button元素添加事件处理程序blog-link.
所以,让我们将这个目标从简单的英语翻译成伪代码:
for each `blog-link` `b`
delete_button.onclick = delete_handler(`b`);
edit_button.onclick = edit_handler(`b`);
Run Code Online (Sandbox Code Playgroud)
工作示例: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>
Run Code Online (Sandbox Code Playgroud)
您选择实施解决方案的方式是有效的,但我认为我会给您一个不同的方式来查看同一个问题.
在我看来,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);
}
});
Run Code Online (Sandbox Code Playgroud)
对于数组中的每个deleteButton元素,我们为事件处理程序分配一个匿名函数onclick.创建这个匿名函数允许我们创建一个闭包.
这意味着每个deleteButton.onclick函数将单独"记住" blogitem它所属的属性.
查看关于闭包的SO问题/答案了解更多信息:JavaScript闭包如何工作?
我们抛出HTMLCollection.prototype.forEach...一行来为forEach所有HTMLCollection对象提供功能.函数如getElementsByClassName返回一个HTMLCollection对象.它在大多数情况下的行为与数组完全相同,但forEach默认情况下它不允许我们使用它.关于兼容性的注意事项:您当然可以使用标准for循环,因为forEach并非所有浏览器都可用(大多数旧版IE浏览器都应该受到指责).我更喜欢这个forEach成语.
最终结果是代码稍微长一点,因为问题的范围比您实际提出的问题要宽一些.优点是此代码更灵活,并且不会被HTML结构的更改破坏.
| 归档时间: |
|
| 查看次数: |
4929 次 |
| 最近记录: |