change style dynamically of none html element - javascript

I'm using angularJs and want to change the style of an attribute dynamically.
Normally I would do this with ng-style in the html element.
But I want to apply styles to the track of a range input.
This element can be accessed in css like that: .slider::-webkit-slider-runnable-track(As Example for the webkit selector). Can I change the style for such an attribute in a function where I have the id for this element?
E.g (how I would do it in jquery):
$scope.change = function(id, value) {
$('#'+id+'::-webkit-slider-runnable-track').css('background-image',value);
};

Javascript generally don't have access to pseudo elements, one possible workaround would be to insert a style tag
$scope.change = function(id, value) {
var style = document.createElement('style');
var styles = '{ background: red }';
style.innerHTML = '#' + id + '::-webkit-slider-runnable-track ' + styles;
document.head.appendChild(style)
};
FIDDLE
Another way would be to keep the styles in the stylesheet, and just use a different class for a different style
#test.red::-webkit-slider-runnable-track {
background : red;
}
and then do
document.getElementById('test').classList.add('red');
FIDDLE

for AngularJs I recommend not to use $scope but use service, factory or directory instead for CSS type of work on html template.
however if you must still want to take this approach you can:
$scope.change = function(id, cssClass, add) {
var el = angular.element(document.querySelector(id));
if (add) {
el.addClass(cssClass);
} else {
el.removeClass(cssClass);
}
}
where you can pass id for element, cssClass from your css class and use add as bool value; pass what ever you want.

Related

Change styling of a psuedo after element with javascript

Is it possible to change the styling of a psuedo :after element with javascript something like this:
document.querySelector('#test:after').attr("style", "content:url('blabla.png')");
Is there any workaround to change the image after 1 click like this:
var timesClicked = 0;
span = document.querySelector('.socialShare');
span.addEventListener('click', function (e) {
timesClicked++;
if (timesClicked > 1) {
document.querySelector('#socialShare').style.left = '-60px';
timesClicked = 0;
console.log(timesClicked)
} else {
document.querySelector('#socialShare').style.left = '0';
document.querySelector('#socialShare:after').attr("style", "content:url('blabla.png')");
console.log(timesClicked)
}
});
Or maybe better transform the image it is about an arrow which needs to point the other way when div is expanded
You can't change styles of pseudo elements with javascript, because they are not part of the DOM, and so do not have any API to work with.
Usual approach is to change classes of the element itself and have those classes affect related pseudo elements. For example in your case:
// Add class selected to element
document.querySelector('#test').classList.add('selected')
In CSS:
#test.selected::after {
content: url('blabla.png');
}

Achieve "::-moz-focus-inner {border:0;}" in javascript

