На нашем сайте есть несколько абстрактных ссылок. Мы хотим отслеживать клики по ним в сочетании с заголовком H1, чтобы иметь возможность идентифицировать блок, в котором он был нажат. Я использую Google Tagmanager. На странице больше блоков с такой же структурой, функция срабатывает при событии клика.
Два жестких требования:
По сути, это блок с заголовком и списком ссылок в нем, последний - «подробнее ...». Я хочу создать функцию, которая возвращает текст ссылки и H1 в одной строке.
Я использую триггер gtm.click и устанавливаю это значение в метке. Для большинства ссылок достаточно {{Click Text}}, но не для этой конкретной.
В конце концов, я хочу, чтобы функция вернула это:
"Подробнее .. | Название"
У меня есть «Подробнее ...», но я не могу получить заголовок из элемента H1 над ним.
https://gomakethings.com/climbing-up-and-down-the-dom-tree-with-vanilla-javascript/
Найдите .parent-column, найдите H1 в родительском столбце, получите innerText и добавьте его в {{Clicked Text}}.
<div class = "column-2 portlet-column span3" id = "sdfghjkl">
<div class = "portlet-dropzone portlet-column-content portlet-spacing portlet-column-content-only" id = "layout-column_column-2">
<div class = "portlet-boundary portlet-boundary_56_ portlet-static portlet-static-end portlet-borderless portlet-journal-content " id = "fdsadf"> <span id = "dsasdf"></span>
<div class = "portlet-borderless-container">
<div class = "portlet-body">
<div class = "journal-content-article">
<style>
span.icon img { background-repeat: no-repeat; }
</style>
<div class = "news_headline headline_news" style = "font-family: Noa LT Std;"> <img src = "dsasdfds" alt = "content" class = "icon icon_spacing">
<h1> <span class = "headline g-font-content">H1 content</span> </h1>
</div>
</div>
<div class = "entry-links"> </div>
</div>
</div>
</div>
<div class = "portlet-boundary portlet-boundary_56_ portlet-static portlet-static-end portlet-borderless portlet-journal-content " id = "content"> <span id = "content"></span>
<div class = "portlet-borderless-container">
<div class = "portlet-body">
<div class = "journal-content-article">
<div class = "news_headline">
<div class = "relatedArticles" style = "margin-top:10px;">
<table>
<tbody>
<tr>
<td style = "vertical-align: top;"> <img style = "margin-left:9px; margin-right: 8px; color:#005B82;max-width:none;" src = "content"> </td>
<td> <a href = "content" target = "_blank"> <span class = "g-font-content content-magazine-color">LINK</span> </a> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class = "news_headline">
<div class = "relatedArticles" style = "margin-top:10px;">
<table>
<tbody>
<tr>
<td style = "vertical-align: top;"> <img style = "margin-left:9px; margin-right: 8px; color:#005B82;max-width:none;" src = "content"> </td>
<td> <a href = "content" target = "_blank"> <span class = "g-font-content content-magazine-color">LINK</span> </a> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class = "news_headline">
<div class = "relatedArticles" style = "margin-top:10px;">
<table>
<tbody>
<tr>
<td style = "vertical-align: top;"> <img style = "margin-left:9px; margin-right: 8px; color:#005B82;max-width:none;" src = "content" target = "_blank"> <span class = "g-font-content content-magazine-color">Read more..</span> </a> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class = "entry-links"> </div>
</div>
</div>
</div>
</div>
</div>
Код:
function() {
labelh1 = {{Click Text}};
if ({{Click Text}} == "Read more.."){
var parentElement = getClosest(event.target, '.parent-column');
var headingInParent = parentElement.querySelector('h1');
var labelh1 = {{Click Text}} + " | " + headingInParent.textContent
var getClosest = function ( elem, selector ) {
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
// Get closest match
for ( ; elem && elem !== document; elem = elem.parentNode ) {
if ( elem.matches( selector ) ) return elem;
}
return null;
};
return labelh1;
}
Вы хотите активировать эту функцию при нажатии Read more...ссылка на сайт?
Да, когда нажимается дополнительная информация
Ближайший - jQuery @Pete, теперь я вижу в вашей ссылке, что он поддерживается Mozilla. Я разберусь, кажется, лучшее решение
прочтите ссылку @Bastiaan, которая не является jquery, и есть полифилл для ie



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Запустите приведенный ниже фрагмент и нажмите «Подробнее ...»
var readMoreAnchors = contains('span', /^Read\smore/i);
for(var i = 0; i < readMoreAnchors.length; ++i) {
var readMoreAnchor = readMoreAnchors[i];
addEvent('click', readMoreAnchor, function(event) {
var parentElement = getClosest(event.target, '.portlet-dropzone');
var headingInParent = parentElement.querySelector('h1');
console.info("{{Click Text}}" + " | " + headingInParent.textContent);
});
}
/**
* Get the closest matching element up the DOM tree.
* @private
* @param {Element} elem Starting element
* @param {String} selector Selector to match against
* @return {Boolean|Element} Returns null if not match found
*/
var getClosest = function ( elem, selector ) {
// Element.matches() polyfill
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
// Get closest match
for ( ; elem && elem !== document; elem = elem.parentNode ) {
if ( elem.matches( selector ) ) return elem;
}
return null;
};
function addEvent(evnt, elem, func) {
if (elem.addEventListener) // W3C DOM
elem.addEventListener(evnt,func,false);
else if (elem.attachEvent) { // IE DOM
elem.attachEvent("on"+evnt, func);
}
else { // No much to do
elem[evnt] = func;
}
}
function contains(selector, text) {
var elements = document.querySelectorAll(selector);
return Array.prototype.filter.call(elements, function(element){
return RegExp(text).test(element.textContent);
});
}<div class = "column-2 portlet-column span3" id = "sdfghjkl">
<div class = "portlet-dropzone portlet-column-content portlet-spacing portlet-column-content-only" id = "layout-column_column-2">
<div class = "portlet-boundary portlet-boundary_56_ portlet-static portlet-static-end portlet-borderless portlet-journal-content " id = "fdsadf"> <span id = "dsasdf"></span>
<div class = "portlet-borderless-container">
<div class = "portlet-body">
<div class = "journal-content-article">
<style>
span.icon img { background-repeat: no-repeat; }
</style>
<div class = "news_headline headline_news" style = "font-family: Noa LT Std;"> <img src = "dsasdfds" alt = "content" class = "icon icon_spacing">
<h1> <span class = "headline g-font-content">H1 content</span> </h1>
</div>
</div>
<div class = "entry-links"> </div>
</div>
</div>
</div>
<div class = "portlet-boundary portlet-boundary_56_ portlet-static portlet-static-end portlet-borderless portlet-journal-content " id = "content"> <span id = "span-content"></span>
<div class = "portlet-borderless-container">
<div class = "portlet-body">
<div class = "journal-content-article">
<div class = "news_headline">
<div class = "relatedArticles" style = "margin-top:10px;">
<table>
<tbody>
<tr>
<td style = "vertical-align: top;"> <img style = "margin-left:9px; margin-right: 8px; color:#005B82;max-width:none;" src = "https://marketplace.cdn.mozilla.net/img/uploads/addon_icons/508/508664-64.png?modified=cdda3e8d"> </td>
<td> <a href = "content" target = "_blank"> <span class = "g-font-content content-magazine-color">LINK</span> </a> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class = "news_headline">
<div class = "relatedArticles" style = "margin-top:10px;">
<table>
<tbody>
<tr>
<td style = "vertical-align: top;"> <img style = "margin-left:9px; margin-right: 8px; color:#005B82;max-width:none;" src = "https://marketplace.cdn.mozilla.net/img/uploads/addon_icons/508/508664-64.png?modified=cdda3e8d"> </td>
<td> <a href = "content" target = "_blank"> <span class = "g-font-content content-magazine-color">LINK</span> </a> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class = "news_headline">
<div class = "relatedArticles" style = "margin-top:10px;">
<table>
<tbody>
<tr>
<td style = "vertical-align: top;"> <img style = "margin-left:9px; margin-right: 8px; color:#005B82;max-width:none;" src = "https://marketplace.cdn.mozilla.net/img/uploads/addon_icons/508/508664-64.png?modified=cdda3e8d" target = "_blank"> <a><span class = "g-font-content content-magazine-color">Read more..</span> </a> </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class = "entry-links"> </div>
</div>
</div>
</div>
</div>
</div>
</div>Привет, Абдул, спасибо за помощь! Я думаю, что мне не совсем понятно, я использую Google tagmanager, намерение состоит в том, чтобы создать переменную с этой функцией. Переменная уже связана с событием щелчка на кнопке «Читать дальше».
Пытался заставить его работать с этими: var parentElement = getClosest (event.target, '.parent-column'); var headingInParent = parentElement.querySelector ('h1'); console.info (event.target.textContent + "|" + headingInParent.textContent); В сочетании с функцией getClosest, но я не могу заставить ее работать
«Переменная уже связана с событием щелчка по кнопке« Читать дальше »». Я не понял, что ты имеешь в виду?
Я намерен создать пользовательскую переменную в Google Tagmanager, которая будет возвращать это значение. support.google.com/tagmanager/answer/6106899?hl=en
Вы хотите создать в этом URL-адресе веб-переменную Пользовательский JavaScript? По коду function () { return {{url}}.toLowerCase(); }.
Да! Пользовательская переменная Javascript. Поэтому мне нужно что-то вроде этого: function () {var parentElement = getClosest (event.target, '.parent-column'); var headingInParent = parentElement.querySelector ('h1'); var labelh1 = {{Click Text}} + "|" + headingInParent.textContent <код для getClosestfunction> return labelh1; }
Но он должен быть прикреплен к ссылке как обработчик событий, поэтому не может быть вызван независимо. Потому что переменная event будет доступна только тогда, когда она будет вызвана как обработчик событий по щелчку. о чем ты думаешь?
Я думаю, что в вашем случае, если вы хотите установить переменную для Диспетчера тегов Google для события DOM, вы можете использовать Уровень данных. ?
Я настроил настраиваемое событие gtm.click, которое запускается при нажатии на ссылки. Он запускает событие (тип отслеживания) с котом, действием и меткой. В ярлыке я установил {{Click Text}}. Все это работает. Теперь я хочу, чтобы H1 был прикреплен к {{Click Text}}, так как на странице есть несколько кнопок "Подробнее ...".
event, который он запускает, можете ли вы подтвердить, что у него есть свойство target, которое является ссылкой на выбранный тег a? Так что мы уверены, что getClosest(event.target, '.parent-column') применим в данном случае.
<td> <a href = "/url" target = "_blank"> <span class = "g-font-fancy nice-color"> Подробнее .. </span> </a> </td> Итак Может быть, он срабатывает на элементе <span>, который вызывает проблему? он срабатывает при клике Element = [object HTMLSpanElement]
Разметка в вашем вопросе, a находится внутри span. Теперь это изменилось?
Отредактировал код на оригинальный, я действительно подумал, что для этого примера это не имеет значения. (Спасибо за ваши усилия, действительно признательны)
Я отредактировал свой ответ. Посмотрите, работает ли это. Запустите обрезанный и нажмите Читать далее.... Обратите внимание, что я изменил a на span, а родительский - на .portlet-dropzone (первый непосредственный общий родитель ссылка на сайт и h1).
Все еще работаю над этим, могу зарегистрировать значение сейчас, но, похоже, в моем случае есть проблема с областью действия. Я дам вам знать, когда он у меня заработает.
Это была проблема времени, функция была выполнена без DOM!
Хм. Вы починили это?
У меня есть рабочее решение, но я предпочитаю лучшее. Теперь я попытаюсь включить часть слушателя событий в состоянии готовности и получить значение в Click.
Ок, отлично. Дай мне знать, если тебе понадобится помощь.
Возможно, добавьте уже протестированный вами Javascript, чтобы у нас был рабочий фрагмент.