Page load order problematic - styles not applying - javascript

I am building a simple web app for mobile platforms using jQuery Mobile and in that, I intend to read some data from an API sending it as JSON (which I have exposed from a server side Django based project), and then parses it using jQuery's mechanism and then I create list elements based off that data.
Now, I have the following index.html:
<html>
<head>
<title>Playism App</title>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/jm/jquery.mobile-1.3.2.min.js"></script>
<script type="text/javascript" src="js/jsonParser.js"></script>
<link rel="stylesheet" type="text/css" href="css/major.css">
<link rel="stylesheet" type="text/css" href="js/jm/jquery.mobile-1.3.2.min.css">
<link rel="stylesheet" type="text/css" href="js/jm/jquery.mobile.theme-1.3.2.min.css">
</head>
<body>
<p>List of games: </p><br/>
<div id="gameContainer" data-role="page">
<ul data-role="listview" data-inset="true" data-filter="true" id="gamesList">
<!-- Content here will be dynamically generated based on the JSON output parsed from the API feed -->
<li>Dummy</li>
</ul>
</div>
<script type="text/javascript" src="js/gamesRenderer.js"></script>
<script type="text/javascript">
$(document).ready(function(){
renderGames();
});
</script>
</body>
</html>
Now, just to test I created that Dummy list element and it's rendering perfect but there is no styling applied to any of the new elements which I inject using .append() calls from jQuery. The code is as follows:
function renderGames(){
for (var i = objCreated.length - 1; i >= 0; i--) {
$("ul#gamesList").append("<li><a href='#''>" + objCreated[i].name + "</a></li></ul>");
};
}
and as can be seen in index.html, I am calling it at DOM ready but no jQuery mobile styling gets applied to these manually injected list elements whereas the Dummy element gets proper styling. I believe something is wrong with the order in which the elements are called.
Thanks in advance !

Don't get me wrong but this question was asked so many times, but here's a solution for you:
function renderGames(){
for (var i = objCreated.length - 1; i >= 0; i--) {
$("ul#gamesList").append("<li><a href='#''>" + objCreated[i].name + "</a></li></ul>");
};
$("ul#gamesList").listview('refresh');
}
You need to use:
$("ul#gamesList").listview('refresh');
When working with a dynamically added jQuery Mobile you must manually start markup enhancement process. Read more about it in this article.
One other thing, never use document ready with jQuery Mobile, they should not be combined. Read more about it here. Sometimes it works sometimes not. Basically when working with jQuery Mobile always use page events.
Your final javascript should look like this:
$(document).on('pagebeforeshow', '#gameContainer', function(){
renderGames();
});
function renderGames(){
for (var i = 10 - 1; i >= 0; i--) {
$("ul#gamesList").append("<li><a href='#''>Some object" + i + "</a></li></ul>");
};
$("ul#gamesList").listview('refresh');
}
Working example: http://jsfiddle.net/Gajotres/5uPfM/

Seems the for loop make the css cannot load properly. Don't know what is the 'objCreated'.
Try to migrate the code here in JSFiddle.
Here is the code:
<body>
<p>List of games: </p><br/>
<div id="gameContainer" data-role="page">
<ul data-role="listview" data-inset="true" data-filter="true" id="gamesList">
<li>Dummy</li>
</ul>
</div>
</body>
$(document).ready(function(){
renderGames();
});
function renderGames(){
$("ul#gamesList").append("<li><a href='#''>Hello world!</a></li></ul>")
}
The css seems works on the injected elements. The list-style is "none" because of the jQuery Mobile UI css works.

first apply css and see your css file are linked properly
<link rel="stylesheet" type="text/css" href="css/major.css">
<link rel="stylesheet" type="text/css" href="js/jm/jquery.mobile-1.3.2.min.css">
<link rel="stylesheet" type="text/css" href="js/jm/jquery.mobile.theme-1.3.2.min.css">
then JS and see your js file are linked properly
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/jm/jquery.mobile-1.3.2.min.js"></script>
<script type="text/javascript" src="js/jsonParser.js"></script>
<script type="text/javascript">
$(document).ready(function(){
renderGames();
});
</script>

