Facebook ad tracking without noscript portion - javascript

The facebook implementation for the custom audience pixel is written in this form:
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
_fbq.push(['addPixelId', '###########']);
})();
window._fbq = window._fbq || [];
window._fbq.push(['track', 'PixelInitialized', {}]);
</script>
<noscript><img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?id=###########&ev=PixelInitialized" /></noscript>
We want to deploy this using a tag manager but ours only supports javascript only not HTML. I'm wondering how important the noscript portion of this is? Would the only drawback be that we would be just losing a certain portion of our audience, namely those on devices that do not support javascript or those who disabled javascript themselves?

The noscript portion is a fallback, yes. But if you can't add it with a tag manager, why not simply place the img tag <img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?id=###########&ev=PixelInitialized" /> on the page somewhere, e.g. just at the bottom of the body tag.

Related

Include Javascript inside JS file

How can we include javascript link inside .js file?. .js file support include, require or import like CSS or PHP?
My Code :
// Global site tag (gtag.js) - Google Analytics
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://www.googletagmanager.com/gtag/js?id=UA-51600743-15';
document.body.appendChild(script);
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-51600743-15');
// Microsoft Clarity
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "9zvbjor3bn");
//Start of Tawk.to Script
var Tawk_API=Tawk_API||{}, Tawk_LoadStart=new Date();
(function(){
var s1=document.createElement("script"),s0=document.getElementsByTagName("script")[0];
s1.async=true;
s1.src='https://embed.tawk.to/61d019a4c82c976b71c45176/1foae8bkm';
s1.charset='UTF-8';
s1.setAttribute('crossorigin','*');
s0.parentNode.insertBefore(s1,s0);
})();
I am trying to add all tracking code inside one file analytic.js and adding that to my website so it will be easy for me to maintain in future, so i do not need to edit in every page whenever any changes required in tracking codes.
What is the correct way to include another js file inside js file?
async src="https://www.googletagmanager.com/gtag/js?id=UA-51600743-15";
//OR
require("https://www.googletagmanager.com/gtag/js?id=UA-51600743-15"};
//OR
import from "https://www.googletagmanager.com/gtag/js?id=UA-51600743-15";
//Or any other way?
Guide : https://www.geeksforgeeks.org/how-to-include-a-javascript-file-in-another-javascript-file/
Solution :
function include(file) {
var script = document.createElement('script');
script.src = file;
script.type = 'text/javascript';
script.defer = true;
document.getElementsByTagName('head').item(0).appendChild(script);
}
/* Include Many js files */
include('https://example.com/example.js');

Inject a tag inside another tag in <head> using javascript/jQuery

How do I inject tag inside in head using javascript.
<noscript>
<img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=801318466672120&ev=PageView&noscript=1"
/></noscript>
I tried
var nonscript = document.createElement('noscript');
nonscript.innerHTML = "<img height='1' width='1' style='display:none' src='https://www.facebook.com/tr?id=801318466672120&ev=PageView&noscript=1'/>";
head.appendChild(nonscript);
but it comes like
<noscript>
"<img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr id=801318466672120&ev=PageView&noscript=1"
/>" </noscript>
You may use the following code:
var nonscript = document.createElement('noscript');
var img = document.createElement("img");
img.height = 1;
img.width = 1;
img.style.display = "none";
img.src = "https://www.facebook.com/trid=801318466672120&ev=PageView&noscript=1"
nonscript.appendChild(img);
document.head.appendChild(nonscript);
Appending a noscript tag with javascript makes no sense whatsoever.
Also, when used in the head, the noscript tag can not contain an img:
Permitted content: When scripting is disabled and when it is a
descendant of the <head> element: in any order, zero or more <link>
elements, zero or more <style> elements, and zero or more <meta>
elements. When scripting is disabled and when it isn't a descendant of
the <head> element: any transparent content, but no <noscript> element
must be among its descendants. Otherwise: flow content or phrasing
content.
Source
But if you insist:
You need to create an img element and append that to your noscript element. You can then append both to head:
var nonscript = document.createElement('noscript');
var img = document.createElement('img');
var head = document.getElementsByTagName('head')[0];
img.width = "0";
img.height = "0";
img.style.display = "none";
img.src = "https://www.facebook.com/tr?id=801318466672120&ev=PageView&noscript=1";
nonscript.appendChild(img);
head.appendChild(nonscript);

Make Facebook pixel fire on click event

