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
Related
We have a very large website that is quite old and has a lot of 'b' tags. My boss wants to change them to 'strong' tags but this will require a lot of time to change manually so she was hoping we could change it with some code.
I had a nice bit of JQuery code that worked (intermittently), but I couldn't get it to work on the site as it uses JQuery 1.9.1 and cannot be upgraded.
I then found this piece of Javascript which does what I need but only works on the first 'b' tag on the page and all others stay as 'b' tags. I don't know enough about Javascript selectors to change the firstChild selector.
<script>
function replaceElement(source, newType) {
// Create the document fragment
const frag = document.createDocumentFragment();
// Fill it with what's in the source element
while (source.firstChild) {
frag.appendChild(source.firstChild);
}
// Create the new element
const newElem = document.createElement(newType);
// Empty the document fragment into it
newElem.appendChild(frag);
// Replace the source element with the new element on the page
source.parentNode.replaceChild(newElem, source);
}
// Replace the <b> with a <div>
replaceElement(document.querySelector('b'), 'strong');
</script>
You might use querySelectorAll:
Array.from(document.querySelectorAll('b')).forEach(e=>{
replaceElement(e, 'strong');
});
But this is really a xy question. You really should do the change server side, for example by using some search/replace (learn to use your code editor). You're adding to the code debt here.
Note also that there's no obvious reason to prefer strong over b in HTML5.
Use getElementsByTagName(). It's more efficient than querySelectorAll because it doesn't have to parse selectors, and it describes better what you are really trying to do - get elements by tag name.
var elements = document.getElementsByTagName("b");
replaceElement(elements[0], "strong");
replaceElement(elements[1], "strong");
replaceElement(elements[2], "strong");
You can also iterate over this collection by using Array.from().
You would be better off finding the source of the <b> tags and changing them there as Denys has mentioned.
Updating the DOM would have little benefit and would cause performance issues when there are many tags on a page.
Does this system use a CMS or database to store the content? I would look to use something like these 2 SQL queries to replace them across the site:
update content_table set content_column = replace(content_column, '<b>','<strong>');
update content_table set content_column = replace(content_column, '</b>','</strong>');
How can I do this(or something alike this) tooltip in only javascript without linking any template styles (I don't want to implement It to all the tooltips on the whole page). I'm designing the webpage on SharePoint which deletes all the ...
https://www.w3schools.com/css/tryit.asp?filename=trycss_tooltip_top
You can always add inline styles via JS.
var a = document.getElementsByClassName("class-name");
a.forEach(function(e) {
e.style.property = "value";
});
For adding :hover effects however, I think you need to append a stylesheet. Example.
Your other option is to use mouseover effects, but that is ridiculous when :hover exists.
I only have access to the back end of my CMS. They are loading the custom style sheet this way
<link rel="stylesheet" media="(min-width:481px)" href=".../css/custom/styles.css" type="text/css">
I need to remove the media="(min-width:481px)". Is there a way to do this with JavaScript (I don't think the CMS uses jquery)?
I personally do not recommend messing with the elements of a link with JavaScript, but if you still want to do it, this should work:
document.querySelector('link[href=href=".../css/custom/styles.css"]').removeAttribute('media');
If you still want to do this, make sure to wait for css styles to load.
If you want to go with this solution for some reason and do it for all link tags, then this one is simple:
var linkList = document.querySelectorAll('link');
for(var i in linkList) {
linkList[i].removeAttribute('media');
}
Always use .removeAttribute, instead of using setAttribute to set the argument to null. That is generally bad practice.
We've got a little tool that I built where you can edit a jQuery template in one field and JSON data in another and then hit a button to see the results immediately within the browser.
I really need to expand this though so the designer can edit a full CSS stylesheet within another field and when we render the template, it will have the CSS applied to it. The idea being that once we've got good results we can take the contents of these three fields, put them in files and use them in our project.
I found the jQuery.cssRule plugin but it looks like it's basically abandoned (all the links go nowhere and there's been no development in three years). Is there something better or is it the only game in town?
Note: We're looking for something where someone types traditional CSS stylesheet data in here and that is used immediately for rendering within the page and that can be edited and changed at will with the old rules going away and new ones used in their stead. I'm not looking for something where the designer has to learn jQuery syntax and enter in individual .css("attribute", "value") type calls to jQuery.
Sure, just append a style tag to the head:
$("head").append("<style>p { color: blue; }</style>");
See it in action here.
You can replace the text in a dynamically added style tag using something like this:
$("head").append("<style id='dynamicStylesheet'></style>");
$("#dynamicStylesheet").text(newStyleTextGoesHere);
See this in action here.
The cleanest way to achieve this is by sandboxing your user-generated content into an <iframe>. This way, changes to the CSS won't affect the editor. (For example, input { display:none; } can't break your page.)
Just render out your HTML (including the CSS in the document's <head>, and write it into the <iframe>.
Example:
<iframe id="preview" src="about:blank">
var i = $('#preview')[0];
var doc = i.contentWindow || i.contentDocument;
if (doc.document) doc = doc.document;
doc.open('text/html',true);
doc.write('<!DOCTYPE html><html>...</html>');
doc.close();
If the user should be able to edit a whole stylesheet, not only single style attributes, then you can store the entered stylesheet in a temporary file and load it into your html document using
$('head').append('<link rel="stylesheet" href="temp.css" type="text/css" />');
sounds like you want to write an interpreter for the css? if it is entered by hand in text, then using it later would be as simple as copy and pasting it into a css file.
so if you have a textarea on your page to type in css and want to apply those rules when you press the button, you could use something like this (only pseudocode, needs work):
//for each css id in the text area
$.each($('textarea[name=cssTextArea]').html().split('#'), function({
//now get each property
$.each($(this).split(';'), function(){
$(elem).css({property:value});
});
});
then you could write something to go through each element that your designer typed in, and get the current css rules for it (including those that you applied using some code like the snippet above) and create a css string from that which could then be output or saved in a db. It's a pain and much faffing around with substrings but unfortunately I don't know of a faster or more efficient way.
Hope this atleast gives you some ideas
I need to give the user a snippet of js code that will insert some HTML code into the page.
I'm wondering what the best method to do so is. Should I use document.write, should I just create all the HTML elements via DOM programmatically?
Is it possible to use a js library? I can see conflicts occurring if the webpage the code is embedded in already contains the library.
Using a library is probably too heavyweight, inserting DOM elements is very verbose and document.write may not work if the target site uses the application/xhtml+xml content type. I think your best bet is to construct one element using document.createElement and then setting innerHTML on that.
A suggestion:
Insert this DIV wherever you want the output to appear:
<div id="uniqueTargetID" style="display: none;"></div>
Then at bottom of page have this:
<script src="snippet.js"></script>
This file (remotely hosted or otherwise) contains could output simple text this way:
var html = [];
html.push('<h1>This is a title</h1>');
html.push('<p>So then she said, thats not a monkey, its a truck!</p>');
html.push('<p>You shoulda seen his face...</p>');
var target = document.getElementById('uniqueTargetID');
target.innerHTML = html.join('');
target.style.display = 'block';
I would avoid using document.write() if you can help it.
Javascript::
//to avoid global bashing
(function(){
var target = document.getElementById('ScriptName'),
parent = target.parentElement,
oput = document.createElement('div');
oput.innerHTML = "<p>Some Content</p>";
parent.insertBefore(oput, target);
}());
HTML to give to client/people::
<script type="text/javascript" id="ScriptName" src="/path/to/ScriptName.js"><script>
ScriptName should be something unique to your script.
If its simple insertion you can use pure js, otherwise if you want to provide some complex functionality you can use library. The best choice in this case will be the lib that does not extend root objects (Array, Function, String) to prevent conflicts (jQuery in noConflict mode, YUI, etc.).
Anyway it will be better to avoid using document.write u'd better use setting of innerHTML of existing element or create new one.