I'd like to remove the ugly focus outline on an input button in firefox. I've tried adding ::-moz-focus-inner {border:0;} as style in my html, which works initially, but not when button elements are re-created via javascript.
I've tried:
cell.style.mozFocusInner.border = "0";
cell.style["-moz-focus-inner"] = "{border:0}";
cell.style["-moz-focus-inner"]["border"] = "0";
etc.
In general, how do I "map" css to javascript?
According to the CSS property to IDL attribute algorithm, a -moz-focus-inner would be camelCased to MozFocusInner. So you could use one of
element.style.MozFocusInner = value;
element.style.setPropertyValue('-moz-focus-inner', value);
element.style.setProperty('-moz-focus-inner', value);
element.style.setProperty('-moz-focus-inner', value, '!important');
But there is a big problem: -moz-focus-inner is not a CSS property, is a pseudo-element.
Given an element, you can read the computed styles of its pseudo-elements via getComputedStyle:
getComputedStyle(element, '::-moz-focus-inner').borderTopWidth; // 1px
However, you can't set them directly. If you want to do that, you can:
Conditionally set the desired styles in a stylesheet, and use JS to trigger that condition whenever you want. For example, add a class.
document.getElementById('enable').addEventListener('click', function() {
document.getElementById('target').classList.remove('no-focus-inner');
});
document.getElementById('disable').addEventListener('click', function() {
document.getElementById('target').classList.add('no-focus-inner');
});
.no-focus-inner::-moz-focus-inner {
border: none;
}
<ol>
<li><button id="enable">Enable inner outline</button> or <button id="disable">Disable inner outline</button></li>
<li>Press Tab key</li>
<li><button id="target">Focus me to check if I have inner outline</button></li>
</ol>
Create a new stylesheet with the desired rulesets, and append it to the document.
var styleSheet = document.createElement('style');
styleSheet.textContent = '#target::-moz-focus-inner { border: none; }';
document.getElementById('enable').addEventListener('click', function() {
if(styleSheet.parentNode) document.head.removeChild(styleSheet);
});
document.getElementById('disable').addEventListener('click', function() {
document.head.appendChild(styleSheet);
});
<ol>
<li><button id="enable">Enable inner outline</button> or <button id="disable">Disable inner outline</button></li>
<li>Press Tab key</li>
<li><button id="target">Focus me to check if I have inner outline</button></li>
</ol>
Maybe this works without javascript: https://css-tricks.com/forums/topic/button-padding-issue/
::moz-focus-inner is a pseudo-element. In this link are several ways how to modify pseudo-elements dynamically (with javascript) http://pankajparashar.com/posts/modify-pseudo-elements-css/
cited from http://pankajparashar.com/posts/modify-pseudo-elements-css/ :
<p class="red">Hi, this is a plain-old, sad-looking paragraph tag.</p>
.red::before {
content: 'red';
color: red;
}
Method 1
Write separate classes attached with pseudo element for each style and then using JavaScript or jQuery toggle between these classes.
.green::before {
content: 'green';
color: green;
}
$('p').removeClass('red').addClass('green');
...
Common css-styles (not pseudo-elements) can be modified using javascript like this:
cited from https://www.kirupa.com/html5/setting_css_styles_using_javascript.htm :
Every HTML element that you access via JavaScript has a style object. This object allows you to specify a CSS property and set its value. For example, this is what setting the background color of an HTML element whose id value is superman looks like:
var myElement = document.querySelector("#superman");
myElement.style.backgroundColor = "#D93600";
To affect many elements, you can do something as follows:
var myElements = document.querySelectorAll(".bar");
for (var i = 0; i < myElements.length; i++) {
myElements[i].style.opacity = 0;
}
In a nutshell, to style elements directly using JavaScript, the first step is to access the element. I am using the querySelector method to make that happen. The second step is just to find the CSS property you care about and give it a value. Remember, many values in CSS are actually strings. Also remember that many values require a unit of measurement like px or em or something like that to actually get recognized.

ng-mouseover ng-mouseout not woking

below is my code, I'm trying to make the content wrapped in div tag change the background color when the mouse curse over it, if the one of the content's variable starts with *. But it doesn't work...
// html
<style>
.normal{background-color: white}
.change{background-color: gainsboro}
</style>
<div ng-mouseover="checkAs(this)" ng-mouseout="this.className='normal'">
......
</div>
// js
$scope.checkAs = function(obj) {
var name = $scope.opportunity.name;
var asterisk = '*';
if(name.startsWith(asterisk)) {
obj.className='change';
} else {
obj.className='normal';
}
};
If you are determined to do this in angular, you would have to call a function through ng-mouseover and in that function, you would need a selector such as JQuery or Javascript's query selector, then modify the element as you see fit. You would have to do something like this (using JQuery):
$scope.checkAs = function() {
$("div").hover(function() {
$(this).prop('background-color','gainsboro');
}, function(){
$(this).prop('background-color','white');
});
};
But, as PSL suggested, the "this" in checkAs(this) won't be the DOM element. A CSS solution might be better:
div :hover{
background-color: gainsboro
}

Get child element by HTML Object