I'm currently trying to follow this FB resource about tracking on page events with conversion pixels.
If I'm understanding correctly, the gist of it is to paste my base pixel code in the header, then add the tweaked "example code" underneath it.
Here is our base pixel code:
<!-- Facebook Conversion Code for Cool Company LLC -->
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
window._fbq.push(['track', '6029151989664', {'value':'0.00','currency':'USD'}]);
</script>
<noscript><img height="1" width="1" alt="" style="display:none" src="https://www.facebook.com/tr?ev=6029151989664&cd[value]=0.00&cd[currency]=USD&noscript=1" /></noscript>
And here is the "example code" they say to use for tracking in-page events:
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', '<pixel_id>', cd]);
}
<button onClick="trackConversionEvent('10.00','USD');" />
And finally the question: we want the in-page event to be hitting the submit button on the rightside subscription widget at http://wearablestylenews.com/
To do this, do I just change the last line of example code to this?
<input id="ykfmc-submit_0-2f6a0367b1" onClick="trackConversionEvent('0.00','USD');" />
And do I just put it after the base code in the header?
Thanks guys, I really appreciate your help!

DRY lazy-loaded images with <noscript> fallback

I know that (a handful of) non-JavaScript users are out there and I'd like to cater for them instead of giving them poorer experience just because of their preference (be that for privacy reasons or whatever).
Most lazy-loading JS libraries seem to address this in the same fashion, for example see lazysizes:
<style>
.no-js img.lazyload {
display: none;
}
</style>
<noscript>
<img src="image.jpg" />
</noscript>
<img src="grey.jpg" data-src="image.jpg" class="lazyload" />
Mainly out of curiosity, I got to wondering if it would be possible to pull the fallback out of the <noscript> tag and add it to the DOM programmatically with JavaScript so that the image source didn't have to be duplicated in two image tags which would leave me with just:
<noscript>
<img src="image.jpg" class="lazyload" width="600" height="400"/>
</noscript>
Here's what I've knocked together:
(function(attribute) {
Array.prototype.forEach.call(document.getElementsByTagName("noscript"), function(node) {
var parser = new DOMParser,
el = parser.parseFromString(node.textContent, "text/xml").documentElement, // XML => <img/> required
img = ("img" == el.tagName) ? el : el.getElementsByTagName("img")[0]; // allow for <img/> in <picture>
img.setAttribute(attribute, img.getAttribute("src"));
img.setAttribute("src", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC");
node.insertAdjacentHTML("beforebegin", el.outerHTML);
});
})("data-src"); // different libraries use different data attribute names
This appears to work everywhere (Chrome, Safari, Opera, Firefox) except Internet Explorer (naturally). I know that .textContent isn't available pre-IE9 but IE9+ all seem to be failing at the final hurdle - the .outerHTML. Am I doomed to failure and having to repeat myself in my markup?
Update: To clarify, I'd ideally like to be able to use arbitrary attributes (alt, title, etc.) in the image tag or even use responsive markup:
<noscript>
<picture>
<source ... />
<source ... />
<img src="image.jpg" />
</picture>
</noscript>
I'm the creator of lazySizes. This approach has multiple porblems:
A noscript element is never renderend, which means it is not detectable, wether it is visible or not (or better said it is always invisible)
You can't use statefull classes lazyloading and lazyload to give feedback to the user
You can't pre-occupy the space for your lazy embed content (which is important for both a) user experience (no content jumping) and b) performance (no reflow)
(It has problems in older browsers)
The data-sizes="auto" feature can't be used
However if 4. and 5. isn't a problem for you, it is possible to use a noscript child element in conjunction with a lazyload parent to achieve this.
The markup could look something like this:
<div class="lazyload" data-noscript="">
<noscript>
<p>any kind of content you want to be unveiled</p>
</noscript>
</div>
And the lazySizes plugin code would look something like this:
(function(){
'use strict';
var supportPicture = !!window.HTMLPictureElement;
addEventListener('lazybeforeunveil', function(e){
if(e.defaultPrevented || e.target.getAttribute('data-noscript') == null){return;}
var imgs, i;
var noScript = e.target.getElementsByTagName('noscript')[0] || {};
var content = noScript.textContent || noScript.innerText || '';
e.target.innerHTML = content;
if(supportPicture){return;}
imgs = e.target.querySelectorAll('img[srcset], picture > img');
for(i = 0; i < imgs.length; i++){
lazySizes.uP(imgs[i]);
}
});
})();
In case you like this, I might make an official plugin for this. Here is the plugin: https://github.com/aFarkas/lazysizes/tree/master/plugins/noscript
Here's how I'd do it, using methods that should be available in all browsers
(function(attribute) {
Array.prototype.forEach.call(document.getElementsByTagName("noscript"), function(node) {
var content = node.childNodes[0].nodeValue,
parser = new DOMParser(),
doc = parser.parseFromString(content, "text/html"),
images = doc.getElementsByTagName('img');
for (var i=images.length; i--;) {
var img = document.createElement('img');
img.src = 'data:image/png;base64,iVBOR ....';
img.height = images[i].getAttribute('height');
img.width = images[i].getAttribute('width');
img.setAttribute(attribute, images[i].getAttribute('src'));
node.parentNode.insertBefore(img, node.nextSibling);
}
});
})("data-src");
Here's the trick I use:
(function() {
"use strict";
var config = {
// If the image gets within 50px in the Y axis, start the download.
rootMargin: "50px 0px",
threshold: 0.01
};
var observer;
//If we're using a browser without the IntersectionObserver (IE11, Safari 11), skip the lazy part and just load the resources
if ("IntersectionObserver" in window) {observer = new IntersectionObserver(onIntersection, config);}
//If we're using a browser without requestAnimationFrame (IE9, Opera Mini), just run the passed function
var rAF;
if ("requestAnimationFrame" in window) rAF = window.requestAnimationFrame;
else rAF = function(func) { func(); };
var tempImg = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==";
/**
* Temporarily replace a expensive resource load with a cheap one
*/
function storeSourceForLater(lazyItem, tempData) {
//Store our ACTUAL source for later
lazyItem.setAttribute("data-lazy-src", lazyItem.getAttribute("src"));
//Set the item to point to a temporary replacement (like a data URI)
lazyItem.setAttribute("src", tempData);
//Now observe the item so that we can start loading when it gets close to the viewport
observer.observe(lazyItem);
}
/**
* Temporarily prevent expensive resource loading by inserting a <source> tag pointing to a cheap one (like a data URI)
*/
function jamSourceLoading(lazyItem, tempData) {
var newSource = document.createElement("source");
newSource.setAttribute("srcset", tempData);
newSource.setAttribute("data-lazy-remove", "true");
//adding this source tag at the start of the picture tag means the browser will load it first
lazyItem.insertBefore(newSource, lazyItem.firstChild);
var baseImage = lazyItem.getElementsByTagName("img")[0];
if (baseImage) {
//this is a picture tag, so we need to watch the image (as the picture tag is smaller than the image usually)
observer.observe(baseImage);
}
}
/**
* Set up the lazy items so that they won't try to load when we add them to the document, but will once the user is close to seeing them
*/
function prepareLazyContents(lazyArea) {
var lazyImgs = lazyArea.getElementsByTagName("img");
for(var i = lazyImgs.length; i--;){
storeSourceForLater(lazyImgs[i], tempImg);
}
var lazyPictures = lazyArea.getElementsByTagName("picture");
for(var i3 = lazyPictures.length; i3--;) {
jamSourceLoading(lazyPictures[i3], tempImg);
}
}
/**
* Put the source back where we found it - now that the element is attached to the document, it will load now
*/
function restoreSource(lazyItem) {
lazyItem.setAttribute("src", lazyItem.getAttribute("data-lazy-src"));
lazyItem.removeAttribute("data-lazy-src");
}
/**
* Remove the source tag preventing the loading of picture/audio/video
*/
function removeJammingSource(lazyItem) {
var jammingSource = lazyItem.querySelector("source[data-lazy-remove]");
if (jammingSource) lazyItem.removeChild(jammingSource);
}
/**
* Handle the intersection postback
*/
function onIntersection(entries, obsvr) {
entries.forEach(function(entry) {
if(entry.intersectionRatio === 0) return;
//if the item is now visible, load it and stop watching it
var lazyItem = entry.target;
obsvr.unobserve(lazyItem);
//Just in case the img is the decendent of a picture element, check for source tags
removeJammingSource(lazyItem.parentNode);
restoreSource(lazyItem);
});
}
/**
* Retrieve the elements from the 'lazy load' no script tags and prepare them for display
*/
function setUp() {
//Get all the noscript tags on the page
var lazyLoadAreas = document.getElementsByTagName("noscript");
for(var i = lazyLoadAreas.length; i--;) {
var noScriptTag = lazyLoadAreas[i];
//only process the ones marked for lazy loading
if (!noScriptTag.hasAttribute("data-lazy-load")) continue;
// The contents of a noscript tag are treated as text to JavaScript
var lazyAreaHtml = noScriptTag.textContent||noScriptTag.innerHTML;
// So we stick them in the innerHTML of a new div tag to 'load' them
var lazyArea = document.createElement("div");
lazyArea.innerHTML = lazyAreaHtml;
//Only delay loading if we can use the IntersectionObserver to check for visibility
if(!observer) {
noScriptTag.parentNode.replaceChild(lazyArea, noScriptTag);
} else {
prepareLazyContents(lazyArea);
noScriptTag.parentNode.replaceChild(lazyArea, noScriptTag);
}
}
}
//If the page has loaded already, run setup - if it hasn't, run as soon as it has.
//Use requestAnimationFrame as this will propably cause repaints
if (/comp|inter/.test(document.readyState)) {
rAF(setUp);
} else if ("addEventListener" in document) {
document.addEventListener("DOMContentLoaded",
function(){rAF(setUp);});
} else {
document.attachEvent("onreadystatechange", function() {
if (document.readyState=="complete") {
setUp();
}
});
}
})();
<p>Scroll down to see lazy loading in action!</p>
<noscript><p>Even with JavaScript turned off, the images should still load.</p></noscript>
<p>Why are the assets in noscript tags? So that they will load for people who have turned JavaScript off!</p>
<p>(The conditional comments are becuase there is no way to fetch the contents of a noscript tag in IE8 and below.)</p>
<hr/>
<div style="height: 600px;"></div>
<hr/>
<!--[if (gt IE 8)|!(IE)]><!--><noscript data-lazy-load><!--<![endif]-->
<img src="//upload.wikimedia.org/wikipedia/commons/2/27/F-16_Plan_Black_on_Circle_Light_Blue.svg?c=25" alt="This is an image used to demonstrate a lazy-loading trick." width="250" height="250">
Here is some text on the outside to demonstrate the lack of reflows!
<!--[if (gt IE 8)|!(IE)]><!--></noscript><!--<![endif]-->
<hr/>
<!--[if (gt IE 8)|!(IE)]><!--><noscript data-lazy-load><!--<![endif]-->
<picture>
<img src="//upload.wikimedia.org/wikipedia/commons/2/27/F-16_Plan_Black_on_Circle_Light_Blue.svg?c=25" alt="This is an image used to demonstrate a lazy-loading trick." width="250" height="250">
</picture>
This one is a reponsive picture element!
<!--[if (gt IE 8)|!(IE)]><!--></noscript><!--<![endif]-->
It only Lazy-Loads on browser that support Intersection Observer (so not IE, but about 87% of the world at time of writing) but the image will show in all browsers.
Since 2019 the img tag has a new attribute: loading. You can specify loading="lazy" which defers loading the image until it reaches a calculated distance from the viewport, as defined by the browser.
It has broad browser support (Edge, Firefox, Chrome, Safari and Opera):
It defaults to eager/normal loading in case of older browsers or when Javascript is disabled. The latter is an anti-tracking measure, because if a user agent supported lazy loading when scripting is disabled, it would still be possible for a site to track a user's approximate scroll position by strategically placing images in a page's markup. (source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading)

How do I add a javascript alert to innerHTML at runtime

When a particular event happens that I listen out for - I want to populate the div 'divDynamicAdvert` with the javascript that calls my Google Ad code.
Huge thanks to "tenbits" for showing me that I need to be appending a script node like this:
function myEventHandler(evt) //called when event is caught
{
var script = document.createElement('script');
script.textContent = 'alert(1)';
document.getElementById('divDynamicAdvert').appendChild(script);
}
This works great, but in place of the alert, I need to insert the Google Ads Javascript:
<script type="text/javascript"><!--
google_ad_client = "ca-pub-3286208413631803";
/* Standard MPU */
google_ad_slot = "8630273973";
google_ad_width = 300;
google_ad_height = 250;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
I've tried:
var script = document.createElement('script');
script.textContent = 'google_ad_client = 'ca-pub-3286208413631803'; google_ad_slot = '8630273973'; google_ad_width = 300; google_ad_height = 250;';
document.getElementById('divDynamicAdvert').appendChild(script);
var script = document.createElement('script src="http://pagead2.googlesyndication.com/pagead/show_ads.js"');
document.getElementById('divDynamicAdvert').appendChild(script);
I've tried escaping the slashes too, but no luck... Can you guys help?
As #slebetman already said, innerHTML wont work. If you trying to evaluate script via DOM, and not eval(code), etc - do this with SCRIPT Node:
var script = document.createElement('script');
script.textContent = 'alert(1)';
document.getElementById('divDynamicAdvert').appendChild(script);
// actually it doesnt matter where you append it
EDIT:
In any case create a SCRIPT NODE, and then manipulate with it - add a script content to it OR add src attribute if you reference external source
var script;
// content
script = document.createElement('script')
script.textContent = 'alert(1)'
document.body.appendChild(script);
// google api source
script = document.createElement('script');
script.src = 'ANY_URL';
// -> in this case, same as script.setAttribute('src', 'ANY_URL');
document.body.appendChild(script);
Having some further questions, do not hesitate to ask in comments.

Categories

Resources