-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathHTMLComment.tsx
More file actions
58 lines (50 loc) · 1.42 KB
/
HTMLComment.tsx
File metadata and controls
58 lines (50 loc) · 1.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import React from "react";
export interface CommentProps {
data?: string;
}
type ElementLike = {
setAttribute: () => boolean;
style: object;
};
const createElement = document.createElement;
const TagSymbol = `comment__`;
//react 内部是用这个创建节点的 由于react本身不支持创建注释节点 这里hack一下
document.createElement = function (
tagName: string,
options?: ElementCreationOptions
) {
if (
tagName === "noscript" &&
options?.is &&
options.is.startsWith(TagSymbol)
) {
const regex = new RegExp(`^${TagSymbol}(.*)$`);
const match = options?.is.match(regex);
if (match) {
const data = match[1].trim?.();
const comment = document.createComment(data) as unknown as ElementLike;
comment.setAttribute = () => true;
comment.style = {};
return comment as unknown as HTMLElement;
}
}
return createElement.call(this, tagName, options);
};
function CommentRender(
{ data = "" }: CommentProps,
ref: React.ForwardedRef<null | Comment>
) {
return (
<noscript
ref={ref as React.ForwardedRef<null | HTMLMetaElement>}
is={`${TagSymbol}${data}`}
/>
);
}
/**支持在react中生成注释节点*/
const HTMLComment = React.memo(
React.forwardRef(CommentRender),
(prevProps, next) => prevProps.data === next.data
);
HTMLComment.displayName = "Comment"; // 设置组件的 displayName,方便调试
export default HTMLComment;