找到最近的 href 属性的最佳方法?
Best way to find nearest href attribute?
为什么我不认为它是重复的。
Hmm, I think that's slightly different to what I'm asking. I don't
want to add a listener to all A tags, rather, substract an href
attribute, if any, on a click event's target.
我正在尝试 "Ajaxify" 我的整个站点,以便当用户单击页面中包含的任何 link 时,脚本会发送 "url" 或 HREF
属性(被点击的元素)添加到 Ajax 函数,该函数在 return 中呈现请求的内容(如 link 所点击的所示)。
如果元素是 link,我需要找到被单击元素的 HREF
属性。 这里的问题 是许多元素可以包含在 A 标签中(因为我构建它们的方式),并且 e.target.href
不一定总是 return 一个 HREF
属性。
这是我目前的情况:
function ajaxifyLinks(e) {
var target = e.target;
e.preventDefault();
while(!target.href) {
target = target.parentNode;
}
if(target.href) {
ajaxLoad(target.href);
}
}
document.body.addEventListener('click', ajaxifyLinks);
下面是我拥有的不同 "clickable" link 的示例:
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span>
<span> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span>
bye
</span>
</a>
如您所见,这就是为什么 e.target.href
不会总是 return HREF 属性,因为您实际上是在单击 "linked" span 元素,但是,浏览器会带你去link。为什么会这样?有什么方法可以让我从这种行为中受益吗? (例如,提取浏览器将您带到的位置,即使您没有点击 A 标签)。
我不喜欢我的解决方案,因为 while 循环一直在查找 DOM 树,有时是不必要的(当 e.target 不是 link 或包含在link).
谢谢。
新答案:
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span style="pointer-events: none;">
<span style="pointer-events: none;"> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span style="pointer-events: none;">
bye
</span>
</a>
使用 .parent()
,参考:http://api.jquery.com/parent/
例如,您可以
var hrefElem = $(target).parent('*[href]');
var link = hrefElem.attr('href');
如果单击的元素没有 href,它会在其父元素中搜索具有 href 的元素。香草 JS 解决方案。
function findUpTag(el, attr) {
while (el.parentNode) {
el = el.parentNode;
if (el[attr]) {
return el;
}
}
return null;
}
document.body.onclick = function (event) {
event.preventDefault();
var href = event.target.href;
if (!href) {
var closest = findUpTag(event.target, 'href');
if (closest) {
href = closest.href;
}
}
document.getElementById('output').innerHTML = 'element clicked: ' + event.target.nodeName + '<br>closest href: ' + href;
};
a,
output {
display: block;
}
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span>
<span> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span>
bye
</span>
</a>
<output id="output"></output>
只需将点击处理程序附加到页面上的每个 link:
function ajaxify(e)
{
e.preventDefault();
ajaxLoad(this.href);
}
[].forEach.call(document.getElementsByTagName('a'), function(el) {
el.addEventListener('click', ajaxify.bind(el));
});
查看 What is event bubbling and capturing? 以了解事件如何通过 DOM 传播。
捕获锚链接并通过Ajax加载它们的技术被称为Hijax. Because you're replacing content on the page, you can't simply set up a single event to handle all links, and you probably don't want to keep re-binding every page load, so the approach you are using is good, and is known as event delegation。
上一篇文章准确描述了您的问题(在最后),还描述了与您的类似的解决方案,这确实是这种情况下的最佳解决方案。但是,您可以考虑使用微库来简化一些事件委托;一个例子是 gator.js.
为什么我不认为它是重复的。
Hmm, I think that's slightly different to what I'm asking. I don't want to add a listener to all A tags, rather, substract an href attribute, if any, on a click event's target.
我正在尝试 "Ajaxify" 我的整个站点,以便当用户单击页面中包含的任何 link 时,脚本会发送 "url" 或 HREF
属性(被点击的元素)添加到 Ajax 函数,该函数在 return 中呈现请求的内容(如 link 所点击的所示)。
如果元素是 link,我需要找到被单击元素的 HREF
属性。 这里的问题 是许多元素可以包含在 A 标签中(因为我构建它们的方式),并且 e.target.href
不一定总是 return 一个 HREF
属性。
这是我目前的情况:
function ajaxifyLinks(e) {
var target = e.target;
e.preventDefault();
while(!target.href) {
target = target.parentNode;
}
if(target.href) {
ajaxLoad(target.href);
}
}
document.body.addEventListener('click', ajaxifyLinks);
下面是我拥有的不同 "clickable" link 的示例:
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span>
<span> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span>
bye
</span>
</a>
如您所见,这就是为什么 e.target.href
不会总是 return HREF 属性,因为您实际上是在单击 "linked" span 元素,但是,浏览器会带你去link。为什么会这样?有什么方法可以让我从这种行为中受益吗? (例如,提取浏览器将您带到的位置,即使您没有点击 A 标签)。
我不喜欢我的解决方案,因为 while 循环一直在查找 DOM 树,有时是不必要的(当 e.target 不是 link 或包含在link).
谢谢。
新答案:
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span style="pointer-events: none;">
<span style="pointer-events: none;"> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span style="pointer-events: none;">
bye
</span>
</a>
使用 .parent()
,参考:http://api.jquery.com/parent/
例如,您可以
var hrefElem = $(target).parent('*[href]');
var link = hrefElem.attr('href');
如果单击的元素没有 href,它会在其父元素中搜索具有 href 的元素。香草 JS 解决方案。
function findUpTag(el, attr) {
while (el.parentNode) {
el = el.parentNode;
if (el[attr]) {
return el;
}
}
return null;
}
document.body.onclick = function (event) {
event.preventDefault();
var href = event.target.href;
if (!href) {
var closest = findUpTag(event.target, 'href');
if (closest) {
href = closest.href;
}
}
document.getElementById('output').innerHTML = 'element clicked: ' + event.target.nodeName + '<br>closest href: ' + href;
};
a,
output {
display: block;
}
<!-- Link -->
<a href="/cats">
cats
</a>
<!-- Link -->
<a href="/hello">
<span>
<span> hi </span>
</span>
</a>
<!-- Link -->
<a href="/bye">
<span>
bye
</span>
</a>
<output id="output"></output>
只需将点击处理程序附加到页面上的每个 link:
function ajaxify(e)
{
e.preventDefault();
ajaxLoad(this.href);
}
[].forEach.call(document.getElementsByTagName('a'), function(el) {
el.addEventListener('click', ajaxify.bind(el));
});
查看 What is event bubbling and capturing? 以了解事件如何通过 DOM 传播。
捕获锚链接并通过Ajax加载它们的技术被称为Hijax. Because you're replacing content on the page, you can't simply set up a single event to handle all links, and you probably don't want to keep re-binding every page load, so the approach you are using is good, and is known as event delegation。
上一篇文章准确描述了您的问题(在最后),还描述了与您的类似的解决方案,这确实是这种情况下的最佳解决方案。但是,您可以考虑使用微库来简化一些事件委托;一个例子是 gator.js.