How to add an extra classname on iframe, generated by DFP? - javascript

I have a DFP creative template that needs to work both on old and new site.
So on the new site (which has its own advertisement component js), I'd like to add a classname "redesign" on the DFP iframe. How do I do it properly?
In conclusion, I'd like to have same creative template on DFP with extra classname for new site.

DFP uses friendly iframes. In your creative template code, you can find this parent iframe and apply a classname if you want.
In the following example, I am rendering my creative template in a div called "mast_head". So the "mast_head"'s first child will be DFP's iframe.
Now in my creative template I can access this masthead element and apply a style attribute as follows:
parent.document.getElementById("mast_head").setAttribute("style","height:400px");
Does this make sense?

Solved it by using the plugin => https://github.com/mcountis/dfp-events
So on redesign ad.js component, I add a new classname "redesign".
window.googletag.cmd.push(function() {
window.googletag.on('gpt-slot_rendered', function(e,level,message,service,slot) {
var slotId = slot.getSlotId();
var $slot = $('#' + slotId.getDomId());
// DFP adds two iframes, one for calling scripts and one for displaying the ad. we want the one that is not hidden
if ($slot.find('iframe:not([id*=hidden])')
.map(function() { return this.contentWindow.document; })
.find('body')
.children().length > 0
) {
$slot.find('iframe').contents().find('body').addClass('redesign');
}
});
});

Related

Adding Javascript Widget to a Single Tumblr Post

I only do scientific programming so I am not too familiar with javascript. I am trying to add a widget to one single tumblr post. The website I got the widget from makes it specifically for tumblr and it is:
<div class="shopthepost-widget" data-widget-id="4665345"><script type="text/javascript">!function(w,i,d,g,e,t){d.getElementById(i)||(element=d.createElement(t),element.id=i,element.src="https://widgets.rewardstyle.com"+e,d.body.appendChild(element)),w.hasOwnProperty(g)===!0&&"complete"===d.readyState&&w[g].init()}(window,"shopthepost-script",document,"__stp","/js/shopthepost.js","script")</script><div class="rs-adblock"><img src="https://assets.rewardstyle.com/production/424ab6aff12fe31b5b93d8f5ce7cc70d2953e565/images/search/350.gif" onerror='this.parentNode.innerHTML="Disable your ad blocking software to view this content."' style="width: 15px; height: 15px"><noscript>JavaScript is currently disabled in this browser. Reactivate it to view this content.</noscript></div></div>
If this is added to the actual theme on tumblr, it works great. However, I am trying to put this in just one post on tumblr. When I'm trying to make the post I will go to the html and add it in there but it will not actually show up on the site. Any tips on how to solve this? Thank you in advance.
You have two choices available to you.
First: If you can host the javascript file somewhere remotely you can link it in the bottom of the post via the editor. The beauty of this is that you can update the js without having to update your main template.
For post edits you can select settings and choose HTML markup
then add a link to the script in the bottom of the page.
Or for a page edit it is the same concept you can switch to HTML markup and add it there.
Second: you can create a function in your template and then only fire it on the relevant post or page.
The way I have done this in the past is to get the post/page name from the file path, split the file path into an array and add them to the classnames for the html element. Example here:
const dom = document.querySelector('html');
const path = document.location.pathname.split('/');
const primaryDir = path[1]; // get the primary folder
const secondaryDir = path[2]; // get secondary folder
const tertiaryDir = path[3]; // get the tertiary folder
const setIndexPage = () => {
if (!primaryDir) { // if there is no primaryDir we should assume we are on the home/index page
dom.classList.add('index');
} else if (tertiaryDir) {
dom.classList.add(primaryDir + ' ' + secondaryDir + ' ' + tertiaryDir);
} else if (secondaryDir) {
dom.classList.add(primaryDir + ' ' + secondaryDir);
} else {
dom.classList.add(primaryDir);
}
}
Now we can target our function to run only if it finds the correct selector
if (document.querySelector('.yourClassName').length) {
// run your function here
}
For .yourClassName you need to pass in the page or post name. By default Tumblr will create a unique post id (integer) and add that to the filepath. But you can also use text/verbose file names in addition.
The beauty of this method, is that the classnames will be added to every page, but you can chose to target only certain posts/pages with your js function.
Alternatively you could use this method and add the html selector only to your post/page content. So wrap your content in a div and give that a unique id or classname, but the method is the same.
Here is an example of a page where I am doing this (although I am concatenating the class names slightly differently).
I hope this makes sense.

