How to target CSS link with JavaScript - javascript

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.

Related

Remove file that contains specific string in href via JS

In HubSpot a file called layout.min.css is automatically added and is you cannot disable this css file anywhere in the CMS.
As such, I've tried to remove() and disable the file via JS, but the styles from that css file are still being rendered.
When I view source, this file looks like this:
<link rel="stylesheet" href="//cdn2.hubspot.net/hub/xxxxxx/hub_generated/template_assets/1642616240355/hubspot/hubspot_default/shared/responsive/layout.min.css">
Now, notice the 1642616240355 in the URL? That number (for some reason) changes everyday.
Yesterday, I had the following running, and it removed the file:
$("link[href='//cdn2.hubspot.net/hub/xxxxxx/hub_generated/template_assets/1642528871696/hubspot/hubspot_default/shared/responsive/layout.min.css']").attr('disabled', 'disabled');
$("link[href='//cdn2.hubspot.net/hub/xxxxxx/hub_generated/template_assets/1642528871696/hubspot/hubspot_default/shared/responsive/layout.min.css']").remove();
However, as it keeps changing, I'm now looking to remove and disable any css file that contains layout.min.css in its href.
I'm aware that there's a :contains selector, which might be of use here, but unsure on how that would be implemented? As in, how would I tell the code to look at all stylesheets and remove the one that contains "layout.min.css" in its href?
Have also tried:
<script>
const stylesheets = document.querySelectorAll('link[rel=stylesheet]');
for (var i = 0; i < stylesheets.length; i++) {
if(stylesheets[i].href.indexOf("responsive/layout.min.css") >= 0) {
stylesheets[i].disabled = true;
stylesheets[i].remove();
}
}
</script>
But it still shows the layout.min.css when viewing source.
I would recommend you to do this with pure JavaScript instead of JQuery. Because otherwise you have to wait until the JQuery library is loaded.
Use this code for that:
const cssElement = document.querySelector("link[href*='layout.min.css']");
cssElement.disabled = true;
cssElement.remove();
Based on the code you provided that you said works, why not use the ends-with matcher: $=?
$("link[href$='layout.min.css']").remove();
That'll find all the <link> HREFs that end with 'layout.min.css' and remove them, which is exactly what you're describing as your goal.

What's the simplest, safest way to dynamically add anchor-able ids to HTML headers?

I want a Tumblr theme to add link-able anchors to every header in the content of a post. I don't have access to, or control over, the rendering of that content; Tumblr tends to spit out plain <h2>s and similar, for Markdown headers:
## Hello, πŸ’– friend πŸ’! -> <h2>Hello, πŸ’– friend πŸ’!</h2>
I'd like to ensure that any section of a post can be hyperlinked directly to with an anchor link, such as http://thing.place/post/12345#hello-friend. Has anybody got a simple, fairly universal JavaScript snippet to sanitize any header element's content, and add it to that header as an id?
(Presumably, if you've already written this for yourself; you might also have some additional code to add an anchor-link indicator that self-links, as well; share it if you've got it.)
I maintain a project that does what you describe: AnchorJS
Docs: http://bryanbraun.github.io/anchorjs/
Github Repo: https://github.com/bryanbraun/anchorjs
Once you include the script, you can pick which elements it adds anchors to with a selector:
// Add anchors to all h1's and h2's on the page
anchors.add('h1, h2');
It doesn't have any dependencies on Jquery or Lodash, in case that's an issue with Tumblr (I'm not familiar enough with Tumblr to know the constraints there).
I've got a really naΓ―ve solution that depends upon both jQuery and Lodash (and I do mean full jQuery, as Zepto and friends don't include :header); but lightweight, elegant, pure-JavaScript solutions are preferred:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
<script>
jQuery.noConflict(true)(function($){
var lodash = _.noConflict()
, anchor = "\u2693\uFE0E"
$(':header')
.wrap(function(){
var wrapper = document.createElement('header')
, title = lodash.kebabCase( $(this).text() )
return $(wrapper).attr('id', title) })
})
</script>
This does the extra work of adding a semantic <header> element that I'm planning on using for other purposes, but that may not be necessary.

Create new (not change) stylesheets using jQuery

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

How to embed HTML via JS embed code

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.

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

Categories