javascript - Mixpanel track_links 無法對動態新增的元素生效
我在使用 mixpanel.track_links 跟蹤動態添加的鏈接(頁面加載後)時遇到麻煩。
舉一個一般性的例子,給定這個頁面:
<div id="link-div"></div>
<input type="button" id="add-link" />
<script type="text/javascript">
mixpanel.track_links(".mixpanel-event", "event name", function(ele) { return { "type": $(ele).attr("type")}});
</script>
在某些使用者操作下,會使用 jquery 將連結新增到頁面上。例如:
$('#add-link).click(function() {
$('#link-div').html('<a class="mixpanel-event" type="event-type" href="#>Link to track</a>');
})
問題是 track_links 在點擊新創建的連結時不會被觸發。我希望有人能分享他們在使 track_link 函數對動態添加的連結有效方面的經驗。
答案#1
我很好奇,所以我查看了他們的程式碼,並按照他們的建議去做。我測試了它,它運作良好。不過,這需要 jQuery。
範例用法:mixpanel.delegate_links(document.body, 'a', 'clicked link');
// with jQuery and mixpanel
mixpanel.delegate_links = function (parent, selector, event_name, properties) {
properties = properties || {};
parent = parent || document.body;
parent = $(parent);
parent.on('click', selector, function (event) {
var new_tab = event.which === 2 || event.metaKey || event.target.target === '_blank';
properties.url = event.target.href;
function callback() {
if (new_tab) {
return;
}
window.location = properties.url;
}
if (!new_tab) {
event.preventDefault();
setTimeout(callback, 300);
}
mixpanel.track(event_name, properties, callback);
});
};
答案#2
我在嘗試讓追蹤連結在 React 上如預期運作時遇到了一些困難。我注意到的主要問題是重複的事件可能會以突發的方式發送到 Mixpanel。我使用了一個稍微修改過的 @Kyle 版本來解決我的問題。此外,這也考慮到 properties 可能是一個函數,這是 Mixpanel API 所支持的。
// mixpanelSetup.js
import md5 from "md5";
const setup = () => {
mixpanel.init(TOKEN);
// Sets ensure unique items
mixpanel.delegated_links = new Set();
mixpanel.delegate_links = (parent, selector, eventName, eventProperties, {ignoreUrl=false}) => {
// Hash by whatever thing(s) the use case considers 'unique' (e.g md5(`${selector}__${eventName}`))
const linkHash = md5(selector);
parent = parent || document.body;
parent = $(parent);
// Do not add additional trackers for an already tracked event.
if (mixpanel.delegated_links.has(linkHash)) {
return;
}
mixpanel.delegated_links.add(linkHash);
parent.on("click", selector, (event) => {
const newTab = event.which === 2 || event.metaKey || event.target.target === "_blank";
if (typeof eventProperties === "function") {
eventProperties = eventProperties(event.target) || {};
}
eventProperties.url = event.target.href;
// In case we don't want the url on the properties.
if (ignoreUrl) {
delete eventProperties.url;
}
const callback = () => {
if (newTab) {
return;
}
window.location = event.target.href;
};
if (!newTab) {
event.preventDefault();
setTimeout(callback, 300);
}
console.debug("Tracking link click!");
mixpanel.track(eventName, eventProperties, callback);
});
};
}
並且可以用作:
// MyComponent.jsx
import React, { useEffect } from "react";
import { Link, useLocation } from "@reach/router";
const MyComponent = ({ moduleName, key, ...props }) => {
const id = `#${id}__${moduleName}`;
useEffect(() => {
mixpanel.delegate_links(document.parent, id, event => {
return {
module: event.id.split("__").pop(),
...props.otherPropsToTrack
};
})
}, [])
return <>
<Link {...props} to="/some/path" id={id}>My Page</Link>
</>
}