I'm attempting to reuse the variable "startGame", variable through which I declare an "a" element to be appended to the "table" element, in order to test for its own presence posteriorly. The code I've written for doing so is the following:
//Helper function to set HTML Tags attributes
function setAttributes(element, attributes)
{ for (var key in attributes) { element.setAttribute(key, attributes[key]); } }
//Opening screen
var startGame = document.createElement("a");
setAttributes(startGame,
{
"style" : "float:left; width: 100%; text-align: center;",
"onclick" : "dealHands()"
});
startGame.appendChild(document.createTextNode("Play"));
var table = document.getElementById("table");
table.appendChild(startGame);
function dealHands()
{
if (table.childNodes[0].nodeValue == startGame)
{ table.removeChild(startGame); }
...
}
So far, the code fails to perceive "startGame" and nothing happens.
You cannot set the style attributes using this:
"style" : "float:left; width: 100%; text-align: center;"
they have to be set individually. But IE doesn't support changing style in this way. You need:
element.style.cssFloat = "left"; // etc.
Discussed here
Also, I wouldn't use table as an ID.
I just had to remove the ".nodeValue" from the if statement in order to make a comparison between two HTML elements instead of comparing a value with a HTML element.

change div/link class onclick with js - problems

Figured out how to change the class of a div/link/whatever onclick with JS. Here's a quick demo: http://nerdi.net/classchangetest.html
Now what I'm trying to figure out is how I can revert the previously clicked link to it's old class (or "deactivate") when clicking a new link.
Any ideas? Thanks!
function changeCssClass(navlink)
{
var links=document.getElementsByTagName('a');
for(var i=0, n=links.length; i<n; i++)
{
links[i].className='redText';
}
document.getElementById(navlink).className = 'blueText';
}
With this code all links will be red and lust clicked will be blue.
I hope it will be helpfull.
function changeCssClass(ele, add_class) {
// if add_class is not passed, revert
// to old className (if present)
if (typeof add_class == 'undefined') {
ele.className = typeof ele._prevClassName != 'undefined' ? ele._prevClassName : '';
} else {
ele._prevClassName = ele.className || '';
ele.className = add_class;
}
}
Try it here: http://jsfiddle.net/Zn7BL/
Use it:
// add "withClass"
changeCssClass(document.getElementById('test'), 'withClass');
// revert to original
changeCssClass(document.getElementById('test'));
It is a much better to post your code here, it makes it easier for those reading the question and for others searching later. Linked examples are unreliable and likely won't persist for long.
Copying from the link (and formatting for posting):
<style type="text/css">
.redText, .blueText { font-family: Arial; }
.redText { color : red; }
.blueText { color : blue; }
</style>
<script language="javascript" type="text/javascript">
The language attribute has been deprecated for a very long time, it should not be used. The type attribute is required, so keep that.
function changeCssClass(navlink)
The HTML class attribute is not sepecifically for CSS, it is used to group elements. A better name might be changeClassName.
{
if(document.getElementById(navlink).className=='redText')
{
document.getElementById(navlink).className = 'blueText';
}
else
{
document.getElementById(navlink).className = 'redText';
}
}
</script>
Link 1<br><br>
When called, the function associated with an inline listener will have its this keyword set to the element, so you can call the function as:
<a ... onclick="changeCssClass(this);" ...>
Then you don't have to pass the ID and you don't need getElementById in the function.
You might consider a function that "toggles" the class: adding it if it's not present, or removed if it is. You'll need to write some small functions like hasClass, addClass and removeClass, then your listener can be:
function toggleClass(el, className) {
if (hasClass(el, className) {
removeClass(el, className);
} else {
addClass(el, className);
}
}
Then give your links a default style using a style rule (i.e. apply the redText style to all links), then just add and remove the blueText class.
You might also consider putting a single function on a parent of the links to handle clicks from A elements — i.e. event delegation.

Categories