How to make use of a pendo function in Angular 12+ - javascript

I have a guide setup in pendo, but I need to include a function that will continue the guide when the user clicks on a different element than the target pendo element.
I found this function:
module.exports = (function wireGuideAdvance(dom, step) {
if (!step) return;
var nextStep = guide.steps[guide.getPositionOfStep(step)];
var advanceOnce = pendo._.once(pendo.onGuideAdvanced);
function checkForElementAndAdvance(e) {
var checkForNextElement = setInterval(function () {
if (dom(nextStep.elementPathRule).length) {
advanceOnce();
clearInterval(checkForNextElement);
}
}, 1000);
}
pendo.attachEvent(document, 'click', checkForElementAndAdvance);
// step wrappable method to clear all event listeners
step.after('teardown', function () {
pendo.detachEvent(document, 'click', checkForElementAndAdvance);
});
})(pendo.dom, step);
but I do not know how to use this within the Angular app.

Related

Rate limiting calls to a function without an event listener (throttle)

I have a long infinite scroll page full of videos that I am refreshing a sticky ad on. On each scroll to a new video the URL is updated. Each URL update fires a callback that calls the refresh function. I would like to rate limit how fast the function can be fired so that refresh calls don't happen too fast if the user scrolls too quickly.
I have been able to get throttle working in a test environment while using an event listener for a button click instead of the URL change callback, but have been unable to find a way to make it work without an event listener.
Here's the base code, as you can see I need to rate-limit how fast refreshFirstSlot is called.
// Function which refreshes the first slot
var refreshFirstSlot = function () {
googletag.cmd.push(function () {
googletag.pubads().refresh([adSlot1]);
});
};
// UrlUpdate is called each time the URL updates
UrlUpdate = function (url, type) {
refreshFirstSlot();
};
// throttle code
const throttle = (callback, delay) => {
let throttleTimeout = null;
let storedEvent = null;
const throttledEventHandler = (event) => {
storedEvent = event;
const shouldHandleEvent = !throttleTimeout;
if (shouldHandleEvent) {
callback(storedEvent);
storedEvent = null;
throttleTimeout = setTimeout(() => {
throttleTimeout = null;
if (storedEvent) {
throttledEventHandler(storedEvent);
}
}, delay);
}
};
return throttledEventHandler;
};
// adding the refresh call
var returnedFunction = throttle(function () {
refreshFirstSlot();
}, 5000);
// final call
UrlUpdate = function (url, type) {
returnedFunction();
};
Where am I going wrong here?
You could do something like this :
load your page => call your ad
scroll your page => refresh your ad unless previous call has not been rendered / ended
and so on...
To do so, you can use Google Publisher Tag's events (see here). Here is a simple example :
var refreshReady = false;
//slotRequested
googletag.pubads().addEventListener('slotRequested', function(event) {
var slotId = event.slot.getSlotElementId();
if(slotId === adSlot1.getSlotElementId()) {
//every time adSlot1 is requested, we disable the refresh variable
refreshReady = false;
}
});
//slotRenderEnded
googletag.pubads().addEventListener('slotRenderEnded', function(event) {
var slotId = event.slot.getSlotElementId();
if(slotId === adSlot1.getSlotElementId()) {
//every time adSlot1 has been rendered, we enable the refresh variable
refreshReady = true;
}
});
var refreshFirstSlot = function () {
if(refreshReady) {
googletag.cmd.push(function () {
googletag.pubads().refresh([adSlot1]);
});
}
else {
console.log('not yet !');
}
};
UrlUpdate = function (url, type) {
refreshFirstSlot();
};
You could add a timeout to make sure the ad is not refreshed as soon as rendered (improve viewability)

Concatenate function

