Conditional include of CSS, but not as last (or first) CSS - javascript

This question adds a CSS conditionally as the last CSS link (effectively overwriting all others), with this javascript:
<link rel="stylesheet" href="website/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="website/reveal/css/reveal.min.css">
<link rel="stylesheet" href="website/reveal/css/theme/simple.css" id="theme">
<!-- Conditionally add <link rel="stylesheet" href="website/reveal/css/print/pdf.css"> -->
<script type="text/javascript">
if (...) {
var lnk = document.createElement('link');
lnk.type='text/css';
lnk.href='website/reveal/css/print/pdf.css';
lnk.rel='stylesheet';
document.getElementsByTagName('head')[0].appendChild(lnk);
}
</script>
<link rel="stylesheet" href="website/highlight/highlight.css">
<link rel="stylesheet" href="website/optaplannerPresentation.css">
The problem is: It adds it as the last CSS link, overwriting the later 2 CSS files (including highlight.css). Is there a way to add it after the simple.css, but before the highlight.css?

Two options for you:
If the condition you're testing is using information immediately available and your script element doesn't use async or defer, this could be one of the rare cases where document.write is a reasonable option:
<link rel="stylesheet" href="website/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="website/reveal/css/reveal.min.css">
<link rel="stylesheet" href="website/reveal/css/theme/simple.css" id="theme">
<!-- Conditionally add <link rel="stylesheet" href="website/reveal/css/print/pdf.css"> -->
<script type="text/javascript">
if (...) {
document.write('<link type="text/css" rel="stylesheet" href="website/reveal/css/print/pdf.css">');
}
</script>
<link rel="stylesheet" href="website/highlight/highlight.css">
<link rel="stylesheet" href="website/optaplannerPresentation.css">
If you're using an async / defer script, or information that isn't avaialble inline, or you just don't want to use document.write, you can still do it: You can find the link that adds highlight.css via querySelector using an attribute-ends-with selector, then use its parentNode and the parent's insertBefore to insert the new link in front of it.
var lnk = document.createElement('link');
lnk.type='text/css';
lnk.href='website/reveal/css/print/pdf.css';
lnk.rel='stylesheet';
var highlight = document.querySelector('link[href$="highlight.css"]');
highlight.parentNode.insertBefore(lnk, highlight);
querySelector works in all modern browsers, and also IE8. It returns the first element that matches the CSS selector you give it. (There's also querySelectorAll, which returns a list of all matching elements.)
To do that, though, your code must be after the link for highlight.css (unless it's running async or in some event handler):
<link rel="stylesheet" href="website/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="website/reveal/css/reveal.min.css">
<link rel="stylesheet" href="website/reveal/css/theme/simple.css" id="theme">
<link rel="stylesheet" href="website/highlight/highlight.css">
<!-- Conditionally add <link rel="stylesheet" href="website/reveal/css/print/pdf.css"> -->
<script type="text/javascript">
if (...) {
var lnk = document.createElement('link');
lnk.type='text/css';
lnk.href='website/reveal/css/print/pdf.css';
lnk.rel='stylesheet';
var highlight = document.querySelector('link[href$="highlight.css"]');
highlight.parentNode.insertBefore(lnk, highlight);
}
</script>
<link rel="stylesheet" href="website/optaplannerPresentation.css">

Because JavaScript not executes with page rendering, so you need to add a place holder and then replace:
function changeCSS(cssFile) {
document.getElementById('stylesheetReplace').href='cssFile';
}
and placeholder for css:
<link rel="stylesheet" href="website/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="website/reveal/css/reveal.min.css">
<link rel="stylesheet" href="website/reveal/css/theme/simple.css" id="theme">
<link rel="stylesheet" href="" id="stylesheetReplace>

Related

Moved my scripts to a external page and they no longer respond

I created a small nav to switch between different stylesheets using jquery, however once I moved my scripts out from the page and into a separate file they no longer respond.
$(document).ready(function() {
// teal stylsheet
$("#cssTeal").click(function() {
$("link[rel=stylesheet]").attr({href : "stylesheetteal.css"});
});
// pink stylesheet
$("#cssPink").click(function() {
$("link[rel=stylesheet]").attr({href : "stylesheetpink.css"});
});
// yellow stylesheet
$("#cssYellow").click(function() {
$("link[rel=stylesheet]").attr({href : "stylesheetyellow.css"});
});
});
<html>
<head>
<meta charset="UTF-8"/>
<title>Mission Statement</title>
<link href="stylesheetteal.css" rel="stylesheet" type="text/css" media="all" id="teal"/>
<link href="stylesheeetpink.css" rel="alternate stylesheet" type="text/css" media="all" id="pink"/>
<link href="stylesheetyellow.css" rel="alternate stylesheet" type="text/css" media="all" id="yellow"/>
<link href="scripts.js" rel="external" type="text/javascript"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="scripts/jquery-ui/jquery-ui.min.js"></script>
<style type="text/css">
</style>
</head>
<body>
<div id="themes">
<div class="indiv"><a id="cssTeal" href="#teal"><img src="assets/tealcircle.png"></a></div>
<div class="indiv"><a id="cssPink" href="#pink"><img src="assets/pinkcircle.png"></a></div>
<div class="indiv"><a id="cssYellow" href="#yellow"><img src="assets/yellowcircle.png"></a></div>
</div>
The problem is the order of the loaded scripts and the tag you are using to load your custom scripts. You are using a link tag instead of a script tag.
Try this:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="scripts/jquery-ui/jquery-ui.min.js"></script>
<script src="scripts.js"></script>
Also add all the script tags just before the closing </body> tag. Scripts block content from loading, so you should add them last so they don’t block the rest of the content from being loaded.

Chrome 64 Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': Cannot access StyleSheet to insertRule

Ahh! My site is broken in Chrome.
Getting this message in console: Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': Cannot access StyleSheet to insertRule
It points to this line of code, which is from a third-party plugin:
document.styleSheets[0].insertRule(rule,0);
Stylesheets defined in head:
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400,700">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<link type="text/css" rel="stylesheet" href="/Public/js/jquery-ui/jquery-ui.css" />
<link type="text/css" rel="stylesheet" href="/Public/js/jquery-ui/jquery-ui.theme.min.css" />
<link type="text/css" rel="stylesheet" href="/Public/css/msgPop.css" />
<link type="text/css" rel="stylesheet" href="/Public/js/select2/select2.css">
We believe this commit to Chromium to be the root cause of our issue:
Update behavior of CSSStyleSheet to match spec for Security origin
The quick solution for us was to simply reorder the CSS. It seems that previously the culprit plugin was inserting CSS rules to this remote CSS:
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400,700">
Simply reordering our stylesheets to ensure a script from our site was in first position (document.styleSheets[0]), fixed the issue:
<link type="text/css" rel="stylesheet" href="/Public/js/jquery-ui/jquery-ui.css" />
<link type="text/css" rel="stylesheet" href="/Public/js/jquery-ui/jquery-ui.theme.min.css" />
<link type="text/css" rel="stylesheet" href="/Public/css/msgPop.css" />
<link type="text/css" rel="stylesheet" href="/Public/js/select2/select2.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,400,700">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
In my case it was adblock playing tricks on me, turn it off and the message should go away
Dynamically add style tag
class StyleSheet {
constructor(name = 'dynamic-styleSheet') {
this.styleSheet = this.getStyleSheet(name)
}
getStyleSheet(name) {
if (!document.getElementById(name)) {
const style = document.createElement('style')
style.title = name
document.getElementsByTagName('head')[0].appendChild(style)
}
let styleSheet = null
for (let i = 0; i < document.styleSheets.length; i++) {
styleSheet = document.styleSheets[i]
if (styleSheet.title === name) {
break
}
}
return styleSheet
}
insertRule(css, index) {
return this.styleSheet.insertRule(css, index)
}
deleteRule(index) {
this.styleSheet.deleteRule(index)
}
}
export default StyleSheet
// let styleSheet = new StyleSheet ()
// styleSheet.insertRule('h1{color:red;}', 0)

Why doesn't my function work on page load?

I am trying to run a function as soon as the user lands on the page. I have the following head section:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="Resources/css/normalize.css">
<link rel="stylesheet" type="text/css" href="Resources/css/ionicons.min.css">
<link rel="stylesheet" type="text/css" href="Resources/css/animate.css">
<link rel="stylesheet" type="text/css" href="Resources/css/style.css">
<link rel="stylesheet" href="https://www.w3schools.com/lib/w3.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript">
function sayOK() {
alert('ok');
}
window.onload = sayOK;
</script>
</head>
Why doesn't sayOK() run?
Your sample code ran fine in testing. You can try moving your script to the footer, just before your closing body tag.
jQuery offers a good onload mechanism, and if you want cross-browser reliability, that would be where I start. Don't reinvent the wheel.
https://learn.jquery.com/using-jquery-core/document-ready/
This is a portable way of running your code as soon as the page is loaded:
function documentReady (cb) {
if (document.readyState !== 'loading') {
cb();
} else {
document.addEventListener('DOMContentLoaded', cb);
}
}
documentReady(function () {
// YOUR CODE GOES HERE
});
It works. Try try to create a separate file, for example ok.html, and open it in any browser. It should show the message.

Can't refresh selectpicker

I'm trying to append some options on the Silvio Moreto's Bootstrap select picker.
When I try to update it after the append, jquery throws this error:
Uncaught TypeError: $(...).selectpicker is not a function
I've read around that It's because select picker is not fully initialized, but if I go to my heading partial, the select picker js and css is included way before the function that tries to update it.
I've also read that this should be done inside a $(function(){}); block. But since the file that is performing the operation is a plain functions file that is called inside a $(function(){}); block the problem shouldn't present.
This is my heading file:
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GMS</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css" integrity="sha384-XdYbMnZ/QjLh6iI4ogqCTaIjrFk87ip+ekIjefZch0Y+PvJ8CDYtEs1ipDmPorQ+" crossorigin="anonymous">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:100,300,400,700">
<!-- Styles -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
{{-- <link href="{{ elixir('css/app.css') }}" rel="stylesheet"> --}}
<link rel="stylesheet" href="{{url('css/general.css')}}">
<link rel="stylesheet" href="{{url('css/modal.css')}}">
<link rel="stylesheet" href="{{url('css/status_page.css')}}">
<link rel="stylesheet" href="{{url('css/dropdowns.css')}}">
<link rel="stylesheet" href="{{url('css/animator.css')}}">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/css/bootstrap-select.min.css">
<!-- Jquery -->
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
<!-- Bootstrap select with live src -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script>
<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<!--
|-----------------------------------
| Custom CSS
|-----------------------------------
-->
#section('css')#show
<!--
|-----------------------------------
| Custom JS
|-----------------------------------
-->
<script src="{{url('js/general.js')}}"></script>
<script src="{{url('js/functions/functions.js')}}"></script>
<script src="{{url('js/functions/animator.js')}}"></script>
<script src="{{url('js/app/gms.js')}}"></script>
<script src="{{url('js/app/controllers/auth_controller.js')}}"></script>
<script src="{{url('js/app/controllers/redirect_controller.js')}}"></script>
<script src="{{url('js/app/controllers/changelog_controller.js')}}"></script>
<script src="{{url('js/app/factories/changelog_factory.js')}}"></script>
#section('js')#show
This is the function that performs the changes in the select:
function fillContracts(contracts) {
for(var i = 0; i < contracts.length; i++)
{
console.log('Iterating');
console.log('Contract ID: ' + contracts[i].id);
console.log('Contract TITLE: ' + contracts[i].titolo);
$('#selectpicker').html('<option>Test1</option><option>Test2</option>').selectpicker('refresh');
}
console.log('Done');
}
The file containing this function is injected in the heading using Blade. The Laravel's template engine. When I check the page source, it's correctly included after the select picker.
If it might help, the data that I try to append comes from a AJAX call. But I can't figure out what's wrong...
Thanks for any help!
Update
I'm still trying to figure out what's wrong. The problem is that I keep getting the error when I try to use the selectpicker plugin. But I can't understand what's missing...
Bootstrap CSS:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
Jquery:
<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
Bootstrap-select.min.css
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/css/bootstrap-select.min.css">
And the bootstrap-select.min.js:
<script src="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script>
how i was able to solve it is by putting
Bootsrap select.js as the last script inclusion
<script src="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script>
if it continues to give you issue.
avoid selectpicker(refresh) and populate select box by javascript means
<script>
document.getElementById("selectboxID").innerHTML = '<option>Test1</option><option>Test2</option>';
</script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.10.0/js/bootstrap-select.min.js"></script>

Conflict between jqueries?

hi I want to use EasyUI GridView and Tab in Asp.net MVC4 and I put two Grid in a Tab.
but I have problem with it.
I added these Script and css in My Layout:
<link href="#Url.Content("~/Content/kendo/2013.1.319/kendo.common.min.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/kendo/2013.1.319/kendo.blueopal.min.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/kendo/2013.1.319/kendo.rtl.min.css")" rel="stylesheet" type="text/css" />
<link href="~/Content/1-ui.core.css" rel="stylesheet" />
<link href="~/Content/2-ui.theme.css" rel="stylesheet" />
<link href="~/Content/3-ui.datepicker.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.7.1.js"></script>
<script src="#Url.Content("~/Scripts/kendo/2013.1.319/jquery.min.js")"> </script>
<script src="#Url.Content("~/Scripts/kendo/2013.1.319/kendo.all.min.js")"> </script>
<script src="#Url.Content("~/Scripts/kendo/2013.1.319/kendo.aspnetmvc.min.js")"> </script>
<script src="#Url.Content("~/Scripts/kendo.modernizr.custom.js")"> </script>
<script src="~/Scripts/jquery-ui-1.9.2.min.js"> </script>
<script src="~/Scripts/jquery.ui.datepicker-cc.js"> </script>
<script src="~/Scripts/calendar.js"> </script>
<script src="~/Scripts/jquery.ui.datepicker-cc-fa.js"> </script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"> </script>
and I added in My Index these :
<script src="~/Scripts/MapScript/Sld.js"></script>
<script src="~/Scripts/MapScript/proj4js-compressed.js"></script>
<script src='http://maps.google.com/maps?file=api&v=2&key=ABQIAAAAl9RMqSzhPUXAfeBCXOussRSPP9rEdPLw3W8siaiuHC3ED5y09RTJKbutSNVCYFKU-GnzKsHwbJ3SUw'></script>
<script src="~/Scripts/MapScript/ToolsMenu.js"></script>
<link href="~/Content/MapStyle/MStyle.css" rel="stylesheet" />
<script src="~/OpenLayers.js"></script>
<script src="~/Scripts/MapScript/LoadMap.js"></script>
<script src="~/Scripts/mootools-core-1.4-full.js"></script>
<script src="~/Scripts/mootools-more-1.4-full.js"></script>
and in My page that I want to load EasyUI GridView I added these:
<link href="~/Scripts/easyui-1.3.6/themes/icon.css" rel="stylesheet" />
<link href="~/Scripts/easyui-1.3.6/themes/default/easyui.css" rel="stylesheet" />
<link href="~/Scripts/easyui-1.3.6/themes/default/easyui-rtl.css" rel="stylesheet" />
but when I Load My page, first the Tab is not loaded and with reClick on its Link , it loaded.
I think it for conflicting between jqueries that added?????!!!
note: when I create this page without index and Layout ,there isn't no problem
what is the problem??
Try using $.noConflict() in order to avoid conflict between different js files.
see here :- http://api.jquery.com/jquery.noconflict/
NOTE :- Try including required js and css files at one place.
Load Mootools before jQuery. Then, use either
document.id("id_of_element")
or enclose any Mootools classes in
( function () {
$ = document.id;
this.MyClass = new Class({
...
});
})();
This will solve any conflicts between jQuery and MooTools, at least.

Categories

Resources