Add Span to Label ID

I'm trying to add a span to a label for which I don't have access to the HTML as it's output from RSForms Pro. I would like to add a tooltip span to individual labels so when the person rolls their mouse over, they get some information.
Here is what the code looks like:
<p class="rsformVerticalClear"><input name="form[Services_DM][]" type="checkbox" value="Death Records Retrieval/Search" id="Services_DM0"><label for="Services_DM0">Death Records Retrieval/Search</label></p>
The next option has the class Services_DM1 and so forth.
How do I go about adding a span to "Death Records Retrieval/Search" without having access to the actual code? Is there a way to inject it?
How are you inserting the code into your page? Anything embedded (such as an Iframe) will be barred from being manipulated from (or, IIRC, accessed by) your javascript due to XSS concerns.
Assuming your html and the loaded html are rendered into the same document, you'd want to use the HTML DOM functions to manipulate the html post load. This function should do what you want:
function addToolTip(elementid, content, classname) {
var theelement=document.getElementById(elementid);
var thetooltip=document.createElement('span');
var thetext = document.createTextNode(content);
thetooltip.appendChild(thetext);
thetooltip.setAttribute('class',classname);
theelement.appendChild(thetooltip);
}
To generate a tooltip, just call addToolTip with your label's element, whatever content text you'd like to see within the tooltip, and a css class (I figured you may want this for styling).
You can target all the labels with class starting from "Services_DM" and append a span to them:
try this jQuery sample snippet.
var $span = $('<span>My span contents here </span>');
$('label[class^="Services_DM"]').each(function(index,item){
$(this).append($span);
});
The above code is not tested, for reference purpose only!

JS wai-aria and dynamic content loaded with jQuery

I'm writing an web application which uses twitter bootstrap and aria. I have table with sort option which looks: .
My content is dynamically loading into #content div with jQuery.html() function. When I hit F5 everything works fine, but after I load content by jQuery to my div which contains these tables, something goes wrong. Tables loses their search options and pagination bars.. like this: .
There are few functionality which stop working too. How should I load dynamic content into my #content div?
My current code:
this.getContent = function(page){
var self = this;
$('#center-column').removeAttr("class");
if (page.indexOf('&') > 0)
$('#center-column').addClass( page.substr(0, page.indexOf('&') ) );
else $('#center-column').addClass( page );
$.get( $('body').attr('id')+".php?page="+page+"&mode=ajax",
function(data){
self.fetchData( data );
}, "json");
}
this.fetchData = function(data){
if (data.redirect_url != null)
window.location = data.redirect_url;
$("#content").html( data.html );
}
Is there any method aria has and I should call after I change content of my div dynamicly?
after I load content by jQuery to my div which contains these tables, something goes wrong. Tables loses their search options and pagination bars
Use .wrap to add dynamic content around the existing markup:
$("#content").html( $(data.html).wrap("#content") )
Is there any method aria has and I should call after I change content of my div dynamicly?
Use the aria-live attribute to indicate the content is dynamic, and assertive as the value.
$("#content").attr("aria-live", "assertive")
References
JSON-ARIA
Using ARIA role=alert or Live Regions to Identify Errors
Choosing Between Special Case Live Regions
aria-live (property)
ARIA Practices: Managing Dynamic Changes

Javascript show/hide - I don't want it to hide the entire element

