Am wondering how it would be possible to unload a CSS from a page. e.g. In my page I have included a file called a.css. Now I want the user to be able to change the theme, which is CSS driven, thus he/she should be able to unload a.css and then I can load b.css (else they will conflict)
Any idea how to go about this?
Take the link element and disable it
document.getElementsByTagName('link')[0].disabled = true;
With jquery, this works:
$("link[href='fileToRemove.css']").remove();
Obviously, replace fileToRemove.css with the relative path and filename of the file to be unloaded.
var firstLink = document.getElementsByTagName('link')[0];
firstLink.parentNode.removeChild(firstLink)
This would remove the first link element on the page - not sure how your html is structured but I'm sure you can use it as an example. You might want to check the type attribute if it's 'text/css' and you're targeting the right media (screen), or possibly check if the href contains 'css' anywhere if you have other link elements that aren't css references.
Note you can also re-set the href attribute to point to a non-existing page instead of removing the element entirely.
Oddly enough, IE and firefox support the disabled attribute, but neither Chrome, Safari, nor Opera support it. So, this should be the most cross-browser solution.
// Disables a particular stylesheet given its DOM Element
function unload_stylesheet(DOMelement){
DOMelement.disabled = true;
DOMelement.parentNode.removeChild( DOMelement );
DOMelement.href = "data:text/css,"; // empty stylesheet to be sure
}
// Usage:
unload_stylesheet( document.getElementsByTagName('link')[0] );
Related
I have this HTML:
Track Your Package »
Somebody on this site was able to provide me with a script to prefix the URL with the domain http://www.example.com/ Here's the script:
$(document).ready(function(){
$('a[onclick^="window.open(\'TrackPackage.asp"]').attr('onClick', $('a[onclick^="window.open(\'TrackPackage.asp"]').attr('onClick').replace("window.open('", "window.open('http://www.example.com/"));
});
However, I am having a little trouble with this:
The first issue is where there is multiple instances of the element. Here's a fiddle: http://jsfiddle.net/VMmZx/
Instead of one anchor being signed with ID=4 and the other with ID=5 as intended, they're both being signed with ID=4.
The idea is, each window.open function should be prefixed with http://www.example.com however, the remainder of the URL should remain intact...
The second problem I'm encountering is when the element does not exist on a page, the remainder of the jQuery fails...
Here's another fiddle: http://jsfiddle.net/VPf32/
The <a> should get the class foo, but since the element does not exist on the page, the jQuery does not execute.
Since the JavaScript is being included in the HTML template of the ASP.NET server, this can create many problems.
I hope I've been clear and you can help me. Thanks.
You can use .each() to iterate over each matching element and change them individually:
$('a[onclick^="window.open(\'TrackPackage.asp"]').each(function(index, element) {
element = $(element);
element.attr('onclick', element.attr('onclick').replace(/open\('/, 'open(\'http://www.example.com/'));
});
However, I don't think using links with a href of # and an onclick opening a window is as semantic as it could be. If possible, try changing the markup to this:
Track Your Package »
Now if someone is curious where it will lead them, the browser can show something useful in the status bar when you hover over it.
If you need to adjust the behavior further, add a class and bind for the click event. When they click, prevent the default action and open the window yourself, as you did before.
Why are you doing the click even inline like that? I would just output the links like:
Link Text
And then:
$('a[target=_blank]').click(function(){
var prefix = 'http://domain.com';
window.open(prefix + $(this).attr('href'));
});
I'm writing a Javascript file which will be a component in a webpage. I'd like it to be simple to use - just reference the script file in your page, and it is there. To that end however there is a complication - where should the HTML go that the Javascript generates? One approach would be to require a placeholder element in the page with a fixed ID or class or something. But that's an extra requirement. It would be better if the HTML was generated at the location that the script is placed (or, at the start of body, if the script is placed in head). Also, for extra customizability, if the fixed ID was found, the HTML would be placed inside that placeholder.
So I'm wondering - how do I detect my script's location in the page? And how do I place HTML there? document.write() comes to mind, but that is documented as being pretty unreliable. Also it doesn't help if the script is in the head. Not to mention what happens if my script is loaded dynamically via some AJAX call, but I suppose that can be left as an unsupported scenario.
I am doing that with this code...
// This is for Firefox only at the moment.
var thisScriptElement = document.currentScript,
// Generic `a` element for exploiting its ability to return `pathname`.
a = document.createElement('a');
if ( ! thisScriptElement) {
// Iterate backwards, to look for our script.
var scriptElements = document.body.getElementsByTagName('script'),
i = scriptElements.length;
while (i--) {
if ( ! scriptElements[i].src) {
continue;
}
a.href = scriptElements[i].src;
if (a.pathname.replace(/^.*\//, '') == 'name-of-your-js-code.js') {
thisScriptElement = scriptElements[i];
break;
}
}
}
Then, to add your element, it's simple as...
currentScript.parentNode.insertBefore(newElement, currentScript);
I simply add a script element anywhere (and multiple times if necessary) in the body element to include it...
<script type="text/javascript" src="somewhere/name-of-your-js-code.js?"></script>
Ensure the code runs as is, not in DOM ready or window's load event.
Basically, we first check for document.currentScript, which is Firefox only but still useful (if it becomes standardised and/or other browsers implement it, it should be most reliable and fastest).
Then I create a generic a element to exploit some of its functionality, such as extracting the path portion of the href.
I then iterate backwards over the script elements (because in parse order the last script element should be the currently executing script), comparing the filename to what we know ours is called. You may be able to skip this, but I am doing this to be safe.
document.write is very reliable if used as you indicate (a default SharePoint 2010 page uses it 6 times). If placed in the head, it will write content to immediately after the body element. The trick is to build a single string of HTML and write it in one go, don't write snippets of half-formed HTML.
An alternative is to use document.getElementsByTagName('script') while the document is loading and assume the the last one is the current script element. Then you can look at the parent and if it's the head, use the load or DOM ready event to add your elements after the body. Otherwise, just add it before or after the script element as appropriate.
Quick question regarding Javascript. I'm working on a Safari Extension for paring down the Google Search page, and I'd like to change the Google logo to a custom image. My plan is to have an injected .js script to put in the extension.
So far, I've tried this:
document.getElementById('img#hplogo').innerHTML =
"<img alt="Google" height="95" id="hplogo" src="logo3w.png" width="275"
style="padding-top:136px" onload="window.lol&&lol()">"
For some clarification, the logo image is under the ID on the Google homepage as "hplogo" or according to Safari Web Inspector, "img#hplogo". I want to replace the src, obviously, with my own logo3w.png that will be located in the root of the extension folder (thus, AFAIK, no advanced directory is needed).
If I could be pointed in the right direction command-wise, that'd be really helpful, but really any and all help is appreciated. Thanks!
You want to do:
document.getElementById("hplogo").src = "logo3w.png";
Note that the "img#hplogo" is not saying that the id of the img element is "img#hplogo", it is saying that you are looking at an "img" element whose id is "hplogo". So when using document.getElementById() you only need to pass "hplogo". In CSS you might say:
img #hplogo {
display: none; //or whatever
}
#hplogo {
display: none; //or whatever
}
And similarly with something like jQuery that supports CSS-style element selectors you might say:
var image = $("#hpLogo");
var theSameImage = $("img #hplogo");
But for document.getElementById() all you need to pass (and all you can pass) is "hplogo".
You may want to change the src attribute of the image:
document.getElementById('img#hplogo').src = 'path/to/your/image.jpg'
Changing the "innerHTML" property changes the inner HTML, not the element itself. The thing you want to do is find the element and change it's "src" property.
Is there any way to remove the tooltip from title attribute without actually remove the title.
I have a link with a title attribute like this
It is important that the title is intact since I need to read the url from there. All the fixes for this that I have found is to remove the title attribute and reuse it but in this case this is not possible.
Any ideas?
It's all about the browser. It's the browser that sees the title as a tooltip, from the browser specifications and interpretations.
You should use if you want to handle data like that, the HTML5 way (which you can use in any other document type as it's ignored) and use:
with the data- attributes, there will be no tooltip as title is not used, and you can easily get that using:
$("a").attr("data-title")
but, you will need to convert stuff and you said that you don't/can't do that.
you can easily convert all titles into data-title and clean the title using
$("a").attr("data-title", function() { return $(this).attr("title"); } );
$("a").removeAttr("title");
(all code is to be used with jQuery Framework)
As you didn't mark this question as jquery, I'm assuming that you'd be open to a pure JavaScript solution?
The following works (on Ubuntu 11.04) in Firefox 5, Chromium 12 and Opera 11, I'm unable to test in IE, but as I'm using querySelectorAll() I'd suspect that it wouldn't work well, if at all. However:
var titled = document.querySelectorAll('[title]'); // gets all elements with a 'title' attribute, as long as the browser supports the css attribute-selector
var numTitled = titled.length;
for (i=0; i<numTitled; i++){
titled[i].setAttribute('data-title',titled[i].title); // copies from 'title' to 'data-title' attribute
titled[i].removeAttribute('title'); // removes the 'title' attribute
}
JS Fiddle demo.
References:
document.querySelectorAll at the Mozilla Developer Network.
Why don't you use jQuery to move this information from title to element data.
Run this on element load:
$(el).data('url', $(el).attr('title')).attr('title', '');
And afterwards read URL like this:
$(el).data('url');
Variable el here is DOM element or element selector.
I'm using the following JavaScript to dynamically load stylesheets:
function set_stylesheet(name) {
var link = document.getElementById('userstylelink');
link.href = link.href.replace(/[^\/]+\.css$/, name + '.css');
}
Is there any way to determine whether the new CSS file is loaded successfully? If it fails, I'd like to be able to apply a default stylesheet.
You might want to see my answer to another similar question here:
Detect and log when external JavaScript or CSS resources fail to load
Basically, you can add an onload callback to see if the file was loaded. (If you load via JS of course)
The simplest way is to check styleSheet.cssText property of the link element after a new href was assigned.
function set_stylesheet(name) {
var link = document.getElementById('userstylelink');
link.href = link.href.replace(/[^\/]+\.css$/, name + '.css');
if ( link.styleSheet.cssText ) {
//if not empty string, it was loaded
}
else {
link.href = "default.css";
}
Alternatively there is "onerror" event which fires when the resource fails to load after href assigned.
Ideally, you would load them all at the beginning and then switch between then.
http://www.alistapart.com/articles/alternate/
http://www.thesitewizard.com/javascripts/change-style-sheets.shtml
That doesn't really answer the question, but I think this way is preferred.
I'd recommend loading via ajax, checking the response as the user pimvbd mentions, but also place a dummy rule at the end of your stylesheet that styles a hidden element with a declaration you can check. For example, give a hidden div border: 987px and check to see if the hidden div's border is in fact 987px. Yes, it introduces a dependency on that style and that element. I've had endless discussions on this with many people, and there's not really a better way (yet). Hopefully s get some attention in browser releases in the near future...
There is a solution that requires no javascript or detection of whether the stylesheet loaded.
It seems you could also apply your default style with a built-in style sheet and then have the dynamically loaded stylesheet override the defaults. If the new stylesheet doesn't load, the default is already loaded and in place, nothing further to do. If the new stylesheet does load, it just overrides the default values and shows the new style.