The idea behind this to animate section with mousewheel - keyboard and swipe on enter and on exit. Each section has different animation.
Everything is wrapp inside a global variable. Here is a bigger sample
var siteGlobal = (function(){
init();
var init = function(){
bindEvents();
}
// then i got my function to bind events
var bindEvents = function(){
$(document).on('mousewheel', mouseNav());
$(document).on('keyup', mouseNav());
}
// then i got my function here for capture the event
var mouseNav = function(){
// the code here for capturing direction or keyboard
// and then check next section
}
var nextSection = function(){
// Here we check if there is prev() or next() section
// if there is do the change on the section
}
var switchSection = function(nextsection){
// Get the current section and remove active class
// get the next section - add active class
// get the name of the function with data-name attribute
// trow the animation
var funcEnter = window['section'+ Name + 'Enter'];
}
// Let's pretend section is call Intro
var sectionIntroEnter = function(){
// animation code here
}
var sectionIntroExit = function(){
// animation code here
}
}();
So far so good until calling funcEnter() and nothing happen
I still stuck to call those function...and sorry guys i'm really not a javascript programmer , i'm on learning process and this way it make it easy for me to read so i would love continue using this way of "coding"...Do someone has a clue ? Thanks
Your concatenation is right but it'd be better if you didn't create global functions to do this. Instead, place them inside of your own object and access the functions through there.
var sectionFuncs = {
A: {
enter: function() {
console.log('Entering A');
},
exit: function() {
console.log('Exiting A');
}
},
B: {
enter: function() {
console.log('Entering B');
},
exit: function() {
console.log('Exiting B');
}
}
};
function onClick() {
var section = this.getAttribute('data-section');
var functions = sectionFuncs[section];
functions.enter();
console.log('In between...');
functions.exit();
}
var buttons = document.querySelectorAll('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', onClick);
}
<button data-section="A">A</button>
<button data-section="B">B</button>
You could have an object that holds these functions, keyed by the name:
var enterExitFns = {
intro: {
enter: function () {
// animation code for intro enter
},
exit: function () {
// animation code for intro exit
}
},
details: {
enter: function () {
// animation code for details enter
},
exit: function () {
// animation code for details exit
}
}
};
var name = activeSection.attr('data-name');
enterExitFns[name].enter();

Fire function within jquery plugin?

I have dynamically created increment and decrement buttons for certain <input> html elements (specifically for numeric inputs), however I cannot for the life of me how to figure out how to bind an action through the plugin function.
I want to do it specifically this way as these arrows will be used on many different types of forms that minus and add values (e.g. %, money etc.) which affect certain visual elements.
The function looks around the lines of:
(function ($) {
$.fn.addIncrementArrows = function (min, max, interval, fastInterval, event) {
var input = this;
/*Other building things go here*/
var timeoutDownArrow;
var intervalDownArrow;
//clicking button down for 1 second fires '-' actions
$(this).parent().children(".downarrow").mousedown(function () {
timeoutDownArrow = setTimeout(function () {
intervalDownArrow = setInterval(function () {
changeValue(-fastInterval);
//how to do event here?
}, 90);
}, 750);
}).bind("mouseup mouseleave", function () {
clearTimeout(timeoutDownArrow);
clearInterval(intervalDownArrow);
});
};
}(jQuery));
Simply what I need to declare to make it have the arrows as follows:
formnamehere.addIncrementArrows(0, 100, 1, 5, event);
If it's possible: how could I bind an action to the button within .addIncrementArrows()?
So after a bit of research I came to a conclusion:
1 - Changed the function to run inside .addIncrementArrows() as a named run-time function:
var setSliderPercentage = function (percent) {
//do stuff here
}
2 - Pass the function into the plugin as a variable name
percentageForm.addIncrementArrows(0, 100, 1, 5, setSliderPercentage);
3 - Ran the passed function within the addIncrementArrows() plugin.
$.fn.addIncrementArrows = function (min, max, interval, fastInterval, event) {
var input = this;
if (max === false) max = Infinity; //infinity and beyond!
//Other stuff here
//make the it auto increment or decrement every 100ms when 'holding down' the button after 1 second
var timeoutUpArrow;
var intervalUpArrow;
$(uparrow).mousedown(function () {
timeoutUpArrow = setTimeout(function () {
intervalUpArrow = setInterval(function () {
changeValue(fastInterval);
//
if (typeof event != "undefined") event(input.val());
//
}, 90);
}, 750);
}).bind("mouseup mouseleave", function () {
clearTimeout(timeoutUpArrow);
clearInterval(intervalUpArrow);
});
}

How can I pass the currentTarget of my mouse into a timelineMax function

So I am trying to create a reusable function that each .featured-image on my page uses. if I don't use backbone events: and I just write the code that is commented out it works. How can i get the events imageOver and imageOut mimicking the commented code??
app.newsroomPageElementView = Backbone.View.extend({
events: {
'mouseenter .featured-image': 'imageOver',
'mouseleave .featured-image': 'imageOut'
},
initialize: function () {
$(".featured-image").each(function(index, element){
var tl = new TimelineLite({paused:true});
tl.to(element, 0.2, {opacity:.9, scale:.9})
.to(element, 0.2, {backgroundColor:"#004", color:"orange"}, "-=0.1")
element.animation = tl;
})
// This part works if i don't use imageOver and imageOut
// $("li").hover(over, out);
// function over(){
// this.animation.play();
// }
// function out(){
// this.animation.reverse();
// }
},
imageOver: function (e) {
// What goes here?
},
imageOut: function (e) {
// What goes here?
}
});
Using the events hash you can access the event target through the event object and still access the view instance through this
imageOver: function (event) {
$(event.target).animation.play();
},
imageOver: function (event) {
var target = event.currentTarget;
// What goes here?
target.animation.play();
},
imageOut: function (event) {
var target = event.currentTarget;
// What goes here?
target.animation.reverse();
}