This is probably a fairly easy question, but I'm new to JavaScript and jquery....
I have a website with a basic show/hide toggle. The show/hide function I'm using is here:
http://andylangton.co.uk/articles/javascript/jquery-show-hide-multiple-elements/
So here's my question..... I would really like the first 5-10 words of the toggled section to always be visible. Is there some way I can change it so that it doesn't hide the entire element, but hides all but the first few words of the element?
Here's a screenshot of what I would like it to do:
http://answers.alchemycs.com/mobile/images/capture.jpg
There are many different implementation possibilities:
You can divide the contents up into the first part and the second part (two separate spans or divs inside your main object) and hide only the child object that represents the second part, not hide the parent object.
Rather than hide the object at all, you can set its height to only show the first part (with overflow: hidden)
Change the contents of the main object to only have the first part as the contents (requires you to maintain the full contents somewhere else so you can restore it when expanded again).
Here's a working example of option 1: http://jsfiddle.net/jfriend00/CTzsP/.
You'd need to either:
Put in a span/etc. after the first n words, and only hide that part, or
Change the viewable region, or
Replace or toggle the span/etc. with the "collapsed" view.
The last is a bit more customizable; using two separate elements allows trivial games to be played (showing an image, for example, like a little curly arrow) without modifying adding/removing DOM elements.
I tend towards the last because it's simple and obvious, but that's a personal preference, and really isn't as true as it used to be.
You can do some plugin authoring,I did a sample demo here ,based on your screenshot
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
here is javascript/jquery code
jQuery.fn.myToggle = function(selector, count) {
var methods = {
toggle: function(selector, count) {
if ($(selector).is(':visible')) {
var span = $('<span>');
span.text($(selector).text().substr(0, count) + "...");
span.insertAfter($(selector));
$(selector).hide();
}
else {
$(selector).show();
$(selector).next('span').hide();
}
}
};
$(this).each(function() {
methods.toggle($(this).next(selector), count);
$(this).click(function(evt) {
methods.toggle($(this).next(selector), count);
});
});
};
$(function() {
$('.toggle').myToggle('.content', 3);
});
Here is a solution using css properties only instead of mangling the dom.
http://jsfiddle.net/AYre3/4/
Now if you want some sort of animation happening as well you'll probably need to do a bit of measurement along the way.

Changing content CSS on the run in TinyMCE or CKEditor

I have a form in which I want to edit a HTML template. It has 2 textareas, one for the HTML and another one for the CSS.
I'd like to use either TinyMCE or CKEditor for the HTML textarea.
Is there any way to change the content CSS in either of them to match the CSS in the CSS textarea on the run, so when I change the CSS it is automatically loaded into the editor?
Thanks.
I have no experience with CKEditor, but i know that it is possible with TinyMce. What you need to do is to write an own plugin which will provide the necessary functionality.
OnNodeChange in the 2nd textarea (the one with your css) you need to update the head of the first editors iframe. This code snippet to be executed on a special action (for example onNodeChange) should point you into the right direction:
var DEBUG = false;
var css_code = tinymce.editors[1].getContent(); // get content of 2nd editorinstance on page (your css)
iframe_id = tinymce.editors[0].id+'_ifr';
with(document.getElementById(iframe_id).contentWindow){
var h=document.getElementsByTagName("head");
if (!h.length) {
if (DEBUG) console.log('length of h is null');
return;
}
var newStyleSheet=document.createElement("style");
newStyleSheet.type="text/css";
h[0].appendChild(newStyleSheet);
try{
if (typeof newStyleSheet.styleSheet !== "undefined") {
newStyleSheet.styleSheet.cssText = css_code;
}
else {
newStyleSheet.appendChild(document.createTextNode(css_code));
newStyleSheet.innerHTML=css_code;
}
}
Be aware that this code will add a new style sheet everytime it is called - yielding in increasing the editor iframes head. So i think best practice is to clean up the last inserted style before appliing the new one. Removing the last Node of the head shozld be sufficient.

Categories