I am using LESS ( http://lesscss.org ) and it says ...
JavaScript evaluation
JavaScript expressions can be evaluated as values inside .less files. This is done by wrapping the expression with back-ticks:
The example provided is ...
#height: `document.body.clientHeight`;
So I've tried to do this in my html ...
<script type="text/javascript">
var fred=5;
</script>
<link rel="stylesheet/less" type="text/css" href="styles.less">
<script type="text/javascript" src="http://lesscss.googlecode.com/files/less-1.2.1.min.js"></script>
and this in styles.less ...
#height:`fred + "px"`;
.mydiv {
background-color:green;
height:#height;
}
But it just won't work!
Also tried variations on this such as using ...
#height:`fred`px;
#height:`fred`;
If I use ...
#height:20px;
It works as expected but I need to use Javascript evaluation.
I would really appreciate it if someone could help - Answers focusing on answering the question and not asking why I need to use Javascript evaluation would be greatly appreciated. Thanks very much all
Its worth noting that if I do ...
#height:`freddd`px;
where freddd is undefined, I get an error from the less compiler - hence it seems to know that fred is defined. However, currently I am not getting an error - it is just not doing anything when I use Javascript variable values.
I am working on the same thing. The way I have been testing the expression is to compile the less file in the browser as you are doing (I am using firefox with firebug). I inspect my rendered css by inspecting the head section of the rendered page and looking for
<style id="less:yourLessFileName-less-styles" type="text/css"> . Twirl that file open and you will see the compliled css. Scroll down until you find your selector and rule you are using the javascript expression for and see how it rendered.
You probably can't call variables created in JS. From what I understand, JavaScript expressions can be evaluated means just that you can evaluate stuff with JS functions and use default JS objects like document.body.clientHeight which doesn't mean that you can call variables from a different file and location. It just doesn't make sense that it'll let you do that, how is it supposed to find the variable?. I might be wrong tho..
Related
Are there any issues with code like the following?
document.documentElement.insertAdjacentHTML('beforeend', `
<div style="border: 5px solid pink">This content is outside the <body>, but both Firefox and Chrome render it fine.</div>
`)
Is this reliable? Or can there be issues in some browsers? From what I can tell, it is totally fine in Firefox and Chrome.
I can't find any information about this, but it seems to work.
EDIT:
The reason I found for using document.documentElement, is we can rely on the fact that document.documentElement seems to be always defined no matter when a <script>'s code runs.
However, document.body is sometimes null depending on when a <script>'s code runs.
For example, consider the following code using document.body. If you stick it in a .html file, then open it in your browser, you will see the message null.
<script>
alert(document.body)
</script>
Here's a live example: https://plnkr.co/edit/PkhHjSHi6esfrl32
Now consider this code:
<script>
alert(document.documentElement)
</script>
The message that you will see is [object HTMLHtmlElement] (or similar). Live example: https://plnkr.co/edit/nSxtGZzN8tU0hCbq
This means, that to write code using document.body, it takes more effort and requires more code.
To get the document.body version to work, we have to do something like the following:
<body>
<script>
alert(document.body)
</script>
</body>
Live example: https://plnkr.co/edit/7BcZDZX4jemhwfcV. Of course, it's not that much more code, but when following the principle of simplicity, it seems that document.documentElement leads to slightly simpler code.
In my tests so far, it seems to work just fine (anything outside the of the eventually-created <body> renders as a sibling to the body element.
What problems may placing DOM elements in document.documentElement cause, that I have not forseen?
by default scripts run synchronously just like normal code. In normal code this won't work
const b = a + 1; // ERROR! a is not defined
const a = 1;
Because a does not exist when b is trying to use it you'll get an error. HTML and scripts are exactly the same
<script>
document.getElementById('a').textContent = 'yo!'; // ERROR <div id="a"> is not defined
</script>
<div id="a"></div>
fails for exactly the same reason as the JavaScript example. <div id="a"> does not exist when the script runs
This explains your <body> issue. If you put the script before the <body> tag then it does not yet exist. If you put it after then it does.
So the simple answer is you can do whatever you want as long as the things you want to reference exist when you try to reference them.
As for adding to the root element, yes you can do that. You don't have to have a body tag. In fact Google even suggests leaving it out.
note: I said above scripts run synchronously by default. There are plenty of ways to make them run later. The modern way is with the defer keyword though that way requires the script to be in a separate file. An old and no longer recommended way is to use the load event using one of <body onload="someFunc()"> or window.onload = someFunc() or window.addEventListener('load', someFunc). In these cases the script actually runs immediately but then effectively sets a callback to be called when the rest of the page has finished loading. Most modern JavaScript no longer uses the load event and either puts the script after the stuff it needs to reference or uses defer. Also es6 modules always "defer"
note that <html> and <body> are special tags. The HTML element is always the root element whether you declare one or not. Also, both <html> and <body> will only have one element each regardless of how many you declare them. Further, <body>, if you declare it, will always be a child of the root element.
During last perioud I've seen more and more often the following situation.
Developer A creates a feature. Let's say is an autocomplete input. Let's assume for simplicity that no framework is used, html and js are on the same file. The file would look like this (let's also asume jquery used - is less to type):
<!-- autocomplete something.html file -->
.........................................
<input id="autocomplete" type="text" />
<script type="text/javascript">
$('#autocomplete').change(function() {
// Do lots of things here -> ajax request, parsing, etc.
});
</script>
.........................................
Now developer B sees the feature and says "Oh, nice feature, I can use that in my section, I'll put one at the top, and one at the bottom - because page is long".
And he does an ajax call to get that html file (this is important, I'm talking about features loaded like this, not features rewritten for the other section) and includes it where he needs it.
Now... problem. The first autocomple works, the second doesn't (because is select by id).
A workaround would be to modify, and use a class. And everything is ok, unless someone else (or himself, or whatever) uses same class for a tottaly different thing.
This could all be avoided if you could the the script to use as a "scope" (I know it is not the correct phrasing, couldn't find any better) the file where it was declared on.
Note: This is a theoretical question. For each particular case a solution could be found, but defining some kind of namespaces for this scenarios would solve the whole class of problems.
How could that be achieved?
As long as you're accessing the DOM the only way I see would be to use the "old" inline event:
<!-- autocomplete something.html file -->
.........................................
<input onchange="autocomplete_change();" type="text" />
<script type="text/javascript">
function autocomplete_change() {
// Do lots of things here -> ajax request, parsing, etc.
};
</script>
...........
Now the function name cannot be used by Developer B.
But when accessing DOM some kind of restriction will always be there.
However when creating the input by Script you can bind the handler directly to the Element:
<script>
var input = $('<input type="text"/>');
input.change(function() {
// Do lots of things here -> ajax request, parsing, etc.
});
document.body.appendChild(input[0]);
</script>
I have created a LESS (http://lesscss.org/) version of a simple css grid solution (http://simplegrid.info/. Now I can happily roll my own grid sizes with the server script from LESS (lessc). That's working for me.
For demo purposes I would like to create a HTML page, where I can put the size of the css grid in a textbox and the grid would change dynamically. Beginning of the demo is here:
http://jsfiddle.net/8QHNc/
So instead of changing #layoutwidth: 720px; in the <style rel="stylesheet" type="text/less" > section I would like to pass these variables to the LESS interpreter.
Can these be done with the client side usage of less? Can I define global variables or pass them as parameters to less.js somehow?
I am aware that I could do this without the usage of LESS (preferably with jQuery o. sth.) - but I figured since it is already there...
I do not know if the parser takes any arguments, but why would you refuse to use the built-in javascript evaluation, e.g. adding something like:
#layoutwidth: `document.getElementById("inputLayoutWidth") + "px"`;
to your Less-Stylesheet. Or, using jQuery, as you proposed:
#layoutwidth: `$("#inputLayoutWidth").val() + "px"`;
while using an input field like
<input type="text" id="inputLayoutWidth" value="720" />
and invoke parsing each time the input field is changed.
If you are using 3.x version of less CSS than u can set them in javascript code as well.
less.modifyVars({
'#buttonFace': '#5B83AD',
'#buttonText': '#D9EEF2'
});
I don't know if this method is also present in older version of less.
We know that using Javascript we can load CSS files.
But, can we load Javascript files or run Javascript code using CSS?
If yes, how? Is there any documentation for this?
I think IE and firefox supports CSS expressions which probably you may think of. Something like
width:expression(document.body.clientWidth > 800? "800px": "auto" );
but these are really bad things and you should avoid this
Also you should avoid CSS expression as much as you can.
You can use the CSS like this:
body {
behavior:url(xyz.htc);
}
and now in the xyz.htc file you can write like:
<PUBLIC:COMPONENT TAGNAME="xss">
<PUBLIC:ATTACH EVENT="ondocumentready" ONEVENT="ABC()" LITERALCONTENT="false"/>
</PUBLIC:COMPONENT>
<SCRIPT>
function ABC()
{
alert("Message");
}
</SCRIPT>
No, you can not run Javascript or import Javascript into CSS... not that you would ever need to.
No.
The closest thing I can think of is Netscape 4 had a thing called JavaScript Style Sheets (JSSS)
http://www.w3.org/Submission/1996/1/WD-jsss-960822
I would like to print the first link in the page with JavaScript. But when I use the following code, it doesn't work:
<html>
<head><title></title></head>
<body>
<a id="mylink" href="http://google.com">Google</a><br />
<script>
a=$('mylink').href;
document.write(document.links[0]);
</script>
</body>
</html>
Then I commented out the code "a=$('mylink').href", it suddenly worked, why? How come the varable a has any influence on the next statement?
Any answers are appreciated.
There's a few possibilities:
The object $ is not defined and caused a JavaScript error preventing your 2nd statement to execute
The $ object does not know what to do with the string passed in and errors
The returned value from $ does not have a value (ie - it returns undefined) which wont have a property href, causing a JavaScript error
the code is not working because in your example the $ object does not exist and will cause an error. It seems that you were trying to use a JavaScript framework like jQuery ($ object) but you forgot to include it.
Try to add the following script-Tag:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
If you wanted to use jQuery, you should also access attributes via the .attr("attrname") function. E.g.
var a = $('#mylink').attr('href');
Again if you wanted to use jQuery, you have to alter the selector from "mylink" to "#mylink" to specify that you were searching for the element with the id "mylink".
I am a bit confused as to what you are trying to do, but couldn't you just write the whole link in js? Ex:
<script>
<!--
document.write('Google');
-->
</script>
<noscript>
Google
</noscript>
The comment tag in the script is ignored and is only there so browsers that don't support javacript won't print it in the document. The <noscript> is so browsers that don't support javascript have alternate content.
It doesn't work because a=$('mylink').href fails to execute and stop executing of following code. The code document.write(document.links[0]) is correct. When you call it without previous wrong line, it just works.
I think in the first line you're trying to use jQuery library. If you want to do it, you need to include jQuery library using <script> tag, then use the following code:
document.write($('a:first').attr("href"));
Just remove the jQuery stuff, you don't need it. As you've already discovered, there is a document.links collection so if you want to print the herf value of the first link in the document:
document.write(document.links[0].href)
and you're done.