我想“管理”div中的第一个h2元素,只要它真的是“第一个元素”
<div id="test">
<h2>Try 1</h2>
Test Test Test
<h2>Try 2</h2>
</div>
此处只有文字“尝试1”的h2必须管理
<div id="test">
Test Test Test
<h2>Try 1</h2>
<h2>Try 2</h2>
</div>
这里没有(之前有文字)。
我如何使用jQuery做到这一点?
答案 0 :(得分:4)
不需要jquery,只需:
document.getElementById('test').firstChild.nodeName // gives the name of the node
这将为您提供第一个节点的名称,即使它不是标签而只是纯文本节点!
如果您希望更灵活地使用选择器并且知道大多数客户端浏览器都支持它,那么您当然可以使用document.querySelector()
。
要明确:如果添加换行符,也会将其视为文本节点,因此标题需要从同一行开始,否则两个示例都会得到#text
!< / p>
这将失败:
<div id="test">
<h2>Try 1</h2>
Test Test Test
<h2>Try 2</h2>
</div>
这将有效:
<div id="test"><h2>Try 1</h2>
Test Test Test
<h2>Try 2</h2>
</div>
答案 1 :(得分:2)
我们在这里面临的挑战是javascript也将空白识别为文本节点。因此,从javascript的角度来看,这个HTML:
<div id="test">
<h2>Try 1</h2>
Test Test Test
<h2>Try 2</h2>
</div>
与此HTML不同:
<div id="test"><h2>Try 1</h2>
Test Test Test
<h2>Try 2</h2>
</div>
在第一种情况下,div
内的第一个节点是textNode(nodeType == 3
)
在第二个HTML示例中,div
内的第一个节点是h2
节点。
我已经为此提出了一个解决方案,这是一个方便的函数,它循环结合了jQuery和本机javascript的所有元素。
var objNodes = $(".wrapper").contents().get();
function loopNodes(objNodes, i) {
i = (typeof i === "undefined") ? 0 : i;
if (objNodes[i].nodeType !== 3) {
return {"isHeader":true, "first":$(objNodes[i])};
} else {
var strText = objNodes[i].innerText || objNodes[i].textContent;
if ($.trim(strText).length === 0) {
return loopNodes(objNodes, i+1);
} else {
return {"isHeader":false, "first":null};
}
}
}
var objResults = loopNodes(objNodes);
if (objResults.isHeader) {
console.log("Coolness");
objResults.first.text("AWESOME FIRST HEADER!");
} else {
console.log("Less Coolness");
}
行动中: http://jsbin.com/welcome/61883/edit
编辑:添加了获取innerText / textContent的跨浏览器方式。有关此事,请参阅Quirksmode以获取完整参考。
答案 2 :(得分:2)
我觉得我发现自己是solution,有点滑稽:
if($.trim($('#test').html()).substr(0,4).toLowerCase() == "<h2>")
{
$('#test h2:first').css('background-color', 'red');
}
你怎么看? :)
答案 3 :(得分:2)
您可以使用.contents
有条件地忽略仅为空白文本的前导节点。然后查看第一个节点是<h2>
(Fiddle):
function isFirstChildH2(selector) {
// get th efirst node, which may be a text node
var firstNode = $(selector).contents().first();
// if the first node is all whitespace text, ignore it and go to the next
if(firstNode[0].nodeType == 3 && firstNode.text().match(/\S/g) == null) {
firstNode = firstNode.next();
}
if(firstNode.is("h2")) {
// it's an h2; do your magic!
alert("h2 is the first thing on " + selector)
} else {
// first node is either non-whitespace text or an non-h2 element
// don't do your magic
alert("h2 is NOT the first thing on " + selector)
}
}
isFirstElementH2("#test");
答案 4 :(得分:2)
这是过滤器只能获取第一个节点的标头,忽略所有空白文本节点的方法: -
$("#test").children("h2").first().filter(function() {
var childNodes = this.parentNode.childNodes;
var i = 0;
var textNode = 3;
// No children
if(!childNodes.length) {
return false;
}
// Skip blank text node
if(childNodes[i].nodeType === textNode && childNodes[i].textContent.trim().length === 0) {
i ++;
}
// Check we have a match
return childNodes[i] === this;
});
答案 5 :(得分:1)
好的,让我们将一些jQuery与普通的DOM代码混合在一起(因为jQuery无法处理text nodes):
var $el = $("#test > h2:first-child");
if (!$el.length) return false;
var el = $el.get(0),
reg = /\S/; // no whitespace
for (var prev = el; prev = prev.previousSibling; )
if (prev.nodeType == 3 && reg.test(prev.data))
return false;
return el;