We have a nav menu that has banners on the category flyouts. I'm trying to setup a rule in Data Collection to report these page event views to Analytics.
I have a data element for these menu banners of core. Constant and the constant value is %event.element.innerText%
I have an action that says "When it hovers" after a 3,000millisecond delay, for elelments matching a.sub-menu-link... then set the value of the constant to an evar.
The problem that I have is... It will trigger when you hover the menu, except it only will report the very first "inner text" in the menu and not the menu item that is hovered over.
I'm curious if anyone has suggestions on how to adjust this. Here is a anonymized sample what our menu html looks like.
Or even better to configure my data element so it will report the banner path?
<ul class="dropdown-menu browse-products OneCol">
<li class="menu-link">
<a class="sub-menu-link" href="javascript:void(0)">Category 1<i class="fa fa-chevron-right"></i></a>
<div class="flyout-submenu container">
<div class="row">
<div class="col-xs-6">
<ul class="dropdown-menu sub-menu">
<li class="flyout-link">
<a href="#">Subcategory 1a</a>
</li>
<li class="flyout-link">
<a href="#">Subcategory 2a</a>
</li>
<li class="flyout-link">
<a href="#">Subcategory 3a</a>
</li>
</ul>
</div>
</div>
<div class="row flyout-note-row">
<div class="col-xs-12"><div> <a target="_blank" href="#">
<img src="/media/img/web/2024/BannerForCat1.jpg" alt="Name of ad" data-vendorname="vendor" data-pagename="Category 1" data-activitytype="Menu Banner" border="0"> </a> </div></div>
</div>
</div>
</li>
<li class="menu-link">
<a class="sub-menu-link" href="javascript:void(0)">Category 2<i class="fa fa-chevron-right"></i></a>
<div class="flyout-submenu container">
<div class="row">
<div class="col-xs-6">
<ul class="dropdown-menu sub-menu">
<li class="flyout-link">
<a href="#">Subcategory 1b</a>
</li>
<li class="flyout-link">
<a href="#">Subcategory 2b</a>
</li>
<li class="flyout-link">
<a href="#">Subcategory 3b</a>
</li>
</ul>
</div>
</div>
<div class="row flyout-note-row">
<div class="col-xs-12"><div> <a target="_blank" href="#">
<img src="/media/img/web/2024/BannerForCat2.jpg" alt="Name of ad" data-vendorname="vendor" data-pagename="Category 2" data-activitytype="Menu Banner" border="0"> </a> </div></div>
</div>
</div>
</li>
</ul>
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hi @Motoed-Work ,
Can you please share the expected output from your shared HTML? Also, an anonymized screenshot of your rule trigger, condition and code please? Also, just sharing a consideration that Hover does not work with mobile devices if you expect majority of your traffic from Mobile.
Best,
Isha
Thank you for that reply. I will try that now. And I hear what you and the previous poster are saying on hover. Maybe seeing a wireframe of what I have going on will help. We have a products menu, in that products menu we have some promo banner that relates to that category of product.
I'm looking at providing an "impressions" on these banners as part of the ROI reporting on this.
I have the "wait" in my trigger because I don't want to trigger this metric when someone quickly scrolls down the list of categories... only when someone would pause to reveal and take in the flyout menu.
So this is what I'm looking at providing, metrics on impressions. I think the likelyhood that someone is seeing the banner is high... as they are paused on a category and looking at the subcategories to proceed.
I will try your js suggestions. I'm going to try this now.
Views
Replies
Total Likes
Ohhh I see... and I assume this banner is "self hosted" and not distributed though an ad server that would do its own impression tracking...
I provided code to get the parent "category".. not sure if you need info about the actual banner? Is the banner that is loaded going to be relatively stable? Or could the content change through the day so you need to know more about the banner?
The HTML you sent only had two levels, and the hover was on the child...
In the screenshot, you actually have three levels, and I think the hover would have to be on the second level (i.e. "Category 2"), to then grab info about the child ad....
So here is some updated code, I think your hoverstate actually has to be on the li item (not the link that has "Category 2"), since the menu is open if you are anywhere in the nested list item... so your selector would be li.menu-link
var subMenu = this.querySelector('a');
var hoverEleText = subMenu.innerText;
This get you "Category 1" or "Category 2", etc
To get info about the ad:
var adForHoverEle = this.querySelector('img[data-vendorname]');
I noticed that your banner ads had data attributes, so I used this to separate out from other links (which might have chevrons or other images)
The above just gets the element, now to get data from the banner, depending on what you want:
var bannerAltTag = adForHoverEle.alt;
var bannerVendorName = adForHoverEle.dataset.vendorname;
var bannerUrl = adForHoverEle.parentNode.href;
So the first option, the "Alt", I am pulling from the banner element directly, same with the second, the "Vendor Name", except that since this is in a data attribute, I have to pull it slightly differently. The last, the URL, I have to pull from the anchor tag above the banner, so I just had to reference the parentNode.
I hope this helps
Views
Replies
Total Likes
Yes, we are all self hosted with all of our content and are marketing efforts are in house for the partners we serve. I think this is very helpful and I look forward to diving in and testing shortly.
Thank you for all your insight.
You're welcome. Good luck!
Views
Replies
Total Likes
Thanks Jennifer.
I got a few other things done and moved back to this again. I'm starting to grasp this a bit and I dove into another possible method that might be more appropriate.
The problem I found was based on customer behavior, if they hover over the main menu and then move the mouse to the submenu flyout... then the hover doesn't trigger. I tried adding another hover detection on the submenu but thought I might have a better way.
I modified our banner code to provide a specific selector for the banner.
<div class="BillBoardBanner">
<a target="_blank" href="#">
<img src="/media/img/web/2024/BannerForCat1.jpg" alt="Name of ad" data-vendorname="vendor" data-pagename="Category 1" data-activitytype="Menu Banner" border="0">
</a>
</div>
And then changed my Action in my rule to "When div.BillboardBanner img enters Viewport". That trigger seems to work a little more reliably.
For Simplicity.. I'll stick with just the menu name portion.
I have a data element: Billboard Banner - Menu Cat
With this custom code
var BillboardMenu = this.querySelector('div.BillboardBanner img').data-pagename;
And then in my Rule. I have the action I mentioned above and under set variables I have custom code set to this
s.eVar52 = BillboardMenu.toLowerCase();
s.linkTrackVars += "eVar52";
And the error I'm seeing in a browser when I do the hover is "failed to execute "set Variables" for Billboard Banner rule. BillboardMenu is not defined.
I thought I had it. sigh.
Edit to add:
Looks like I'm getting other errors as well on the data element code.
Failed to execute data element module core/src/lib/dataElements/customCode.js for data element Billboard Banner - src. this.querySelector is not a function
TypeError: this.querySelector is not a function
Views
Replies
Total Likes
Oh, I should mention that the "this" code has to be run in the Rule... not in a data element.
This is why you have to manually set the eVar using "s.eVar52=" and you have to manually add eVar52 into s.linkTrackVars.
"This" has no context outside of the rule where the click occurred, as it directly references the CSS selector of the clicked element... It cannot be done in a Data Element.
Now, changing the trigger to "enters viewport" may or may not respond to this... So what I would do first, would be to get rid of the Data Element and move the code into the Custom Code of the Set Variables action.
I would also create some temporary console logs or satellite logs (whichever you prefer) to try and see what "this" is returning, if anything... and any other parts of the code to check as the code is being run as part of your debugging process.
Hope this helps on the next step of your implementation.
I second @igupta's question about what the expected outcome is... if anyone asked me to track hovers I would immediately push back.
First, a "hover" is not really a definitive metric... even with a delay, my mouse might be hovering over "A" while I am looking elsewhere on the screen trying to figure out what I want to look at, or where I want to navigate. So the information collected really isn't an indication of my intention. I also don't think most navigation is going to result in a 3 second wait time... so the people that are taking actionable steps to navigate aren't going to have any data collected... unless you are trying to capture "in-action"?
Second, this sounds like a way to really inflate the server calls, which I try and avoid as much as possible.
Now, questions about the validity of such tracking aside, from a technical "can it be done" perspective...
When you are targeting an element in Launch, you can write custom JS, using the "this" keyword, so if your rule is targeting the a.sub-menu-link elements, and you are hovering over "subcategory 2b"
You should be able to get the main category value by using something like:
var topLevelMenu = this.closest(".menu-link");
This should get you the element for "Category 2", but it will also include all the sub-elements because they are nested.
So you would have to get the first anchor, then get the innerText of that anchor:
var topLevelMenuAnchor = topLevelMenu.querySelector('a');
var topLevelMenuText = topLevelMenuAnchor.innerText;
Now, there are many way to get this value back into your tracking... me personally? I usually do custom code inside the Set Variables, then I will set the dimension directly, and ensure that my dimension is added to the linkTrackVars (for actions) to ensure my dimension is bundled into the beacon.
s.prop1 = topLevelMenuText.toLowerCase();
s.linkTrackVars += ",prop1";