Customizing external embed widget - javascript

I've been trying to customize an embedded widget from Zendesk on my website. Since they don't give any option to customize the look of its form, I would like to enforce my css rules.
I added this piece of code from Zendesk to have their form on my page.
<script type="text/javascript" src="https://leads-capturer.futuresimple.com/embed.js?token=ca98908sdgfgds9834234jlkjsdb">
This script places a form within an <iframe> and all nodes inside this <iframe> cannot be customized/changed.
I tried JS to set an inline style to form elements inside the <iframe>. Tried create a new stylesheet to override their original stylesheet but nothing seems to work.
Even something as simple as this code below, fails (#iframe-main-container is a child from <iframe>):
<script>
let p = document.querySelector('#iframe-main-container');
p.style.background = 'red';
</script>
If I change the code above and target <iframe>, it works.
My first question would be, is it possible to override an existing CSS rule from an embedded widget?
If this is possible, am I doing something wrong to change its looks?

Give this a try.
<script>
let iframe = document.getElementsByTagName("iframe");
let p = iframe[0].contentWindow.document.getElementById('#iframe-main-container');
p.style.background = 'red';
</script>

Related

Is it possible to do some client-side DOM manipulation before document ready?

I am trying to find a way (if possible) to use javascript to add some attributes to an element at render time and before the DOM is fully loaded. I know, that sounds counterproductive, but let me give you some background:
I'm working in an extremely limited templating platform that gives me access to some page variables, but they need some minor string manipulation. I can't leverage any of the ASP preprocessing so it has to happen on the client-side.
Specifically, I am trying to add Schema.org Microdata markup to an element before Googlebot scans through the document contents.
Essentially I need to modify an attribute value from $5.99 to 5.99.
Here's my most recent attempt, which makes the DOM modifications correctly, but not before Google's rich snippet validator processes the page:
<div class="pitinfo"><div class="padleft padright"><%Product.BasePrice%></div></div>
<!-- at page bottom -->
<script type="text/javascript">
(function() {
var pricesting = "<%Product.BasePrice%>";
var price = pricesting.slice(1);
$('.pitinfo').attr('itemprop', 'price');
$('.pitinfo').attr('content', price);
})();
</script>
After load I get this <div class="pitinfo" itemprop="price" content="9.99">$9.99</div>, however the Rich Snippet Testing tool tells me price is not set.
I have already tried using ASP in my template code but the hosting provider does not allow it.
Is it possible to make the DOM modifications sometime in the middle of the document rendering flow?
It is possible to insert a <script> tag inside of the <body>. JavaScript inside of the tag is loaded before the HTML after it, so you would be able to edit the element's value before the rest of the HTML/JS is loaded.
For example:
<div>
<div id="element" value="$5.99"></div>
<script>
var element = document.getElementById("element")
element.value = 5.99;
</script>
</div>
You can check it out here

Inserting CSS for an Element from a input field

Is there any easy way to take in a block of CSS from the user from an textarea and add this styling to the styling for a specific div?
See I'm creating a simple code preview tool like codePen, so far I have two textarea inputs, one for Html and one for CSS, as the user types in the Html input this updates the preview pane, this works, now I want to do it for CSS.
CSS textarea could contain a few blocks like:
h1 {
font-size:23px;
}
.myClass {
//Somestyle
}
Now I want this CSS to be contained in the
<div id="preview"></div>
So it doesnt effect the rest of the page, so a manual example would be
$('preview h1').css('font-size','23px');
Anyway to automate this?
Do it like this. Hope it works.
Add a style block for dynamic styling.
<style id="dynamicCss">
</style>
on the apply button click handler, set the style
$('#btnApplyStyle').click(function(){
$('#dynamicCss').html('').html($('#txtaCustomCss').val());
});
See the Fiddle here.
Please use developer tools to see the new style tag added to head section.
This script simply adds rule to the document. If you don't want that behavior, you can use this plugin in combination with my logic to set scope for rule. You will need to place the style tag inside of the container and add a scoped attribute to style for it to work. Please see the documentation.
If you want to use the iframe approach instead, you'll first need an HTML document to host inside of the iframe. The iframe document should be loaded for the same origin (protocol + domain) as the host document (cross-document cross-domain stuff is tricky otherwise). With your application, this is probably not an issue.
Host page:
<iframe id="preview" src="preview.html"></iframe>
To make things easier on yourself, this iframe document could load a script with convenience functions for injecting the HTML and CSS from the host.
preview.html:
<html>
<head>
<script src="preview.js"></script>
<style type="text/css" id="page-css"></style>
</head>
<body></body>
</html>
preview.js:
function setHTML(html) {
document.querySelector('body').innerHTML = html;
}
function setCSS(css) {
var stylesheet = document.querySelector('#page-css');
// Empty the stylesheet
while (stylesheet.firstChild) {
stylesheet.removeChild(stylesheet.firstChild);
}
// Inject new CSS
stylesheet.appendChild(document.createTextNode(css));
}
Now, from the host page, you can call these functions whenever your text inputs change:
document.querySelector('#preview').contentWindow.setCSS(someCSS);
This plugin may come in handy: https://github.com/websanova/wJSNova/downloads .
Edited
Insert the text of the rules in one of the existing cssStyleSheets you have.
It will be something like
window.document.styleSheets[0].insertRule("a{color:red;}",window.document.styleSheets[0].cssRules.length)
The first parameter is the rule to insert and the second is the index.
Fiddle
The only problem here is that this will affect all the DOM on the page maybe looking for a way to add the #preview before each css rule to get something like
#preview h1{}

Javascript Embedding Scripts onclick

What I would like to do is change the content of a div based on the different links clicked on the same page. Can anyone point me in the correct direction? AFAIK it could be dangerous to insert scripts directly into a page, changing text works okay but it seems I'm not sure about scripts. The content of the scripts are embed codes for video streaming. I realise this may not be the right way to go about it. My attempt won't work because of escaping the '<,>' characters and passing the parameter only seems to accept text with no spaces.
The way I've attempted it is as follows (in pseudocode);
function changeVideo(script){ div.innerhtml=script;}
then links that change the content of the div;
<a href='#' onclick=changeVideo('<iframe src=justin.tv etc..></iframe>')>
<a href='#' onclick=changeVideo('<iframe src=ustream.tv etc..></iframe>')>
You could drop the use of JavaScript and create an iFrame with a specified name to host the content; while giving the links a target tag. Thus making any links with the target tag specified appear within the named iFrame.
However if you insist upon using JavaScript you could consider the use of AJAX.
I suggest you to locate your a elements with unobstrusive Javascript, with getElementById() for example.
Once you have got them in variables like, lets say, a1 and a2, and the iFrame is in variable iframe do a code like this.
// ...a1 and a2 are anchors and iframe is the frame.
var srcSwitch = function(e)
{
e.preventDefault(); // this will prevent the anchor from redirecting you
iframe.src = this.src; // this changes the iFrame‘s source
};
a1.addEventListener('click', srcSwitch, 1);
a2.addEventListener('click', srcSwitch, 1); // and we register event listeners.
With this code, there is no need to insert Javascript within HTML attributes and you must only put the script URL in the anchors SRC attributes.
Tell me how it goes, greetings.
I may have generalised the question too much.
So I want to embed a stream on clicking a link. If the link is something like a proper URL
http://Jimey.tv/mystream
the iframe works, but loads the whole page. But I want to use the stream embed code to get just the player
The embed code looks similar to;
<script type = text/javascript> channel='mychannel' w='620' h='400'</script><script type=text/javascript> src="jimmy.tv/embed.js></script>
My original JavaScript method doesn't work because of escaping the < characters, and passing the embedcode seems to be problamatic. Hopefully I've made this a bit clearer?
<script>
iframe1 = '<iframe frameborder="0" scrolling="no" id="chat_embed" src="http://twitch.tv/chat/embed?channel=xenema&popout_chat=true" height="301" width="221"></iframe>'
</script>
link 1
link 2
<div id="videos">diiiiv</div>

How to change the CSS of entire page/website on click?

Is it possible to have 3-4 CSS on a page, and then on any event, say click, change the css for entire webpage. This way we can give our user the ability to change the theme. I know we can change the css of an element by:
$("#myElementID").removeClass("class1").addClass("class2");
Yes, it is possible. Typically what you would do is write a JavaScript function that will change, or add, or remove a style sheet from the <head> of the document. To make the experience a little better you'll typically store the user's preference in a cookie. There's an article on A List Apart that show how to implement this.
And of course, you can do this with jQuery... you may want to check out the source of jStyler.
The CSS Zen Garden (see the fifth question) ended up deciding that the easiest way was just to refresh the page and set a new CSS server side.
CSS is emdeded to DOM over 'link' tag, so you can locate this link and add/remove
Following code shows how to remove and add new one (I'm using MS AJAX see method $get, but you can replace it with pure DOM or other dialect):
var head = document.getElementsByTagName('head')[0];
var oldLink = $get("nameOfLink", head);
if(oldLink!=null)
head.removeChild(oldLink); //remove old entry
var s = document.createElement('link');
s.id="nameOfLink";
s.type = 'text/css';
s.rel="stylesheet";
s.charset ='utf-8';
s.href = "http://your-provided-url";
head.appendChild(s);
Usually best to load an external stylesheet (append a <link>): http://snipplr.com/view/3873/failsafe-load-for-attaching-stylesheet/
But if you need to create a bunch of styles on the fly, you can also build and append a <style> node to the DOM: http://jonraasch.com/blog/javascript-style-node

How can I create a javascript badge or widget?

I want to create a javascript badge that displays a list of links. We host the javascript on our domain. Other sites can put an empty div tag on their page and at the bottom a reference to our javascript that would render the content in the div tag. How do you implement something like this?
I would give the SCRIPT tag an ID and replace the script tag itself with the DIV + contents, making it so they only have to include one line of code. Something along the lines of the following:
<script id="my-script" src="http://example.com/my-script.js"></script>
In your script, you can swap out the SCRIPT tag for your DIV in one fell swoop, like so:
var scriptTag, myDiv;
scriptTag = document.getElementById('my-script');
myDiv = document.createElement('DIV');
myDiv.innerHTML = '<p>Wow, cool!</p>';
scriptTag.parentNode.replaceChild(myDiv, scriptTag);
just as you say, have them put a div at the bottom of their page:
<div id="mywidget"></div>
then have them link to your javascript:
<script type="text/javascript" src="http://yourdomain.com/mywidget.js"></script>
then have them alter their body tag, or onload to call your script
<script type="text/javascript">
document.body.onload = loadYourWidget();
</script>
You do not necessary need an initial div to fill with you link list.
Simply create the div using document.write at the place where the script is placed.
<script type="text/javascript" src="http://domain.com/badge.js"></script>
... and in your script:
var links = [
'One',
'Two',
'Three'
];
document.write("<div>" + links.join(", ") + "</div>");
Another benefit is that you do not have to wait for the page to be fully loaded.
Like #Owen said, except why not craft your javascript so that
<script type="text/javascript" src="http://yourdomain.com/mywidget.js"></script>
does the work of populating <div id="mywidget"></div> on its own, thus negating the need for them to call loadYourWidget() from their DOM load if you include the script tag right after the mywidget div in the html source. This isn't really a best practice, but I think it'll work.
Example for your mywidget.js code:
document.getElementById('mywidget').innerHTML = "<a href=''>LinkOne</a> <a href=''>LinkTwo</a>";
It took me some time to find this answer on Stackexchange because I was using different search terms. I believe that the link suggested there is a more complete answer than the ones already given here:
How to build a web widget (using jQuery)
It covers:
ensure the widget’s code doesn’t accidentally mess up with the rest of the page,
dynamically load external CSS and JavaScript files,
bypass browsers’ single-origin policy using JSONP.

Categories