最近做了一些和MutationObserver相关的东西,然后今天把这些相关的东西分享一下。
MutationObserver是一个突变观察者,可以监控目标节点的改变(增加删除节点,改变属性, 改变文本等),一般都是通过JS来使用。
但使用js,显然不如直接在webkit中进行观测效率高。通过在webkit中添加观察者以来可以提高效率,二来可以熟悉下相关的代码。
MutationObserver.cpp
具体观测类型可以通过如下来设置:
55 enum MutationType {
56 ChildList = 1 << 0,
57 Attributes = 1 << 1,
58 CharacterData = 1 << 2,
59
60 AllMutationTypes = ChildList | Attributes | CharacterData
61 };
62
63 enum ObservationFlags {
64 Subtree = 1 << 3,
65 AttributeFilter = 1 << 4
66 };
67
68 enum DeliveryFlags {
69 AttributeOldValue = 1 << 5,
70 CharacterDataOldValue = 1 << 6,
71 };
如 MutationObserverOptions oprtions = ChildList | SubTree;
在定义MutationObserver时, 显然需要事先定义一个MutationCallback
MutationCallback是一个虚类,需要自己实现类中的函数。
贴一下自己的
19 class RMMutationCallback : public MutationCallback {
20 public:
21 explicit RMMutationCallback(Document*, const base::Callback<void(void)>&);
22 virtual ~RMMutationCallback();
23
24 virtual void call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*);
25 virtual ExecutionContext* executionContext() const;
26
27 void startTimerForRecheckRM();
28 void timerFired(Timer<RMMutationCallback>* timer);
29 private:
30 Document* m_document;
31 Timer<RMMutationCallback> m_timer;
32 base::Callback<void()> m_reCheckRMCallback;
33 };
其中的m_timer可以忽略,这是为了实现一些特殊的功能。具体就不说了,^_^。
然后就可以来定义自己的Observer了,我还是觉的应该自己定制一个observer, 有一个MutationObserver类型的成员,需要观察时,如
195 m_options = 0;
196 m_options |= MutationObserver::ChildList;
197 m_options |= MutationObserver::Attribute;
198 m_options |= MutationObserver::CharacterData;
199 m_attributeFilter.add("style");
Node* targetNode = getTargetNode();
targetNode->registerMutationObserver(m_mutationObserverForRM.get(), m_options, m_attributeFilter);
下面看一下
RMMutationCallback::call(const Vector<RefPtr<MutationRecord> >&, MutationObserver*) {
}
MutationRecord 包括三种类型: ChildListRecord, AttributesRecord, CharacterDataRecord
分别对应 MutationObserver::ChildList, MutationObserver::Attribute, MutationObserver::CharacterData
具体类型通过 AtomicString MutationRecord::type()可以得到。
里边还有 NodeLists* addedNodes(); NodeLists* removedNodes();等
当然还有其他的公有接口可使用:
如下是MutationObserver的一些公有接口:(当然ChildListRecord,AttributesRecord,CharacterDataRecord都实现了相应的函数)
59 virtual const AtomicString& type() = 0;
60 virtual Node* target() = 0;
61
62 virtual NodeList* addedNodes() = 0;
63 virtual NodeList* removedNodes() = 0;
64 virtual Node* previousSibling() { return 0; }
65 virtual Node* nextSibling() { return 0; }
66
67 virtual const AtomicString& attributeName() { return nullAtom; }
68 virtual const AtomicString& attributeNamespace() { return nullAtom; }
69
70 virtual String oldValue() { return String(); }