setInterval and clearInterval javascript not working as needed

I have the following code partially working. I am newbie in javascript so please don't blame me if my approach is not the best.
window.url_var = "status.htm";
window.elem = "#e1";
function menu_item(){
$(window.elem).click(function (event)
{
$("#divTestArea1").load(window.url_var);
});
}
$("#e1").click(function (event)
{
event.preventDefault();
window.url_var = "demo2.txt";
window.elem = "#e1";
$("#divTestArea1").load(window.url_var);
auto_refresh = setInterval(menu_item(), 5000);
});
$("#e2").click(function (event)
{
event.preventDefault();
window.url_var = "status.htm";
window.elem = "#e2";
$("#divTestArea1").load(window.url_var);
auto_refresh = setInterval(menu_item(), 5000);
});
$("#e3").click(function (event)
{
event.preventDefault();
window.url_var = "form.htm";
window.elem = "#e3";
clearInterval(auto_refresh);
$("#divTestArea1").load(window.url_var);
});
jQuery(document).ready(function() {
$("#divTestArea1").load(window.url_var);
auto_refresh = setInterval(menu_item(), 5000);
});
Whenever I click elements e1 and e2, the setInterval works as expected and as soon as I click element e3, the element cease to be reloaded.
That's the behavior I want so far. But I also wants to start the setinterval again if e1 or e2 get's again clicked.
the last is what it's not working on the above code.
I will appreciate if you could point me in the right direction.
I have come to this code after seeing some of the answers to my original question (thanks to everyone). To clarify my original idea, I need to update some items on my web page on a regular basics but the content can be change with some menu and also some of the contents like a form should not be updated.
window.url_var = "demo2.txt";
var auto_refresh = null;
function setRefresh() {
var self = this;
this.bar = function() {
if(window.url_var != ""){
$("#divTestArea1").load(window.url_var);
auto_refresh = setTimeout(function() { self.bar(); }, 5000);
}
}
this.bar();
}
$("#e1").click(function (event)
{
event.preventDefault();
window.url_var = "demo2.txt";
setRefresh();
});
$("#e2").click(function (event)
{
event.preventDefault();
window.url_var = "status.htm";
setRefresh();
});
$("#e3").click(function (event)
{
event.preventDefault();
window.url_var = "form.htm";
$("#divTestArea1").load(window.url_var);
window.url_var = "";
});
$(document).ready(function() {
setRefresh();
});
Try using 2 different variables and clearing all if needed. This is: auto_refresh1 and auto_refresh2. Each time you call setinterval, it creates a new timer with a new id. You are overwriting auto_refresh variable and the timer before that will still fire.
Or you can store the setinterval in a hash object and run through and clear them all.
I'm unclear as to what exactly it is that you're trying to do here. Nevertheless, I've rewritten your code a bit to make some improvements (and fix one glaring bug in your code involving the setInterval calls).
var url_var = "status.htm",
elem = "#e1",
$destination = $("#divTestArea1"),
auto_refresh;
function menu_item() {
$(elem).bind("click", function (e) {
$destination.load(url_var);
});
}
function load() {
$destination.load(url_var);
}
function set(url, id) {
url_var = url;
elem = id;
}
function setRefresh() {
return setInterval(menu_item, 5000);
}
function handleClick(e) {
e.preventDefault();
set(e.data.url, e.data.id);
load();
auto_refresh = setRefresh();
}
$("#e1").on("click", {
url: "demo2.txt",
id: "#e1"
}, handleClick);
$("#e2").on("click", {
url: "status.htm",
id: "#e2"
}, handleClick);
$("#e3").on("click", function (e) {
e.preventDefault();
set("form.htm", "#e3");
clearInterval(auto_refresh);
load();
});
$(document).ready(function () {
load();
auto_refresh = setRefresh();
});
I'm guessing that maybe those setInterval calls should actually be setTimeout calls? Why would you want to bind a "click" event handler over and over again?
EDIT #1: Switched to jQuery's currently preferred on method from the bind method, included use of event data parameter to further abstract event handling code.

Categories

Resources