how to apply css and js dynamically - css

i have One xml file which contain some css and script links i want to apply this dynamically on page load i want to do this on page load please help?
xml File---
<template>
<theme id="1" name="default">
<css>
<name>css/style.css</name>
<name>css/normalize.css</name>
<name>css/grid.css</name>
<name>css/prettyPhoto.css</name>
</css>
<js>
<name>js/jquery.easing.1.3.js</name>
<name>js/jquery.prettyPhoto.js</name>
<name>js/js.js</name>
<name>js/jquery.stellar.min.js</name>
<name>js/waypoints.min.js</name>
</js>
</theme>
</template>
i have done this using jquery but the problem is when i adding debugger between
script and execute code step by step using firebug css and js applying and
without debugger loading in head but not applying can anyOne suggest
Xml File---
jquery Code implemented in aspx file
<script src="templates/1/jquery.xml2json.js"></script>
<script type="text/javascript">
//debugger
$.get('templates/1/SettingBasic2.xml', function (xml) {
var newTemplate = $.xml2json(xml);
$(newTemplate).each(function (key, data) {
$(window).load(function () {
switch (data.theme['name']) {
default:
$(data.theme['css']['name']).each(function (key_css, css) {
$('head').append('<link rel="stylesheet" href="' + css + '" type="text/css" media="all" />');
});
val = '';
$(data.theme['js']['name']).each(function (key_js, js) {
val += '<script type="text/javascript" src="' + js + '"></\script>';
});
$('head').append(val);
break;
}
});
});
</script>

i would like to say that you should use JS instead use, loadCSS.js for loading dynamic css, with control where to put what and also you can listen for when it gets loaded.
For scripts use $script.js which is smallest lib you can find or use require js which is the best for these stuff, but overkill for just loading scripts.

Related

Cannot load script in ViewComponent

I created a ViewComponent which display a Table that require some plugin for enable specific functionalities. Inside the ViewComponent I tried to create a specific section:
#section DataTableScripts{
<script src="~/js/JQuery/jquery.dataTables.js"></script>
}
unfortunately I discovered that a ViewComponent cannot load a #section.
So I tried to include the script directly in the ViewComponent, but the problem is that the scripts are loaded before of JQuery which is loaded inside the _Layout, specifically:
ViewComponent
<script src="~/js/JQuery/jquery.dataTables.js"></script>
<script src="~/js/JQuery/dataTables.buttons.min.js"></script>
<script src="~/js/JQuery/dataTables.keyTable.min.js"></script>
<script src="~/js/JQuery/dataTables.responsive.min.js"></script>
<script src="~/js/JQuery/dataTables.select.min.js"></script>
<script src="~/js/JQuery/dataTables.bootstrap4.js"></script>
<script src="~/js/JQuery/jquery.dataTables.js"></script>
Layout
<script src="~/js/jquery.min.js"></script>
so in this case I'll get:
jQuery is not defined
How can I manage this situation?
Simply set the Layout for your ViewComponent .
#{
Layout = "/Views/Shared/_Layout.cshtml";
}
#section DataTableScripts{
<div>It works </div>
<script src="~/js/JQuery/jquery.dataTables.js"></script>
}
Here's the screenshot that works :
[Edit]
This approach does not seems a good way to do that . As #Kirk Larkin says , this will make the Layout render twice . Another patch is to write a new RefinedLayout.cshtml and set the Layout of ViewComponent as the RefinedLayout :
#{
Layout = "_RefinedLayout.cshtml";
}
#section DataTableScripts{
<div>It works </div>
<script src="~/js/JQuery/jquery.dataTables.js"></script>
}
For more information , refer workaround by MortenMeisler
You are using<script src="~/js/JQuery/jquery.dataTables.js"></script> twice. Just keep it once.
Specifying another layout for viewcomponents with scripts will duplicate scripts. And #section is just ignored during rendering.
So I replaced jquery document ready with plain javascript domcontentloaded and any jquery can be written inside domcontentloaded. Not a permanent good approach but works for me.
<script>
document.addEventListener('DOMContentLoaded', function (event) {
console.log($ === jQuery)
});
</script>

