使用 jQuery 定位 DOM 中的评论?
Use jQuery to Target Comments in the DOM?
我正在编写一个修改 Facebook 的浏览器扩展,运行 遇到了麻烦。 Facebook 使用 HTML 评论作为标记,例如:
<a class="UFILikeLink">
<!-- react-text: 9 -->
Like
<! -- /react-text -->
</a>
我想要的是一种更改上面示例中的文本 "Like" 的方法。但是,如果我使用类似的东西:
$('.UFILikeLink').html("<!-- react-text: 9 -->Like<!-- /react-text -->");
它破坏了后续操作的对象功能。换句话说,我很确定他的意思是某些操作绑定到现有的 HTML 那里(通过 Facebook),而不是我在其位置写的 HTML 的一部分。
有什么方法可以使用 jQuery 来定位 <!-- react-text -->
和 <-- /react-text -->
之间的文本吗?以类似于 text()
更改文本的方式?这样我就不必为 a
标签覆盖 HTML。
也许对这个问题有帮助的是 a
内部的整体结构。在 Chrome devtools 中查看时,它看起来更像这样:
<a class="UFILikeLink">
::before
<!-- react-text: 9 -->
"Like"
<! -- /react-text -->
::after
</a>
当我使用 HTML 替换 HTML 时:
$('.UFILikeLink').html($('.UFILikeLink').html());
::before
和 ::after
结构在那里仍然可见(它在开发工具中看起来相同)。但就 Facebook 而言,功能已损坏。
要更改文本以尽量减少对周围评论和非标准事件处理程序的干扰,您需要仅针对特定的 HTML Text 节点。
jQuery 不能很好地处理文本节点,但您可以扩展 jQuery 以适应 Facebook 的非标准标记。这可能是一个温和的 PITA,具体取决于您需要参与的程度,但这是一个入门 jQuery 扩展:
jQuery.fn.extend ( {
changeTextJustAfterCommentTag: function (commentTag, newText) {
return this.each (function () {
//--- process child nodes. No recursion for now.
for (var J = 0, L = this.childNodes.length - 1; J < L; J++) {
var chldNd = this.childNodes[J];
if (chldNd.nodeType === Node.COMMENT_NODE && chldNd.nodeValue.indexOf (commentTag) !== -1) {
var targText = this.childNodes[ J + 1 ];
if (targText.nodeType === Node.TEXT_NODE) {
targText.nodeValue = newText;
}
break;
}
}
} );
}
} );
你会像这样使用它:
$('.UFILikeLink').changeTextJustAfterCommentTag ("react-text: 9", "My new like");
显示并运行此代码片段进行现场演示:
jQuery.fn.extend ( {
changeTextJustAfterCommentTag: function (commentTag, newText) {
return this.each (function () {
//--- process child nodes. No recursion for now.
for (var J = 0, L = this.childNodes.length - 1; J < L; J++) {
var chldNd = this.childNodes[J];
if (chldNd.nodeType === Node.COMMENT_NODE && chldNd.nodeValue.indexOf (commentTag) !== -1) {
var targText = this.childNodes[ J + 1 ];
if (targText.nodeType === Node.TEXT_NODE) {
targText.nodeValue = newText;
}
break;
}
}
} );
}
} );
//--- Simulated Facebook code:
$(".UFILikeLink")[0].firstChild.facebook = "megaFubar";
$(".UFILikeLink").click ( function (zEvent) {
zEvent.preventDefault ();
zEvent.stopImmediatePropagation ();
if (this.firstChild.facebook) {
$("body").append ('<span>You like!</span> ');
}
} );
//--- Simulate userscript:
$("#normRewrite").click ( function (zEvent) {
$('.UFILikeLink').html ("<!-- react-text: 9 -->Oops!<!-- /react-text -->");
} );
$("#textRewrite").click ( function (zEvent) {
$('.UFILikeLink').changeTextJustAfterCommentTag ("react-text: 9", "My new like");
} );
body {width: 96%;}
body > span {
margin-right: 2em;
white-space: nowrap;
}
.UFILikeLink {
background: buttonface;
border: 3px outset black;
cursor: pointer;
display: inline-block;
padding: 1ex 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p>Click the "Like" link, see the action. Then use the rewrite buttons and see if click still works.
</p>
<p><button id="textRewrite">Special text rewrite</button> <button id="normRewrite">Normal (destructive) rewrite</button>
</p>
<p><a class="UFILikeLink">
<!-- react-text: 9 -->
Like
<! -- /react-text -->
</a></p>
<hr>
我正在编写一个修改 Facebook 的浏览器扩展,运行 遇到了麻烦。 Facebook 使用 HTML 评论作为标记,例如:
<a class="UFILikeLink">
<!-- react-text: 9 -->
Like
<! -- /react-text -->
</a>
我想要的是一种更改上面示例中的文本 "Like" 的方法。但是,如果我使用类似的东西:
$('.UFILikeLink').html("<!-- react-text: 9 -->Like<!-- /react-text -->");
它破坏了后续操作的对象功能。换句话说,我很确定他的意思是某些操作绑定到现有的 HTML 那里(通过 Facebook),而不是我在其位置写的 HTML 的一部分。
有什么方法可以使用 jQuery 来定位 <!-- react-text -->
和 <-- /react-text -->
之间的文本吗?以类似于 text()
更改文本的方式?这样我就不必为 a
标签覆盖 HTML。
也许对这个问题有帮助的是 a
内部的整体结构。在 Chrome devtools 中查看时,它看起来更像这样:
<a class="UFILikeLink">
::before
<!-- react-text: 9 -->
"Like"
<! -- /react-text -->
::after
</a>
当我使用 HTML 替换 HTML 时:
$('.UFILikeLink').html($('.UFILikeLink').html());
::before
和 ::after
结构在那里仍然可见(它在开发工具中看起来相同)。但就 Facebook 而言,功能已损坏。
要更改文本以尽量减少对周围评论和非标准事件处理程序的干扰,您需要仅针对特定的 HTML Text 节点。
jQuery 不能很好地处理文本节点,但您可以扩展 jQuery 以适应 Facebook 的非标准标记。这可能是一个温和的 PITA,具体取决于您需要参与的程度,但这是一个入门 jQuery 扩展:
jQuery.fn.extend ( {
changeTextJustAfterCommentTag: function (commentTag, newText) {
return this.each (function () {
//--- process child nodes. No recursion for now.
for (var J = 0, L = this.childNodes.length - 1; J < L; J++) {
var chldNd = this.childNodes[J];
if (chldNd.nodeType === Node.COMMENT_NODE && chldNd.nodeValue.indexOf (commentTag) !== -1) {
var targText = this.childNodes[ J + 1 ];
if (targText.nodeType === Node.TEXT_NODE) {
targText.nodeValue = newText;
}
break;
}
}
} );
}
} );
你会像这样使用它:
$('.UFILikeLink').changeTextJustAfterCommentTag ("react-text: 9", "My new like");
显示并运行此代码片段进行现场演示:
jQuery.fn.extend ( {
changeTextJustAfterCommentTag: function (commentTag, newText) {
return this.each (function () {
//--- process child nodes. No recursion for now.
for (var J = 0, L = this.childNodes.length - 1; J < L; J++) {
var chldNd = this.childNodes[J];
if (chldNd.nodeType === Node.COMMENT_NODE && chldNd.nodeValue.indexOf (commentTag) !== -1) {
var targText = this.childNodes[ J + 1 ];
if (targText.nodeType === Node.TEXT_NODE) {
targText.nodeValue = newText;
}
break;
}
}
} );
}
} );
//--- Simulated Facebook code:
$(".UFILikeLink")[0].firstChild.facebook = "megaFubar";
$(".UFILikeLink").click ( function (zEvent) {
zEvent.preventDefault ();
zEvent.stopImmediatePropagation ();
if (this.firstChild.facebook) {
$("body").append ('<span>You like!</span> ');
}
} );
//--- Simulate userscript:
$("#normRewrite").click ( function (zEvent) {
$('.UFILikeLink').html ("<!-- react-text: 9 -->Oops!<!-- /react-text -->");
} );
$("#textRewrite").click ( function (zEvent) {
$('.UFILikeLink').changeTextJustAfterCommentTag ("react-text: 9", "My new like");
} );
body {width: 96%;}
body > span {
margin-right: 2em;
white-space: nowrap;
}
.UFILikeLink {
background: buttonface;
border: 3px outset black;
cursor: pointer;
display: inline-block;
padding: 1ex 2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<p>Click the "Like" link, see the action. Then use the rewrite buttons and see if click still works.
</p>
<p><button id="textRewrite">Special text rewrite</button> <button id="normRewrite">Normal (destructive) rewrite</button>
</p>
<p><a class="UFILikeLink">
<!-- react-text: 9 -->
Like
<! -- /react-text -->
</a></p>
<hr>