I'm trying to add icons to my navigation (which dynamically changes) via JavaScript.
Here is my code (or JSFiddle):
var icon = document.querySelector('#icon');
icon.setAttribute('data-icon', '');
#icon:after {
content: attr(data-icon);
}
<div id="icon" data-icon="">
Icon
</div>
But it is not working, why? When tried to edit data-icon attribute manually, icon appears. Otherwise just unicode of icon.
HTML entities don't have any meaning in CSS. If you want to follow that path you need to decode it first:
var icon = document.querySelector('#icon');
var tmp = document.createElement("span");
tmp.innerHTML = '';
icon.setAttribute('data-icon', tmp.innerText);
#icon:after {
content: attr(data-icon);
}
<div id="icon" data-icon="">
Icon
</div>
... or, alternatively, just type character as-is (as long as your application is written in UTF-8):
var icon = document.querySelector('#icon');
icon.setAttribute('data-icon', '†');
#icon:after {
content: attr(data-icon);
}
<div id="icon" data-icon="">
Icon
</div>
Last but not least, CSS also accepts escape sequences but you need to use the appropriate syntax. This approach, however, does not seem to work for your specific character:
var icon = document.querySelector('#icon');
// Brackets added for visibility, not part of the syntax
icon.setAttribute('data-icon', '(\u0086)(\u2020)');
#icon:after {
content: attr(data-icon);
}
<div id="icon" data-icon="">
Icon
</div>
I presume it's related to the fact that U+2020 'DAGGER' (that works fine) is a regular character but the one you're using U+0086 'START OF SELECTED AREA' (which doesn't show) is a control character. As you mention in a follow-up comment, you're using FontAwesome and such libraries provide custom fonts that map certain code points to display icons (though they normally use private areas to avoid conflicts).
That is obviously because setAttribute is escaping your special characters...and anyway you need to use CSS encoded icons and not an HTML entity. use this convertor:
→ \0086
I would suggest working with meaningful names instead of hard-coded writing the icon's code into an attribute.
For example:
var icon = document.querySelector('#icon');
icon.setAttribute('data-icon', 'icon-heart');
[data-icon=icon-heart]{
content:'\2764';
}
(better that all your icons elements will have a shared class which shared properties)
Encoding minefield
See this StackOverflow answer for more details.
Answer updated (see comments and edits).
In short, I recommend using the character instead of any method of encoding it. It will be vital in this case that your HTML files are correctly encoded and that they properly inform browsers what the encoding is.
var js = document.querySelectorAll( ".js" );
js[ 0 ].setAttribute( "data-icon", "\u0086" );
js[ 1 ].setAttribute( "data-icon", "†" );
.css:after {
content: "\86";
color: red;
}
.css.char:after {
content: "†";
color: blue;
}
.data:after {
content: attr( data-icon );
}
.js:after {
content: attr( data-icon );
}
.red:after {
color: red;
}
.blue:after {
color: blue;
}
<div class="css">hard coded css content</div>
<div class="css char">hard coded css content char</div>
<br>
<div class="data red" data-icon="">hard coded data-icon</div>
<div class="data blue" data-icon="†">hard coded data-icon char</div>
<br>
<div class="js red">data-icon by js</div>
<div class="js blue">data-icon by js char</div>
Related
I have a label which displays an IP address:
<label id="internet_ipaddr" class="label_s1"></label>
What I want to do is display a div, #youareoffline if the label is empty. This was suggested as an implementation but after playing around I can't get it to work:
if (string.IsNullOrWhiteSpace(#internet_ipaddr)) {
$(#youareoffline).show();
}
The code you've attempted to use looks like a mix of C# (string.isNullOrWhiteSpace()) and pseudo code, not valid JS.
To make this work you can check if the element has any children (text nodes or otherwise) using the is(':empty') method, then show the relevant element. Try this:
if ($('#internet_ipaddr').is(':empty')) {
$('#youareoffline').show();
}
#youareoffline { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label id="internet_ipaddr" class="label_s1"></label>
<div id="youareoffline">You are offline</div>
Also note that you can make the JS more succinct, although arguably harder to read, by using toggle():
$('#youareoffline').toggle($('#internet_ipaddr').is(':empty'));
you can easily do this using jQuery.
HTML
<label id="label1"></label>
<div id="div1" style="display: none; color: red;">You are off line.</div>
jQuery
var labelText = $("#label1").text();
if (!labelText) {
$("#div1").show();
}
So I'm having a really strange issue with the cursor. Basically, my menu allows keyboard navigation, so whenever a key is pressed, it will hide the cursor.
This works great (left screenshot) but when I have the mouse immediately over the menu itself, the cursor does not hide, despite the body showing inline style of cursor: none.
http://i.imgur.com/1VvS3H2.png
Here is the code that hides the cursor:
onKey(event: KeyboardEvent) {
var key = event.keyCode;
//User hit an arrow key, so we can assume they want to navigate using the arrows.
//Remove the mouse, until the mouse is moved again.
if (key == 38 || key == 40 || key == 8 || key == 13)
{
document.body.style.cursor = 'none';
this.mouseHidden = true;
}
...
}
Here is the code that returns it:
onMouseMove()
{
if (this.mouseHidden) {
this.mouseHidden = false;
document.body.style.cursor = 'default';
}
}
And here is my menu template:
<div id="menuContainer" *ngIf="!this.displaySplash" (mousemove)="onMouseMove($event)">
<div id="menu" class="cl-effect-1">
<div id="menuHeader">
<h1>{{gameName}}</h1>
</div>
<div id="menuContents" #menuContainer>
<div id="homeMenu" *ngIf="this.displayHome" #homeMenu>
<button class="mainmenu-button" id="play-button" (click)="pressedPlay()" (mouseover)="onMouseEnter($event)">Play</button>
<button class="mainmenu-button" id="music-button" (click)="pressedMusic()" (mouseover)="onMouseEnter($event)">Music</button>
<button class="mainmenu-button" id="credits-button" (click)="pressedCredits()" (mouseover)="onMouseEnter($event)">Credits</button>
<button class="mainmenu-button" id="exit-button" (click)="pressedBack()" (mouseover)="onMouseEnter($event)">Exit</button>
</div>
<div id="soundMenu" *ngIf="displaySound" #soundMenu>
<button class="mainmenu-button" id="mute-button" (click)="pressedMute()" (mouseover)="onMouseEnter($event)">Mute</button>
<button class="mainmenu-button" id="volUp-button" (click)="pressedVolUp()" (mouseover)="onMouseEnter($event)">Volume +</button>
<button class="mainmenu-button" id="volDown-button" (click)="pressedVolDown()" (mouseover)="onMouseEnter($event)">Volume -</button>
<button class="mainmenu-button" id="back-button" (click)="pressedBack()" (mouseover)="onMouseEnter($event)">Back</button>
</div>
<div id="creditsMenu" *ngIf="displayCredits" #creditsMenu>
<p class="mainmenu-text">Author: Kilo Mike Software</p>
<p class="mainmenu-text">License: Open Source</p>
<p class="mainmenu-text">Music License: Public Domain</p>
<button class="mainmenu-button" id="back-button" (click)="pressedBack()" (mouseover)="onMouseEnter($event)">Back</button>
</div>
</div>
</div>
I'm not sure what else to include, because I honestly have no idea as to why this is happening.
Any help would be much appreciated!
Cheers.
Edit: Oh, you can view the problem here: https://steamboatt.github.io/gravity/
Source Code: https://github.com/Steamboatt/gravity
You seem to be wanting to hide the cursor in your entire website.
I'd like to start by outlining this is regarded, in general, as a poor design decision, in terms of usability and accessibility. First of all, this can be done entirely with CSS and it is the recommended way to go about it. So, first, please remove all scripts related to hiding the cursor as they will most likely interact with the method I'm about to propose, rendering it ineffective.
body {
cursor: none;
}
should do the trick, in theory.
But most browsers, exactly for the reasons outlined above, have stronger rules applying to html elements designed for pointer interaction, when it comes to the cursor property. Namely, for <button>s. This is why you will need a stronger CSS rule applying. As in:
body *, body button {
cursor: none !important;
}
If you don't want this applying on all your elements, feel free to replace body with a more specific selector.
Looks like you need some CSS:
body.hide-cursor * {
cursor: none;
}
document.body.className = 'hide-cursor';
//or
document.body.className = '';
How can I have elements .show in the order they're clicked and not the order they're appear in the HTML using jquery?
E.g.
Css code:
.sq{
display:none;
}
Html Code:
A
B
C
<span class="sq" id="01">a</span>
<span class="sq" id="02">b</span>
<span class="sq" id="03">c</span>
JavaScript code:
$("#1").click(function(){
$("#01").show();
});
$("#2").click(function(){
$("#02").show();
});
$("#3").click(function(){
$("#03").show();
});
Using this code if I click C,B,A the output will arrange "a b c"
What I would like is if I click C,B,A the output should arrange "c b a"
I've tried various CSS positioning rules to do this, but the best I can do is have them arrange in the same position as each other. I realize I could make a new class for each but would rather not do it that way in the interest of minimal code and I'm learning right now so it would be useful to know a better way around the issue.
Here's a fiddle: http://jsfiddle.net/xuxsuagg/4/
You can do something like
$(".myclass").one('click', function() {
$($(this).data('target')).appendTo('.output').show();
});
a {
text-decoration: none;
}
.sq {
display: none;
}
.output {}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
A
B
C
D
E
F
<p class="output">
<span class="sq" id="01">A</span>
<span class="sq" id="02">B</span>
<span class="sq" id="03">C</span>
<span class="sq" id="04">D</span>
<span class="sq" id="05">E</span>
<span class="sq" id="06">F</span>
</p>
Notes
Used a common event handler instead of using different handlers for each link
Before shown the element the target is moved to the last position of the parent
Used .one() to register the handler so that one element is shown only once
There is a very simple trick: use .append(). When you append a selected element that is already present in the DOM, you are actually moving it around. Also, I recommend that to optimize your code, you can:
Use a common class for the <a> elements
Assigned a HTML5 data- attribute, say data-target, to specify the ID of its intended target
Listen to click events triggered on the common class
An example of the proposed new markup:
A
B
<!-- and more -->
Here is the code (and the demo fiddle here—http://jsfiddle.net/teddyrised/xuxsuagg/9/)
$('.sq-click').click(function(e) {
// Prevent default action
e.preventDefault();
// Use .append() to move element
var $out = $('.output');
$out.find('#'+$(this).attr('data-target')).appendTo($out).show();
});
On a side note, if you do not want the users to rearrange the order after an anchor has been clicked, you will have to rely on the .one() method for listening to click events. Also, it will help that you style the disabled anchors appropriately so the users can see it—see proof-of-concept demo: http://jsfiddle.net/teddyrised/xuxsuagg/26/
$('.sq-click').one('click', function(e) {
// Prevent default action
e.preventDefault();
// Use .append() to move element
var $out = $('.output');
$out.find('#'+$(this).attr('data-target')).appendTo($out).show();
// Add class to change appearance of disabled <a>
$(this).addClass('disabled');
});
And your CSS can look like this:
.disabled {
cursor: default;
opacity: 0.2;
}
You can simplify this code to:
var a = document.getElementsByTagName('a');
for (i = 0; i < a.length; i++) {
a[i].addEventListener('click', function() {
var span = document.createElement('span');
var text = document.createTextNode(this.innerHTML + " ");
span.appendChild(text);
document.getElementsByClassName('output')[0].appendChild(span);
})
}
a {
text-decoration: none;
}
.sq {
display: none;
}
A
B
C
D
E
F
<p class="output">
</p>
Bind the click event to the class that they share and not their own unique id.
In the function scope of clickClosure 'this' is referring to the current element.
$(".sq").click(function clickClosure(){
$(this).show();
});
Using styles to achieve this might range from painful to very hard, depending on the exact way you want them displayed. I'd suggest instead to re-order them in DOM. That might look something like this:
<a id="link-1">...</a>
...
<div style="display: none" id="hidden-items">
<span id="item-1">...</span>
</div>
<div id="visible-items"></div>
&
$('#link-1').click(function () {
$('#visible-items').append($('#item-1'));
});
As other respondents suggested, you could also optimize your code in various ways, but that's outside the scope of the question.
Try this: You can put empty <p class="output"> and remove display:none; from CSS .sq{... In jQuery, create a <span> on the basis of clicked link and append it to <p class="output">
HTML:
A
B
C
D
E
F
<p class="output">
</p>
CSS:
.sq{
/*display:none;*/
color: green;
margin-right: 10px;
}
jQuery
$("a[href='#']").click(function(e){
e.preventDefault();
var text = '<span class="sq" id="0'+$(this).prop('id')+'">'
+$(this).text()+'</span>';
$(text).appendTo('p.output');
});
DEMO
I am new at creating websites in HTML. I use free for all SeaMonkey software. So, I want to create several image buttons which would change when user moves the mouse over the image. I already have created 3 images for the different stages of each button (normal, active and clicked). I wrote this code for the first button:
<body>
<a href="first.html" onmouseover="return changeImage(jsbutton)" onmouseout="return changeImageBack(jsbutton)">
<img name="jsbutton" src="first normal.png" alt="first">
<script type="text/javascript">
function changeImage() {
document.images["jsbutton"].src= "first active.png";
return true;
}
function changeImageBack() {
document.images["jsbutton"].src = "first normal.png";
return true;
}
</script>
</a>
</body>
And it works. But when I did the same for second button, it didn't work and in addition to that, the first one has stopped working too. What do I have to change to make it work properly?
Update:
For second button I wrote:
<a href="second.html" onmouseover="return changeImage(jsbutton)"
onmouseout="return changeImageBack(jsbutton)">
<img name="jsbutton" src="second normal.png" alt="second">
<script type="text/javascript">
function changeImage()
{
document.images["jsbutton"].src= "second active.png";
return true;
}
function changeImageBack()
{
document.images["jsbutton"].src = "second normal.png";
return true;
}
</script> </a>
</body>
You are using the same "name" attribute i.e. jsbutton for the both the images. Use different name attributes. Also css :hover is a better way to do this problem.
Your JavaScript is failing because you are using the same name attribute for both images. Each element must have a unique name.
That being said, the functionality you are after is already built in to CSS, so unless you have a specific requirement for this to be JavaScript, this is a problem far better solved in CSS, using :hover.
So in your html:
In your CSS:
#firstButton {
background-image: url('first normal.png');
display:block;
height: [height of img];
width: [width of img];
}
#firstButton:visited {background-image: url('first visited.png'); }
#firstButton:hover { background-image: url('first active.png'); }
And you are done! No use recreating functionality already built in to CSS!
Well you can also use inline javascript for this purpose as it is pretty simple:
<a href="first.html" >
<img onmouseover="this.src = 'second active.png'; " src="second normal.png" onmouseout="this.src = 'second normal.png'; " alt="first" />
</a>
Here is the Demo , in which I used some random images urls
Hope this helps.
So the labels are populated from the database. Once the label is clicked, the label need to turn red and bold. when clicked on another label, the first label need to come back to original state and the new label should be activated and it needs to be bold and red. for some reason, the changeActiveStates() only works for the first 2 labels, i.e., when first label is clicked it turns red and when the second label is clicked the first label is turned black and the second label is turned red. when the third label is clicked, the second label remains red and the third one turns red. How do i fix this??
Here is the code:
<html>
<span>
<input type="hidden" name="LiabFilter" id= "idLib<%=liabkey %>" value="<%=liabkey %>" />
<div>
<label for="idLib<%=liabkey%>" id="liablabel" style="cursor: hand; padding-left: 25px; font-weight: normal"
onClick ="clearLiabFilter();
document.getElementById('idLib<%=liabkey%>').checked = true;
changeActiveStates(this);">
<%=liab.getName() %>
</br>
</label>
</div>
</span>
<style type="text/css">
.activate { font-weight: bold; color:#e40000;}
.visited{ font-weight: normal; color: #000000;}
</style>
<script>
function byId(id) {
return document.getElementById ? document.getElementById(id) : document.all[id];
}
var prevLink = "";
function changeActiveStates(ele) {
if (prevLink) byId(prevLink).className = '';
ele.className = 'activate';
prevLink = ele.id;
}
</script>
</html>
Are you averse to JQuery?
If not, this should work.
$('label').click(function() {
$('label').removeClass('activate'); /* Remove 'activate' class from all labels */
$(this).addClass('activate'); /* Add 'activate' class to clicked label
});
EDIT: Example on jsFiddle
EDIT: A little more detail as the questioner hasn't used JQuery before.
JQuery is a javscript library and so must be loaded by the browser before you can do all the nifty stuff.
Add the following between the <head></head> tags on your page:
<script src="http//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
(Why let google host JQuery for you?)
Then add the following, also between the tags but after the script tag given above:
$(document).ready(function() {
$('label').click(function() {
$('label').removeClass('activate'); /* Remove 'activate' class from all labels */
$(this).addClass('activate'); /* Add 'activate' class to clicked label
});
});
(What does $(document).ready() do?)
Maybe not the best of solutions, but have you considered using jQuery? It's generally not too much of a dependency , and will solve these sort of issues quite elegantly and easily for you. Plus. Cross-browser compatibility.