"Optimize CSS Delivery" - Why Google uses this much code to load CSS file?

This is Google Optimize CSS Delivery page. At the bottom google suggests use this code to load CSS file at the end of the page body:
<noscript id="deferred-styles">
<link rel="stylesheet" type="text/css" href="small.css"/>
</noscript>
<script>
var loadDeferredStyles = function() {
var addStylesNode = document.getElementById("deferred-styles");
var replacement = document.createElement("div");
replacement.innerHTML = addStylesNode.textContent;
document.body.appendChild(replacement)
addStylesNode.parentElement.removeChild(addStylesNode);
};
var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
else window.addEventListener('load', loadDeferredStyles);
</script>
</body>
My questions is why not just use this one line to do the job? Especially we are in HTML5 world.
<link rel="stylesheet" type="text/css" href="small.css"/>
</body>
When a browser is parsing an HTML response, it does so line by line. And when it encounters a <link> element, it stops parsing the HTML and goes to fetch the resource set by the element's href attribute.
What the code is doing is wrapping the CSS in a <noscript> element as a fallback, and instead of blocking the page load, making a request for the CSS after the page has finished loading. It is a way to manually give a <link> element similar behavior to the <script> element's defer attribute.

css not overriding external css? [duplicate]

I have a simple page that has some iframe sections (to display RSS links). How can I apply the same CSS format from the main page to the page displayed in the iframe?
Edit: This does not work cross domain unless the appropriate CORS header is set.
There are two different things here: the style of the iframe block and the style of the page embedded in the iframe. You can set the style of the iframe block the usual way:
<iframe name="iframe1" id="iframe1" src="empty.htm"
frameborder="0" border="0" cellspacing="0"
style="border-style: none;width: 100%; height: 120px;"></iframe>
The style of the page embedded in the iframe must be either set by including it in the child page:
<link type="text/css" rel="Stylesheet" href="Style/simple.css" />
Or it can be loaded from the parent page with Javascript:
var cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['iframe1'].document.head.appendChild(cssLink);
I met this issue with Google Calendar. I wanted to style it on a darker background and change font.
Luckily, the URL from the embed code had no restriction on direct access, so by using PHP function file_get_contents it is possible to get the
entire content from the page. Instead of calling the Google URL, it is possible to call a php file located on your server, ex. google.php, which will contain the original content with modifications:
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
Adding the path to your stylesheet:
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
(This will place your stylesheet last just before the head end tag.)
Specify the base url form the original url in case css and js are called relatively:
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
The final google.php file should look like this:
<?php
$content = file_get_contents('https://www.google.com/calendar/embed?src=%23contacts%40group.v.calendar.google.com&ctz=America/Montreal');
$content = str_replace('</title>','</title><base href="https://www.google.com/calendar/" />', $content);
$content = str_replace('</head>','<link rel="stylesheet" href="http://www.yourwebsiteurl.com/google.css" /></head>', $content);
echo $content;
Then you change the iframe embed code to:
<iframe src="http://www.yourwebsiteurl.com/google.php" style="border: 0" width="800" height="600" frameborder="0" scrolling="no"></iframe>
Good luck!
If the content of the iframe is not completely under your control or you want to access the content from different pages with different styles you could try manipulating it using JavaScript.
var frm = frames['frame'].document;
var otherhead = frm.getElementsByTagName("head")[0];
var link = frm.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "style.css");
otherhead.appendChild(link);
Note that depending on what browser you use this might only work on pages served from the same domain.
var $head = $("#eFormIFrame").contents().find("head");
$head.append($("<link/>", {
rel: "stylesheet",
href: url,
type: "text/css"
}));
Here is how to apply CSS code directly without using <link> to load an extra stylesheet.
var head = jQuery("#iframe").contents().find("head");
var css = '<style type="text/css">' +
'#banner{display:none}; ' +
'</style>';
jQuery(head).append(css);
This hides the banner in the iframe page. Thank you for your suggestions!
If you control the page in the iframe, as hangy said, the easiest approach is to create a shared CSS file with common styles, then just link to it from your html pages.
Otherwise it is unlikely you will be able to dynamically change the style of a page from an external page in your iframe. This is because browsers have tightened the security on cross frame dom scripting due to possible misuse for spoofing and other hacks.
This tutorial may provide you with more information on scripting iframes in general. About cross frame scripting explains the security restrictions from the IE perspective.
An iframe is universally handled like a different HTML page by most browsers. If you want to apply the same stylesheet to the content of the iframe, just reference it from the pages used in there.
The above with a little change works:
var cssLink = document.createElement("link")
cssLink.href = "pFstylesEditor.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
//Instead of this
//frames['frame1'].document.body.appendChild(cssLink);
//Do this
var doc=document.getElementById("edit").contentWindow.document;
//If you are doing any dynamic writing do that first
doc.open();
doc.write(myData);
doc.close();
//Then append child
doc.body.appendChild(cssLink);
Works fine with ff3 and ie8 at least
The following worked for me.
var iframe = top.frames[name].document;
var css = '' +
'<style type="text/css">' +
'body{margin:0;padding:0;background:transparent}' +
'</style>';
iframe.open();
iframe.write(css);
iframe.close();
Expanding on the above jQuery solution to cope with any delays in loading the frame contents.
$('iframe').each(function(){
function injectCSS(){
$iframe.contents().find('head').append(
$('<link/>', { rel: 'stylesheet', href: 'iframe.css', type: 'text/css' })
);
}
var $iframe = $(this);
$iframe.on('load', injectCSS);
injectCSS();
});
use can try this:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
If you want to reuse CSS and JavaScript from the main page maybe you should consider replacing <IFRAME> with a Ajax loaded content. This is more SEO friendly now when search bots are able to execute JavaScript.
This is jQuery example that includes another html page into your document. This is much more SEO friendly than iframe. In order to be sure that the bots are not indexing the included page just add it to disallow in robots.txt
<html>
<header>
<script src="/js/jquery.js" type="text/javascript"></script>
</header>
<body>
<div id='include-from-outside'></div>
<script type='text/javascript'>
$('#include-from-outside').load('http://example.com/included.html');
</script>
</body>
</html>
You could also include jQuery directly from Google: http://code.google.com/apis/ajaxlibs/documentation/ - this means optional auto-inclusion of newer versions and some significant speed increase. Also, means that you have to trust them for delivering you just the jQuery ;)
My compact version:
<script type="text/javascript">
$(window).load(function () {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
});
</script>
However, sometimes the iframe is not ready on window loaded, so there is a need of using a timer.
Ready-to-use code (with timer):
<script type="text/javascript">
var frameListener;
$(window).load(function () {
frameListener = setInterval("frameLoaded()", 50);
});
function frameLoaded() {
var frame = $('iframe').get(0);
if (frame != null) {
var frmHead = $(frame).contents().find('head');
if (frmHead != null) {
clearInterval(frameListener); // stop the listener
frmHead.append($('style, link[rel=stylesheet]').clone()); // clone existing css link
//frmHead.append($("<link/>", { rel: "stylesheet", href: "/styles/style.css", type: "text/css" })); // or create css link yourself
}
}
}
</script>
...and jQuery link:
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.min.js" type="text/javascript"></script>
As many answers are written for the same domains, I'll write how to do this in cross domains.
First, you need to know the Post Message API. We need a messenger to communicate between two windows.
Here's a messenger I created.
/**
* Creates a messenger between two windows
* which have two different domains
*/
class CrossMessenger {
/**
*
* #param {object} otherWindow - window object of the other
* #param {string} targetDomain - domain of the other window
* #param {object} eventHandlers - all the event names and handlers
*/
constructor(otherWindow, targetDomain, eventHandlers = {}) {
this.otherWindow = otherWindow;
this.targetDomain = targetDomain;
this.eventHandlers = eventHandlers;
window.addEventListener("message", (e) => this.receive.call(this, e));
}
post(event, data) {
try {
// data obj should have event name
var json = JSON.stringify({
event,
data
});
this.otherWindow.postMessage(json, this.targetDomain);
} catch (e) {}
}
receive(e) {
var json;
try {
json = JSON.parse(e.data ? e.data : "{}");
} catch (e) {
return;
}
var eventName = json.event,
data = json.data;
if (e.origin !== this.targetDomain)
return;
if (typeof this.eventHandlers[eventName] === "function")
this.eventHandlers[eventName](data);
}
}
Using this in two windows to communicate can solve your problem.
In the main windows,
var msger = new CrossMessenger(iframe.contentWindow, "https://iframe.s.domain");
var cssContent = Array.prototype.map.call(yourCSSElement.sheet.cssRules, css_text).join('\n');
msger.post("cssContent", {
css: cssContent
})
Then, receive the event from the Iframe.
In the Iframe:
var msger = new CrossMessenger(window.parent, "https://parent.window.domain", {
cssContent: (data) => {
var cssElem = document.createElement("style");
cssElem.innerHTML = data.css;
document.head.appendChild(cssElem);
}
})
See the Complete Javascript and Iframes tutorial for more details.
Other answers here seem to use jQuery and CSS links.
This code uses vanilla JavaScript. It creates a new <style> element. It sets the text content of that element to be a string containing the new CSS. And it appends that element directly to the iframe document's head.
var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
'.some-class-name {' +
' some-style-name: some-value;' +
'}'
;
iframe.contentDocument.head.appendChild(style);
When you say "doc.open()" it means you can write whatever HTML tag inside the iframe, so you should write all the basic tags for the HTML page and if you want to have a CSS link in your iframe head just write an iframe with CSS link in it. I give you an example:
doc.open();
doc.write('<!DOCTYPE html><html><head><meta charset="utf-8"/><meta http-quiv="Content-Type" content="text/html; charset=utf-8"/><title>Print Frame</title><link rel="stylesheet" type="text/css" href="/css/print.css"/></head><body><table id="' + gridId + 'Printable' + '" class="print" >' + out + '</table></body></html>');
doc.close();
You will not be able to style the contents of the iframe this way. My suggestion would be to use serverside scripting (PHP, ASP, or a Perl script) or find an online service that will convert a feed to JavaScript code. The only other way to do it would be if you can do a serverside include.
Incase if you have access to iframe page and want a different CSS to apply on it only when you load it via iframe on your page, here I found a solution for these kind of things
this works even if iframe is loading a different domain
check about postMessage()
plan is, send the css to iframe as a message like
iframenode.postMessage('h2{color:red;}','*');
* is to send this message irrespective of what domain it is in iframe
and receive the message in iframe and add the received message(CSS) to that document head.
code to add in iframe page
window.addEventListener('message',function(e){
if(e.data == 'send_user_details')
document.head.appendChild('<style>'+e.data+'</style>');
});
I think the easiest way is to add another div, in the same place as the iframe, then
make its z-index bigger than the iframe container, so you can easly just style your own div. If you need to click on it, just use pointer-events:none on your own div, so the iframe would be working in case you need to click on it ;)
I hope It will help someone ;)
I found another solution to put the style in the main html like this
<style id="iframestyle">
html {
color: white;
background: black;
}
</style>
<style>
html {
color: initial;
background: initial;
}
iframe {
border: none;
}
</style>
and then in iframe do this (see the js onload)
<iframe onload="iframe.document.head.appendChild(ifstyle)" name="log" src="/upgrading.log"></iframe>
and in js
<script>
ifstyle = document.getElementById('iframestyle')
iframe = top.frames["log"];
</script>
It may not be the best solution, and it certainly can be improved, but it is another option if you want to keep a "style" tag in parent window
Here, There are two things inside the domain
iFrame Section
Page Loaded inside the iFrame
So you want to style those two sections as follows,
1. Style for the iFrame Section
It can style using CSS with that respected id or class name. You can just style it in your parent Style sheets also.
<style>
#my_iFrame{
height: 300px;
width: 100%;
position:absolute;
top:0;
left:0;
border: 1px black solid;
}
</style>
<iframe name='iframe1' id="my_iFrame" src="#" cellspacing="0"></iframe>
2. Style the Page Loaded inside the iFrame
This Styles can be loaded from the parent page with the help of Javascript
var cssFile = document.createElement("link")
cssFile.rel = "stylesheet";
cssFile.type = "text/css";
cssFile.href = "iFramePage.css";
then set that CSS file to the respected iFrame section
//to Load in the Body Part
frames['my_iFrame'].document.body.appendChild(cssFile);
//to Load in the Head Part
frames['my_iFrame'].document.head.appendChild(cssFile);
Here, You can edit the Head Part of the Page inside the iFrame using this way also
var $iFrameHead = $("#my_iFrame").contents().find("head");
$iFrameHead.append(
$("<link/>",{
rel: "stylesheet",
href: urlPath,
type: "text/css" }
));
We can insert style tag into iframe.
<style type="text/css" id="cssID">
.className
{
background-color: red;
}
</style>
<iframe id="iFrameID"></iframe>
<script type="text/javascript">
$(function () {
$("#iFrameID").contents().find("head")[0].appendChild(cssID);
//Or $("#iFrameID").contents().find("head")[0].appendChild($('#cssID')[0]);
});
</script>
var link1 = document.createElement('link');
link1.type = 'text/css';
link1.rel = 'stylesheet';
link1.href = "../../assets/css/normalize.css";
window.frames['richTextField'].document.body.appendChild(link1);
This is how I'm doing in production. It's worth bearing in mind that if the iframe belongs to other website, it will trigger the CORS error and will not work.
var $iframe = document.querySelector(`iframe`);
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
In some cases you may also want to attach a load event to the iframe:
var $iframe = document.querySelector(`iframe`);
$iframe.addEventListener("load", function() {
var doc = $iframe.contentDocument;
var style = doc.createElement("style");
style.textContent = `*{display:none!important;}`;
doc.head.append(style);
});
There is a wonderful script that replaces a node with an iframe version of itself.
CodePen Demo
Usage Examples:
// Single node
var component = document.querySelector('.component');
var iframe = iframify(component);
// Collection of nodes
var components = document.querySelectorAll('.component');
var iframes = Array.prototype.map.call(components, function (component) {
return iframify(component, {});
});
// With options
var component = document.querySelector('.component');
var iframe = iframify(component, {
headExtra: '<style>.component { color: red; }</style>',
metaViewport: '<meta name="viewport" content="width=device-width">'
});
As an alternative, you can use CSS-in-JS technology, like below lib:
https://github.com/cssobj/cssobj
It can inject JS object as CSS to iframe, dynamically
This is just a concept, but don't implement this without security checks and filtering! Otherwise script could hack your site!
Answer: if you control target site, you can setup the receiver script like:
1) set the iframe link with style parameter, like:
http://your_site.com/target.php?color=red
(the last phrase is a{color:red} encoded by urlencode function.
2) set the receiver page target.php like this:
<head>
..........
$col = FILTER_VAR(SANITIZE_STRING, $_GET['color']);
<style>.xyz{color: <?php echo (in_array( $col, ['red','yellow','green'])? $col : "black") ;?> } </style>
..........
Well, I have followed these steps:
Div with a class to hold iframe
Add iframe to the div.
In CSS file,
divClass { width: 500px; height: 500px; }
divClass iframe { width: 100%; height: 100%; }
This works in IE 6. Should work in other browsers, do check!

