I need to create doubleclick banner, and i am using Google Web Designer. I want to call clickTag by simple href="javascript:window.open(window.clickTag)", and everything works fine, but when i validate it on
https://h5validator.appspot.com/dcm/asset i get error:
Missing click tag check
How can I remove this error, what am I missing?
Thanks
I think this will help you out to find solution to your problem, please follow the below steps :
Step 1: extract the files from zip. and Open .html file using any code editor, most useful for trafficker is notepad++.
Step 2: There will be two important section in html file <head></head> and <body></body>
<head> section will have <script type=”text/javascript”> which handle most the functionality will be present.
Now Paste below code Before </head> section and Inside <script type=”text/javascript”>Some Code From Creative </script>
var clickTag = "http://www.google.com";
Make sure that other tags/function are close and you are not pasting the above code inside other tag/function.
Code:
<head>
<script type=”text/javascript”>
var clickTag = “http://www.google.com”;
Somecode of(function()
{
somefunctionality code ...
}
</script>
</head>
Step 3: Paste the below code after <body> start, Arrangement of the code can impact what portion of the creative will be clickable, so make sure that you cover every assets of creative code withing the code below
<body>
<a href="javascript:window.open(window.clickTag)">
.......Creative assets code...
.......Some functionality code.....
</a>
</body>
click tag google web designer
Step 4: Make sure that clickTag defined in body and clickTag defined in head section should be same. Now save the file.
Step 5: Go to the folder where all the assets presents, Select all then create the zip, make sure you create zip and not rar because zip is only supported format in DFP. For other servers it might be different.
Because if don’t zip all files correctly you might get “No Primary HTML file detected” this error
No Primary HTML file detected
Creative is built from Adobe Animate CC
Step resolve the creative issue
Step 1: Extract the zip file and open the html file present in the folder
Step 2: Open the .html in file sublime/Notepad++ editor, Paste below Code in <head> section just before You can replace the http://www.google.com with the clicktracker or landing page URL provided by client.
Code:
var clickTag = "http://www.google.com";
Adobe_animate_CC_clickTag_Issue_head_section
Step 3: Now once above code is implemented its time to implement the clickTag in body section, Since the clickTag is case sensitive make sure that clickTag implemented in Head section should match with clickTag in body section, Now implement below code just After tag.
Adobe_animate_CC_clickTag_Issue_body_section
Step 4: Make sure that the placement of tag is important, you must cover the whole canvas portion so that whole creative will be clickable.
I had the same problem and I tried to follow the instructions under https://support.google.com/dcm/answer/3145300?visit_id=636892883779240296-1524067146&rd=1#dev > Click tags > Sample click tag insertion.
However, I could not make it work, whatever I tried. The result was always: it worked fine, but the validator threw an error.
So I went back to the second option described under "Use Google Web Designer for exit events". Following all the steps there exactly.
The result was a creative that checked in the validator but was not clickable.
So after including the gwd tap area, I also manually added an additional anchor just inside the body, so it looked something like this:
<body>
<a href="javascript:window.open(window.clickTag)">
<gwd-google-ad id="gwd-ad" polite-load="">
(...)
<gwd-pagedeck class="gwd-page-container" id="pagedeck">
<gwd-page id="page1" class="gwd-page-wrapper gwd-page-size gwd-lightbox" data-gwd-width="300px" data-gwd-height="600px">
(...)
<gwd-taparea id="gwd-taparea_1" class="gwd-taparea-vsnj"></gwd-taparea>
</div>
</gwd-page>
</gwd-pagedeck>
<gwd-exit metric="CTA-xyz" url="http://abc.de"></gwd-exit>
</gwd-google-ad>
<script type="text/javascript" id="gwd-init-code">
(...)
</script>
</a>
</body>
Now I had a creative that validated but was also clickable.
HTML5 creatives created using Google Web Designer (GWD) should have the clickTag added as a call to action (https://support.google.com/webdesigner/answer/3263494?hl=en) added within Google Web Designer BEFORE exporting to a .zip file.
Since you only have the exported .zip file, you will need to either go back to GWD and add in the call to action OR follow the hardcode workaround I made:
I will refer to your jsfiddle (http://jsfiddle.net/ae363saf):
Paste in the with the rest of style tags (line 8).
<style data-exports-type="gwd-taparea" data-gwd-node="true">gwd-taparea{display:block;cursor:pointer;background-color:rgba(0,0,0,0);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}</style>
Depending on your creative size, you'll need to modify the values in this code. The creative example is 300x250, so in the following code, set:
height:300px,
width:250px,
transform-origin:125px 150px 0px,
-webkit-transform-origin:125px 150px 0px, and
-moz-transform-origin:125px 150px 0px (half width, half height, 0).
Paste the edited code immediately before </style> at the end of line 13.
.gwd-taparea-11s4{position:absolute;top:0px;height:300px;left:0px;width:250px;transform-origin:125px 150px 0px;-webkit-transform-origin:125px 150px 0px;-moz-transform-origin:125px 150px 0px}
Paste immediately before </head> (line 86).
<script data-source="gwdtaparea_min.js" data-version="4" data-exports-type="gwd-taparea">(function(){'use strict';var c;var d=function(a,b,e){if(e){var f=document.createEvent("CustomEvent");f.initCustomEvent(a,!0,!0,e)}else f=document.createEvent("Event"),f.initEvent(a,!0,!0);b.dispatchEvent(f);return f};var g=[],h=function(a){a=g.indexOf(a);0<=a&&g.splice(a,1)};document.addEventListener("click",function(a){for(var b=0;b<g.length;b++)if(25>Math.abs(a.clientX-g[b].m)&&25>Math.abs(a.clientY-g[b].o)||25>Math.abs(a.screenX-g[b].A)&&25>Math.abs(a.screenY-g[b].B))g.splice(b,1),a.stopPropagation(),a.preventDefault()},!0);var k=function(){};goog.inherits(k,HTMLElement);c=k.prototype;c.createdCallback=function(){this.l=this.j=0;this.f=this.b=this.g=this.c=null;this.a=!0;this.h=this.s.bind(this)};
c.attachedCallback=function(){this.b||(this.c=this.i.bind(this),this.g=this.w.bind(this),this.b=this.v.bind(this),this.f=this.u.bind(this));this.addEventListener("click",this.c,!1);this.addEventListener("touchstart",this.g,!1);this.addEventListener("action",this.h,!1)};c.detachedCallback=function(){this.removeEventListener("click",this.c,!1);this.removeEventListener("touchstart",this.g,!1);this.removeEventListener("action",this.h,!1)};c.i=function(){this.a&&d("action",this);this.a=!0};
c.w=function(a){this.addEventListener("touchmove",this.b,!1);this.addEventListener("touchend",this.f,!1);a=a.touches[0];this.j=a.clientX;this.l=a.clientY};c.u=function(a){this.i();this.removeEventListener("touchmove",this.b,!1);this.removeEventListener("touchend",this.f,!1);a=a.changedTouches[0];a={m:a.clientX,o:a.clientY,A:a.screenX,B:a.screenY};g.push(a);setTimeout(h.bind(null,a),2500)};c.v=function(a){a=a.touches[0];this.a=this.a&&10>=Math.abs(this.j-a.clientX)&&10>=Math.abs(this.l-a.clientY)};
c.s=function(){var a=this.getAttribute("exit-id"),b=this.getAttribute("product-index"),e=this.getAttribute("exit-override-url");e&&!d("tapareaexit",this,{"exit-id":a,url:e,"product-index":b}).detail.handled&&window.open(e)};c.attributeChangedCallback=function(){};document.registerElement("gwd-taparea",{prototype:k.prototype});}).call(this);
</script>
<script type="text/javascript" gwd-events="support">var gwd=gwd||{};gwd.actions=gwd.actions||{};gwd.actions.events=gwd.actions.events||{};gwd.actions.events.getElementById=function(id){var element=document.getElementById(id);if(!element){var pageDeck=document.querySelector("[is=gwd-pagedeck]");if(pageDeck){if(typeof pageDeck.getElementById==="function"){element=pageDeck.getElementById(id)}}}if(!element){switch(id){case"document.body":element=document.body;break;case"document":element=document;break;case"window":element=window;break;default:break}}return element};gwd.actions.events.addHandler=function(eventTarget,eventName,eventHandler,useCapture){var targetElement=gwd.actions.events.getElementById(eventTarget);if(targetElement){targetElement.addEventListener(eventName,eventHandler,useCapture)}};gwd.actions.events.removeHandler=function(eventTarget,eventName,eventHandler,useCapture){var targetElement=gwd.actions.events.getElementById(eventTarget);if(targetElement){targetElement.removeEventListener(eventName,eventHandler,useCapture)}};gwd.actions.events.setInlineStyle=function(id,styles){var element=gwd.actions.events.getElementById(id);if(!element||!styles){return}var transitionProperty=element.style.transition!==undefined?"transition":"-webkit-transition";var prevTransition=element.style[transitionProperty];var splitStyles=styles.split(/\s*;\s*/);var nameValue;splitStyles.forEach(function(splitStyle){if(splitStyle){var regex=new RegExp("[:](?![/]{2})");nameValue=splitStyle.split(regex);nameValue[1]=nameValue[1]?nameValue[1].trim():null;if(!(nameValue[0]&&nameValue[1])){return}element.style.setProperty(nameValue[0],nameValue[1])}});function restoreTransition(event){var el=event.target;el.style.transition=prevTransition;el.removeEventListener(event.type,restoreTransition,false)}element.addEventListener("transitionend",restoreTransition,false);element.addEventListener("webkitTransitionEnd",restoreTransition,false)};gwd.actions.gwdDoubleclick=gwd.actions.gwdDoubleclick||{};gwd.actions.gwdDoubleclick.exit=function(receiver,exitId,url,opt_collapseOnExit,opt_pauseMedia){gwd.actions.events.getElementById(receiver).exit(exitId,url,opt_collapseOnExit,opt_pauseMedia)}</script>
<script type="text/javascript" gwd-events="handlers">gwd.auto_Gwd_taparea_1Action=function(event){gwd.actions.gwdDoubleclick.exit("gwd-ad","clickTag","http://www.visitloscabos.travel/",true,true)}</script>
<script type="text/javascript" gwd-events="registration">gwd.actions.events.registerEventHandlers=function(event){gwd.actions.events.addHandler("gwd-taparea_1","action",gwd.auto_Gwd_taparea_1Action,false)};gwd.actions.events.deregisterEventHandlers=function(event){gwd.actions.events.removeHandler("gwd-taparea_1","action",gwd.auto_Gwd_taparea_1Action,false)};document.addEventListener("DOMContentLoaded",gwd.actions.events.registerEventHandlers);document.addEventListener("unload",gwd.actions.events.deregisterEventHandlers)</script>
Within the <gwd-metric-configuration> tag (line 90).
<gwd-metric-event source="gwd-taparea_1" event="tapareaexit" metric="" exit="Exit"></gwd-metric-event>
Before </div> of <div class="gwd-page-content gwd-page-size"> (line 95).
<gwd-taparea id="gwd-taparea_1" class="gwd-taparea-11s4"></gwd-taparea>
Replace the URL below with whatever URL you want to click through to (your clickTag) or a default one, because some ad servers will have an option to modify this URL in their interface. Paste immediately before </gwd-doubleclick> (line 98).
<gwd-exit metric="clickTag" url="https://www.google.com/"></gwd-exit>
Replace the URL with the URL you want to click through to. Paste within StudioExports function between the brackets (end of line 138).
Enabler.exit("clickTag", "https://www.google.com/");
Replace the URL with the URL you want to click through to. Paste within <script type="text/gwd-admetadata"> "exits":[] array between the brackets (line 138).
{"exitId":"clickTag","url":"https://www.google.com/"}
Paste to the end of the <script type="text/gwd-admetadata"> tag in the "components":["gwd-doubleclick","gwd-page","gwd-pagedeck"] array after the last component, "gwd-pagedeck" (line 138).
,"gwd-taparea"
Save the file, .zip the folder again, and the creative should now pass in Google's HTML5 Validator.
I know I might be late, but I sat with the same problem and I found an easier way to fix the "Missing click tag check" error on https://h5validator.appspot.com/dcm/asset and there is no need to add custom code.
The steps are as follows:
Create a Tap Area
Add an event to the Tap Area and setup the event as follows:
Tap Area - Touch/Click
Action - Google ad - Exit ad
Receiver - gwd-ad
Configuration - fill out the details (see: https://support.google.com/webdesigner/answer/3263494?hl=en&ref_topic=3261495 for configuration details )
Once you are done, save your build and publish it to ZIP. You can upload the ZIP at https://h5validator.appspot.com/dcm/asset and you should get the all clear.
I have a HTML page where a user is able to edit a HTML resource (using ACE Editor). Within this HTML source, there is a <script>-tag, which does some pretty basic stuff.
Is there any elegant solution to parse the script tag in order to (e.g.) evaluate the variables used within the script tag? For "normal" tags I use parseHTML() to have the html as a jQuery object.
From this example, I would like to retrieve the value of $myVal (which is "f00") and write it to #myLabel:
<textarea id="myScript" rows="5" readonly>
<script>
$myVal = "f00";
</script>
</textarea>
<label id="myLabel">Hello</label>
$(function(){
$scriptVar = $('#myScript').text;
// parse the $scriptVar
// retrieve the value of, $myVal, write it to #myLabel
//$myParsedValue = ???
//$('#myLabel').text('bar!');
});
And here is the fiddle: https://jsfiddle.net/stepdown/jqcut0sn/
Is this possible at all? I don't really care about vanilla js, jQuery, regex or maybe even an external library for that purpose.
Thanks to #JeremyThille, who pointed me to the right direction. I found out, what I want to achieve is possible through jQuerys $.globalEval() - see the official documentation.
Basically what globalEval() does: it runs the script which is written in the <textarea> and makes the variables / functions globally accessible.
IMPORTANT: this implies, that syntax errors (etc) by the user will break the evaluation, and sequential functionality could be flawed. Also, the new variables are GLOBAL, so basically a user could rewrite scripts on the hosting page. (In my case both problems are of minor importance, since this is an internal application for trained users - they also have syntax highlighting through the amazing ACE editor. But I wanted to make sure to point it out. Also, there are several articles regarding the risks/ouch-moments when using eval()...)
I updated the fiddle to achieve what I wanted: https://jsfiddle.net/stepdown/Lxz7q6uv/
HTML:
<textarea id="myScript" rows="5" readonly>
$myVal = "f00";
</textarea>
<hr />
<label id="myLabel">Hello</label>
Script:
$(function(){
var myScriptContent = $('#myScript').text();
$.globalEval(myScriptContent);
console.log($myVal);
$('#myLabel').text($myVal);
});
I am in the process of AJAX-ing a WordPress theme with a persistent music player. Wordpress uses dynamic classes on the <body> tag. The basic structure is as follows:
<html>
<head>
</head>
<body class="unique-class-1 unique-class-2 unique-class-3">
<div id="site-container">
<nav class="nav-primary">
Other Page 01
Other Page 02
</nav>
<div class="site-inner">
<p>Site Content Here</p>
</div>
</div>
<div id="music-player"></div>
</body>
</html>
I am currently successfully loading the content of /other-page-01/, /other-page-02/, etc, using load('/other-page-01/ #site-container'). However, I need to extract all <body> classes from the AJAX loaded page and replace the current page's <body> classes with them dynamically.
Note: Replacing the entire <body> element is not an option due to the persistent <div id="music-player">. I've tried jQuery.get(), but couldn't get it to work.
How do I extract the <body> classes from the AJAX requested page and replace the current page's <body> classes with them?
I am not very familiar with jQuery or Javascript, so the exact code would be extremely helpful. Any help is greatly appreciated.
Thanks,
Aaron
My typical solution would have been to tell you to throw the AJAX code in to a jQuery object and then read it out like normal:
$(ajaxResult).attr('class');
Interestingly though, it appears you can't do this with a <body> element.
I'd say the easiest solution (if you have control over the resulting HTML) is to just use some good ol' regex:
var matches = ajaxResult.match(/<body.*class=["']([^"']*)["'].*>/),
classes = matches && matches[1];
I say "if you have control over the resulting HTML", because this relies on the HTML being reasonably well formed.
The other method would involve parsing it as a DOMDocument and then extracting what you need, but this would take a lot more and is usually overkill in simple cases like this.
Convert the body within your returned html to a div with a specific ID, then target that id to get the classes of the body (which is now a div.)
modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div id="re_body"')
.replace(/<\/body/i,'</div');
$(modifiedAjaxResult).filter("#re_body").attr("class");
Of course, if the body has an id, this will conflict with it, so an arbitrary data attribute might be less likely to break.
modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div data-re-id="re_body"')
.replace(/<\/body/i,'</div');
$(modifiedAjaxResult).filter("[data-re-id=re_body]").attr("class");
http://jsfiddle.net/N68St/
Of course, to use this method, you'll have to switch to using $.get instead.
$.get("/other-page-01/",function(ajaxResult){
var modifiedAjaxResult = ajaxResult.replace(/<body/i,'<div data-re-id="re_body"')
.replace(/<\/body/i,'</div');
alert($(modifiedAjaxResult).filter("[data-re-id=re_body]").attr("class"));
// the following line replicates what `.load` was doing.
$(someElement).append( $("<div>").html(ajaxResult).find("#site-container") );
});
I have been searching about this subject now for quite a few days. And could not find a working or conclusive answer.
What I want to do, is to simply display the (styled) summary of the latest blog entry (from the blog page on my own site) in a div container on the front page of my site (which is not my blog). All active links of that mirrored blog entry ideally lead to the appropriate section of my blog page. That is however not a must, as long as the entire entry can link to the blog page.
Each blog entry summary on the blog summary page has a unique ID, sorted by numbers (e.g. unique-ID-51 (latest) unique-ID-50 (the one before) etc.)
I was thinking of doing so with the document.getElementById JS command.
I would have to point the JS function to a relative location (../blog_folder/blog_summary.html) with maybe the .window.location.assign
command, than grab the (styled) contents of the latest element and display that on my front page.
But I have no idea how that code would look in reality. Can you point me in the right direction?
Thank you !!!!!!!
M.
You could add jQuery to your page and use a simple construction:
$('.result-container').load('path/to/your/file.html #id_of_element_to_fetch');
An example chunk of code:
...
<body>
<div class="result-container">There will be your content from some file.</div>
<p>
<a class="result-loader" href="#"></a>
<script type="text/javascript">
$(".result-loader").click(function() {
//Replace path/to/your/file.html and #id_of_element_to_fetch with appropriate values
$('.result-container').load('path/to/your/file.html #id_of_element_to_fetch');
return false;
});
</script>
</p>
</body>
...
And that string somewhere inside the <head> tag:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
An example chunk of code with an autostart feature:
...
<body>
<div class="result-container">There will be your content from some file.</div>
<p>
<a class="result-loader" href="#"></a>
<script type="text/javascript">
$(document).ready(function() { //Launches the code below right after the initialization event
//Replace path/to/your/file.html and #id_of_element_to_fetch with appropriate values
$('.result-container').load('path/to/your/file.html #id_of_element_to_fetch');
return false;
});
</script>
</p>
</body>
...
I assume you are using a hidden iframe?
This for example will thet the height of the style.. there are other things in the style
this.container.getElementsByTagName("YOUuniqueID")[0].style.(STYLE)
But you have to put an unique ID in the iframe
Try and use the built in debuggers in IE or Chrome to find what you want...
You can take a look at this for maybe some more info(its for cross domain) but there could be something taht helps you. You might even consider using jquery to access that data.
Yet Another cross-domain iframe resize Q&A
I'm running my site through the W3C's validator trying to get it to validate as XHTML 1.0 Strict and I've gotten down to a particularly sticky (at least in my experience) validation error. I'm including certain badges from various services in the site that provide their own API and code for inclusion on an external site. These badges use javascript (for the most part) to fill an element that you insert in the markup which requires a child. This means that in the end, perfectly valid markup is generated, but to the validator, all it sees is an incomplete parent-child tag which it then throws an error on.
As a caveat, I understand that I could complain to the services that their badges don't validate. Sans this, I assume that someone has validated their code while including badges like this, and that's what I'm interested in. Answers such as, 'Complain to Flickr about their badge' aren't going to help me much.
An additional caveat: I would prefer that as much as possible the markup remains semantic. I.E. Adding an empty li tag or tr-td pair to make it validate would be an undesirable solution, even though it may be necessary. If that's the only way it can be made to validate, oh well, but please lean answers towards semantic markup.
As an example:
<div id="twitter_div">
<h2>#Twitter</h2>
<ul id="twitter_update_list">
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=twitterCallback2&count=1"></script>
</ul>
</div>
Notice the ul tags wrapping the javascript. This eventually gets filled in with lis via the script, but to the validator it only sees the unpopulated ul.
Thanks in advance!
The following fragment is valid XHTML and does the job:
<div id="twitter_div">
<h2 class="twitter-title">Twitter Updates</h2>
<div id="myDiv" />
</div>
<script type="text/javascript">
var placeHolderNode = document.getElementById("myDiv");
var parentNode = placeHolderNode.parentNode;
var insertedNode = document.createElement("ul");
insertedNode .setAttribute("id", "twitter_update_list");
parentNode.insertBefore( insertedNode, placeHolderNode);
parentNode.remove(placeHolderNode);
</script>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=twitterCallback2&count=5"></script>
Perhaps you could use javascript to write the initial badge HTML? You'd probably only want the badge code to be inserted in your document if javascript were available to populate it, right?
You'd just need to make sure your document writing happens before the javascript for your various badges.
Could you give a specific example of the HTML / link to a page with the invalid code?
The solutions might be different for each badge. In Twitter's case, you can just write your own callback function. Here's an example based on their badge code:
<div id="twitter_div">
<h2>#Twitter</h2>
<div id="twitter_update_list"></div>
</div>
<script type="text/javascript">
function updateTwitterCallback(obj)
{
var twitters = obj;
var statusHTML = "";
var username = "";
for (var i = 0; i < twitters.length; i++)
{
username = twitters[i].user.screen_name;
statusHTML += ('<li><span>' + twitters[i].text + '</span> <a style="font-size:85%" href="http://twitter.com/' + username + '/statuses/' + twitters[i].id + '">' + relative_time(twitters[i].created_at) + '</a></li>');
}
document.getElementById('twitter_update_list').innerHTML = '<ul>' + statusHTML + '</ul>';
}
</script>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/stopsineman.json?callback=updateTwitterCallback&count=1"></script>
I put a <li> with "display:none" in the <ul> Tag:
<ul id="twitter_update_list"><li style="display:none;">A</li></ul>
<script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script>
<script type="text/javascript" src="http://twitter.com/statuses/user_timeline/01241.json?callback=twitterCallback2&count=1"></script>
This does not disturb the script and in this case it works,
and I think its not a "undesirable solution" :)
At some point the page becomes valid, right? That's the only time it can really be validated.
I'm not sure a non-trivial page will remain valid at every point during its construction if it's constructed with a lot of DOM scripting.
This might not be the most popular opinion on this topic, but...
Don't worry about 100% validation. It's just not that big of a deal.
The point of validation is to make your markup as standard as possible. Why? Because browsers that are given markup that doesn't conform to the spec (eg, markup that does not validate) do their own error checking to correct it and display the page the way you intended it to look to the user. The quality of the browsers error checking varies, yadda-yadda-yadda, it's better to have valid markup... But it's not even your code that's causing the validation to fail! The people who wrote those badges probably tested them in multiple browsers (and you should do the same, of course), if they work as expected then just leave it at that.
In short, there's no prize for validating :)