Related

div button to change css files [duplicate]

I have a page which has <link> in the header that loads the CSS named light.css. I also have a file named dark.css. I want a button to swap the style of the page all together (there are 40 selectors used in css file and some do not match in two files).
How can I remove reference to light.css with JS and remove all the styles that were applied and then load dark.css and apply all the styles from that? I can't simply reset all of the elements, since some of the styles are applied through different css files and some are dynamically generated by JS. Is there a simple, yet effective way to do that without reloading the page? Vanilla JS is preferable, however I will use jQuery for later processing anyways, so jQ is also fine.
You can include all the stylesheets in the document and then activate/deactivate them as needed.
In my reading of the spec, you should be able to activate an alternate stylesheet by changing its disabled property from true to false, but only Firefox seems to do this correctly.
So I think you have a few options:
Toggle rel=alternate
<link rel="stylesheet" href="main.css">
<link rel="stylesheet alternate" href="light.css" id="light" title="Light">
<link rel="stylesheet alternate" href="dark.css" id="dark" title="Dark">
<script>
function enableStylesheet (node) {
node.rel = 'stylesheet';
}
function disableStylesheet (node) {
node.rel = 'alternate stylesheet';
}
</script>
Set and toggle disabled
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="light.css" id="light" class="alternate">
<link rel="stylesheet" href="dark.css" id="dark" class="alternate">
<script>
function enableStylesheet (node) {
node.disabled = false;
}
function disableStylesheet (node) {
node.disabled = true;
}
document
.querySelectorAll('link[rel=stylesheet].alternate')
.forEach(disableStylesheet);
</script>
Toggle media=none
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="light.css" media="none" id="light">
<link rel="stylesheet" href="dark.css" media="none" id="dark">
<script>
function enableStylesheet (node) {
node.media = '';
}
function disableStylesheet (node) {
node.media = 'none';
}
</script>
You can select a stylesheet node with getElementById, querySelector, etc.
(Avoid the nonstandard <link disabled>. Setting HTMLLinkElement#disabled is fine though.)
You can create a new link, and replace the old one with the new one. If you put it in a function, you can reuse it wherever it's needed.
The Javascript:
function changeCSS(cssFile, cssLinkIndex) {
var oldlink = document.getElementsByTagName("link").item(cssLinkIndex);
var newlink = document.createElement("link");
newlink.setAttribute("rel", "stylesheet");
newlink.setAttribute("type", "text/css");
newlink.setAttribute("href", cssFile);
document.getElementsByTagName("head").item(cssLinkIndex).replaceChild(newlink, oldlink);
}
The HTML:
<html>
<head>
<title>Changing CSS</title>
<link rel="stylesheet" type="text/css" href="positive.css"/>
</head>
<body>
STYLE 1
STYLE 2
</body>
</html>
For simplicity, I used inline javascript. In production you would want to use unobtrusive event listeners.
If you set an ID on the link element
<link rel="stylesheet" id="stylesheet" href="stylesheet1.css"/>
you can target it with Javascript
document.getElementsByTagName('head')[0].getElementById('stylesheet').href='stylesheet2.css';
or just..
document.getElementById('stylesheet').href='stylesheet2.css';
Here's a more thorough example:
<head>
<script>
function setStyleSheet(url){
var stylesheet = document.getElementById("stylesheet");
stylesheet.setAttribute('href', url);
}
</script>
<link id="stylesheet" rel="stylesheet" type="text/css" href="stylesheet1.css"/>
</head>
<body>
<a onclick="setStyleSheet('stylesheet1.css')" href="#">Style 1</a>
<a onclick="setStyleSheet('stylesheet2.css')" href="#">Style 2</a>
</body>
This question is pretty old but I would suggest an approach which is not mentioned here, in which you will include both the CSS files in the HTML, but the CSS will be like
light.css
/*** light.css ***/
p.main{
color: #222;
}
/*** other light CSS ***/
and dark.css will be like
/*** dark.css ***/
.dark_theme p.main{
color: #fff;
background-color: #222;
}
/*** other dark CSS ***/
basicall every selector in dark.css will be a child of .dark_theme
Then all you need to do is to change the class of body element if someone selects to change the theme of the website.
$("#changetheme").click(function(){
$("body").toggleClass("dark_theme");
});
And now all your elements will have the dark css once the user clicks on #changetheme. This is very easy to do if you are using any kind of CSS preprocessors.
You can also add CSS animations for backgrounds and colors which makes the transition highly smooth.
Using jquery you can definitely swap the css file. Do this on button click.
var cssLink = $('link[href*="light.css"]');
cssLink.replaceWith('<link href="dark.css" type="text/css" rel="stylesheet">');
Or as sam's answer, that works too. Here is the jquery syntax.
$('link[href*="light.css"]').prop('disabled', true);
$('link[href*="dark.css"]').prop('disabled', false);
Using jquery .attr() you can set href of your link tag .i.e
Sample code
$("#yourButtonId").on('click',function(){
$("link").attr(href,yourCssUrl);
});
Maybe I'm thinking too complicated, but since the accepted answer was not working for me I thought I'd share my solution as well.
Story:
What I wanted to do was to include different 'skins' of my page in the head as additional stylesheets that where added to the 'main' style and switch them by pressing a button on the page (no browser settings or stuff).
Problem:
I thought #sam's solution was very elegant but it did not work at all for me. At least part of the problem is that I'm using one main CSS file and just add others on top as 'skins' and thus I had to group the files with the missing 'title' property.
Here is what I came up with.
First add all 'skins' to the head using 'alternate':
<link rel="stylesheet" href="css/main.css" title='main'>
<link rel="stylesheet alternate" href="css/skin1.css" class='style-skin' title=''>
<link rel="stylesheet alternate" href="css/skin2.css" class='style-skin' title=''>
<link rel="stylesheet alternate" href="css/skin3.css" class='style-skin' title=''>
Note that I gave the main CSS file the title='main' and all others have a class='style-skin' and no title.
To switch the skins I'm using jQuery. I leave it up to the purists to find an elegant VanillaJS version:
var activeSkin = 0;
$('#myButton').on('click', function(){
var skins = $('.style-skin');
if (activeSkin > skins.length) activeSkin=0;
skins.each(function(index){
if (index === activeSkin){
$(this).prop('title', 'main');
$(this).prop('disabled', false);
}else{
$(this).prop('title', '');
$(this).prop('disabled', true);
}
});
activeSkin++
});
What it does is it iterates over all available skins, takes the (soon) active one, sets the title to 'main' and activates it. All other skins are disabled and title is removed.
Simply update you Link href attribute to your new css file.
function setStyleSheet(fileName){
document.getElementById("WhatEverYouAssignIdToStyleSheet").setAttribute('href', fileName);
}
I reworked lampe's example, and you can add a class using a selector in this way:
first apply the class to specific selectors in a javascript (repeat as many times you need for specific element selectors (in my HTML):
$("p:nth-of-type(even)").toggleClass("main mainswitch");
Then the html looks like this
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js">
</script>
<script>
$(document).ready(function(){
$("button").click(function(){
$(".mainswitch").toggleClass("main");
});
});
</script>
<style>
.main {
font-size: 120%;
color: red;
}
</style>
</head>
<body>
<div>
<p>This is a paragraph.</p>
<p class="main mainswitch">This is another paragraph.</p>
<p>This is a paragraph.</p>
<p>This is a paragraph.</p>
<p>This is a paragraph.</p>
</div>
<button>Toggle class "main" for p elements</button>
</body>
</html>
If you're using Angular (cause it's not 2013 anymore), you can try the answer/solution/suggestion from here:
How can I change the targeted CSS file on a click event
It did the trick for me.

How to fetch a particular div from one html file and place it in other html file using normal JavaScript?

I have two html files named homepage.html & dashboard.html at same level under same folder. I only want to fetch a particular div as my main project has a lot of divs.
Here's the code of homepage.html
<html>
<head>
<meta charset="UTF-8">
<title>Homepage</title>
<link rel="stylesheet" href="css/homepage.css">
</head>
<body>
<div class="homepage-side-menu">
<div id="homepage-home">
<label>Home</label>
</div>
<div id="homepage-dashboard">
<label>Dashboard</label>
</div>
</div>
<div id="homepage-main-view"></div>
<script src="js/homepage.js"></script>
</body>
</html>
And here's the code of dashboard.html
<html>
<head>
<meta charset="UTF-8">
<title>Dashboard</title>
<link rel="stylesheet" href="css/dashboard.css">
</head>
<body>
<div class="dashboard-side-menu"></div>
<div id="dashboard-main-view"></div>
<script src="js/dashboard.js"></script>
</body>
</html>
I want to only fetch the content from the div class="homepage-side-menu"> and show it under <div class="dashboard-side-menu"></div> using simple JavaScript.
First you have to refer the file which you want to consume. then you use getElementByClass()
here is how you import the html file into another html
<link href="homepage.html" rel="import" />
or using javascript:
<script>
$(function(){
$("#addContentFromAnotherHTML").load("homepage.html");
});
</script>
and you can view something like this:
<body>
<div id="addContentFromAnotherHTML"></div>
</body>
something like this:
var classData = document.getElementsByClassName('homepage-side-menu');
Since html5 you can use imports
<link rel="import" href="/path/to/imports/stuff.html">
In older browsers the only way is using javascript (XHR, fetch, or Jquery .load
Using jQuery you could add this to dashboard.html :
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>
$( ".dashboard-side-menu" ).load( "homepage.html .homepage-side-menu" );
</script>
There are several ways in which you can share HTML template across several pages
1. jQuery - AJAX load() Method
$(selector).load(URL,data,callback);
The load() method loads data from URL and puts the returned data into the selected element.
Read more about it here
2. Server side inclueds using some server side programming languages
<?
php include 'header.php';
?>
Read more about it here
3. Using some build tools like gulp or grunt or webpack
https://www.npmjs.com/package/file-include-webpack-plugin
https://www.npmjs.com/package/gulp-file-include
4. Using HTML imports
HTML imports is an exciting technology that promises to change how we build websites. Imports allow you to include HTML documents within other HTML documents.
Read more about it here
https://www.html5rocks.com/en/tutorials/webcomponents/imports/
https://blog.teamtreehouse.com/introduction-html-imports
This one is recomended but not works with older browser

Issue in my Javascript

I actually created a Javascript to get a plot of statistics of my assembled genome : here is the name of my Javascript: myscript.html
First, I had to convert my assembly.fa file in a JSON format object:
perl asm2stats.pl genome_assembly.fa > myoutput.json
Then, here is the usage gave in the github:
usage
The simplest plot requires a target div, an assembly span, a count of ACGT bases, the GC percentage and an array of scaffold lengths, however it is best to use the asm2stats.pl/asm2stats.minmaxgc.pl perl scripts described above to generate a richer, pre-processed input format. See the Danaus_plexippus_v3.assembly-stats.json file for a complete example using pre-binned data, basic usage is detailed below:
<div id="assembly_stats">
<script>
d3.json("Danaus_plexippus_v3.assembly-stats.json", function(error, json) {
if (error) return console.warn(error);
asm = new Assembly (json);
asm.drawPlot('assembly_stats');
})
</script>
Then I wrote:
<html>
<head>
<title>assembly stats</title>
</head>
<body>
<link rel="stylesheet" type="text/css" href="css/circle-plot.css">
<link rel="stylesheet" type="text/css" href="css/square-plot.css">
<link rel="stylesheet" type="text/css" href="css/table.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script type="text/javascript" src="js/circle-plot.js"></script>
<script type="text/javascript" src="js/square-plot.js"></script>
<script type="text/javascript" src="js/table.js"></script>
<div id="assembly_stats">
<div class="my_class"></div>
<script>
d3.json("output_0035.json", function(error, json) {
if (error) return console.warn(error);
asm = new Assembly (json);
asm.drawPlot('assembly_stats');
asm.drawTable('my_class');
asm.toggleVisible(['asm-longest_pie','asm-count']);
})
</script>
</body>
</html>
and when I try to run it in my browser, I only get the circular plot, but I should also get a tabular representation as in the github exemple.
I'm not really familiar vith html code, does someone could tell me if I forgot somethingin the code to get this code? Here is the manual : github
Thanks for your help :)
Add a div Element inside the body and give it a class attribute:
<div class="my-class-name"></div>
After
asm.drawPlot('assembly_stats');
create the table with
asm.drawTable('my-class-name');

EJS File Not Recognizing JavaScript File's Code

I am creating a website, I am using a NodeJS server. In my public folder I have a script named website.js and it has the jQuery code to give a console.log when the h1 is clicked. (Code Below). But when I click on the h1 in the browser it does not work. The file is loaded properly, gives no 404 error and my CSS stylesheet works fine.
Further Testing: I did a simple test to see if it would give back the text when I called the variable (test code below) it responds with: "" (two quotation marks) so it must not be recognizing it.
//Test code
var xyz = $("#testh1").text();
//jQuery Code
$("#testh1").on("click", function(){
console.log("Clicked");
});
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/javascripts/website.js"></script>
<link rel="stylesheet" type="text/css" href="/stylesheets/website.css">
<script src="https://code.jquery.com/jquery-2.2.4.js" integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>
<title>test</title>
</head>
<body>
<h1 id="testh1">TEST</h1>
</body>
</html>
You need to load jQuery before your script.
<script src="https://path-to-jquery"></script>
<script src="/javascripts/website.js"></script>
You need to wait for the DOM to be ready before accessing any elements in it. You can either do it with the following code:
$(document).ready(function() {
$("#testh1").on("click", function(){
console.log("Clicked");
});
});
or by putting your <script>s at the bottom of the <body> instead of in the <head>.
<script src="https://path-to-jquery"></script>
<script src="/javascripts/website.js"></script>
</body>
You're getting an empty string in your test code because your #testh1 element hasn't been loaded yet.

Loaded jQuery UI library but getting "Uncaught TypeError: $(...).effect is not a function"

Trying to make the #intro_title bounce when the document is ready. I loaded both the jQuery and jQuery UI libraries and I still get "Uncaught TypeError: $(...).effect is not a function". I suspect that this is an issue with importing the jQuery UI library so...
I tried loading the libraries at the end of the body, head, html, etc. and changed "src" to "href" but I get the same result each time. I even tried both Google's and jQuery's hosted libraries only to meet the same result.
lodge_101.html
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="lodge_101_main.css">
<head>
<title>Scipio Lodge 101</title>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body>
<h1 id="intro_title">WELCOME TO LODGE 101</h1>
<script src="lodge_101_main.js"></script>
</body>
</html>
lodge_101_main.js
$(document).ready(function() {
$("#intro_title").effect("bounce", { times:3 }, "slow");
});
Why does this continue to happen and how can I fix it? I'm still new to programming so please be very critical of my work, thank you!
you have to load the jquery library before the jquery ui. just change your script tags position. move the jquery script tag at the first position.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
Try defining jquery before jquery-ui.

Categories

Resources