Is it possible to load Mootools in a parent frame and then re-use it in iframes?

Example
-- begin: index.html --
<!doctype html>
<html>
<head>
<title>Index</title>
<script type="text/javascript" src="mootools.js"></script>
</head>
<body>
<iframe src="iframe.html" id="innerFrame">blah</iframe>
</body>
</html>
-- end: index.html --
-- begin: iframe.html --
<!doctype html>
<html>
<head>
<title>iFrame</title>
</head>
<body>
<form>
<input id="inputField" type="text" value="this is text." />
</form>
<script type="text/javascript">
$('inputField').set('value', 'updated text');
</script>
</body>
</html>
-- end: iframe.html --
Currently, $('inputField').set('value', 'updated text'); doesn't work :-\
Yes, assuming the iframe and it's parent window are on the same domain, it is possible to load the Mootools scripts once in the parent, and then programmatically extend the IFrame's window and document, instead of re-loading the script within the iframe. It is not the default behavior, as you've noticed, and probably for good reason - I'm guessing most people will tell you it's more trouble than it's worth.
In fact, the IFrame shortcut element constructor used to do that exact thing, but it was ultimately considered to be too much of a hack and not worth the effort to maintain as part of the framework long-term, so they dropped it - this why the documentation for IFrame is kind of odd ("IFrame Method: constructor, Creates an IFrame HTML Element and extends its window and document with MooTools.", and then right below after the example, "Notes: An IFrame's window and document will not be extended with MooTools methods.").
So, the most straightforward way to have $(..) useable in your iframe is just to have the iframe include the Mootools script. If you're feeling fancy, you could also have your parent window inject the Mootools script into the iframe's HEAD, for example:
index.html
<html>
<head>
<title>Parent</title>
<script type="text/javascript" src="mootools.js"></script>
</head>
<body>
<iframe id="innerFrame"></iframe>
<script type="text/javascript">
var mooFrame = new IFrame("innerFrame", {
src:"iframe.html",
events: {
load: function(){
var mooEl = new Element('script', {
type: 'text/javascript',
src: "mootools.js",
events: {
load: function(){
//passed to mooFrame by the iframe
this.pageReady();
}.bind(this)
}
});
this.contentDocument.head.appendChild(mooEl);
}
}
});
</script>
</body>
</html>
iframe.html
<html>
<head>
<title>Iframe</title>
</head>
<body>
<div id="iframe_element"></div>
<script type="text/javascript">
parent.mooFrame.pageReady = function(){
/* Put your iframe javascript in here */
$('iframe_element').set("text", "Fancy!");
};
</script>
</body>
</html>
Update (July 29th): I was fooling around with this idea again and realized there's a fairly obvious though pretty ham-fisted way to transfer Mootools functionality defined in the parent index.html window to the inner iframe: simply include the entire Mootools source into the parent window (remove the src attribute from the existing script element and add an id), and copy that newly enormous element's text into the new script node that gets injected into the head of the iframe. Inlining the Mootools code in the script element in this fashion gives you access to the contents of the element, which you don't get when the javascript is loaded from an external file via the src attribute.
Of course, this..concept is only relevant if the parent window and iframe are on the same-domain, (same as the code provided above).
The obvious drawback is that the Mootools source isn't cached. I'm not sure if there's a use-case where this method would be more optimal than just including mootools in both parent and iframe. In any event, change the index.html file to this:
<html>
<head>
<title>Parent</title>
<script type="text/javascript" id="mootools_js">
**COPY-PASTE THE CONTENTS OF mootools-core.js HERE**
</script>
</head>
<body>
<iframe id="innerFrame"></iframe>
<script type="text/javascript">
var mooFrame = new IFrame("innerFrame", {
src:"iframe.html",
events: {
load: function(){
var mooEl = new Element('script', {
id: 'mootools_iframe_core',
type: 'text/javascript',
html: $('mootools_js').innerHTML
});
this.contentDocument.head.appendChild(mooEl);
this.pageReady();
}
}
});
</script>
</body>
</html>
My previous answer offered two alternative ways of doing the task in question ("load Mootools in a parent frame and then re-use it in iframes"). The first method didn't "re-use" the Mootools functionality loaded into the parent frame, but was rather an alternative way to load the script in the inner iframe. The second method was just a hacky way of copying over the script by putting the entire mootools core source inline in a script element and then copying that element's content into a script element in the iframe's head (hardly optimal).
This following method does programatically extend the window and document objects of the inner iframe. Again, it is assumed that both the parent page and the iframe are on the same domain.
In my (brief and simple) testing, loading the source in both parent and iframe resulted in 72.1 KB transferred at around 130ms (to finish loading both the parent and iframe pages), while the page that loaded the source and then extended the iframe was 36.8 KB and took around 85ms to load both parent and iframe. (that's with gzip on the server...file size of uncompressed/unminified core source is around 134 kb).
For this method a few trivial additions/edits are made to the mootools core source. Download an uncompressed version of mootools-core-1.3.2.js, and rename it to 'mootools-core-init.js' (or whatever). The following steps assume that you checked all boxes on the core builder page except 'Include Compatibility'.
Add this to the top of the 'mootools-core-init.js' file (above the first self-calling anonymous function):
var initMootoolsCore = function(){
var window = this;
var document = this.document;
Add this to the very bottom of the core js file:
};
initMootoolsCore.call(window);
Do the following find/replace tasks:
1
Find:})();
Replace: }).call(this);
2
Find: if (Browser.Element) Element.prototype = Browser.Element.prototype;
Replace: if (this.Browser.Element) Element.prototype = this.Browser.Element.prototype;
3
Find: var IFrame = new Type
Replace: var IFrame = this.IFrame = new Type
4
Find: var Cookie = new Class
Replace: var Cookie = this.Cookie = new Class
(download | compressed version)
In your parent index.html file, put the following script element in the head
<script type="text/javascript" src="mootools-core-init.js"></script>
Finally, in your iframe.html file, put the following inline script element in the head to extend the iframe's window and document (it must be before any included or inline scripts that need to use Mootools):
<script type="text/javascript">parent.initMootoolsCore.call(window);</script>
No, the iframe.html is an independent page. It does not "inherit" anything from the previous page.

DotNetNuke - jQuery - Why is this jQuery Watermark plugin not working?

I'm using DNN 5.4 with the default google api jquery reference:
I have confirmed that jquery.min.js is loading. I don't know if there's other jQuery (other than the plugin) that needs to be loaded.
I'm utilizing the Google Code jQuery Textbox Watermark Plugin (Link)
Web Dev Toolbar & Firebug suggest that both jQuery and the Watermark Plugin are loading. This code is sitting near the top of my skin .ascs:
<script type="text/javascript" src="/js/watermark/jquery.watermark.min.js"></script>
The following code works (when the inputs are wrapped in form tags) in basic html document. However, when placed inside either a DNN skin or DNN module, it fails to work and generates a javascript here.
<script language="javascript" type="text/javascript">
(function ($) {
$(document).ready(function () {
jQuery("#xsearch").watermark("Leave blank for USA");
})
})(jQuery);
</script>
SearchString: <input type="text" id="xsearch" name="xsearch" />
<input type="button" value="search" id="xsubmit" name="xsubmit" />
The Error (FireBug):
jQuery("#xsearch").watermark is not a function
[Break on this error] jQuery("#xsearch").watermark("Leave blank for USA");
This alternate code produces the same error:
<script language="javascript" type="text/javascript">
jQuery.noConflict();
jQuery(function () {
jQuery("#xsearch").watermark("Leave blank for USA");
jQuery("#xsubmit").click(
function () {
jQuery("#xsearch")[0].focus();
}
);
});
</script>
And finally, the same error is produced when I replace jQuery with $
It feels like a conflict of some sort, but I'm lost on what to do next.
Thanks in advance for your time
I noticed this is because :
<script type="text/javascript" src="/js/watermark/jquery.watermark.min.js">
should be
<script type="text/javascript" src="js/watermark/jquery.watermark.min.js">
If you are having js folder in your skin root.
You can see FireBug's net tab to make sure your script reference is loading properly. I'm judging this because I've done lots of dnn development and the link you referenced will become
http://www.mydomain.com/tabId/80/js/watermark/jquery.watermark.min.js when http://www.mydomain.com/tabId/80/Default.aspx is served

Resources