css hover event not working after using javascript? - javascript

Here is the code in which i am having the problem-
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
p {
font-family: Tahoma;
line-height: 170%;
color: #000;
font-size: 15px;
padding: 5px 0px 5px 0px;
text-align: center;
}
#col1 {
//some propeties
}
#col1:hover ~ p {
color: #f00;
}
#col2 {
//some propeties
}
#col2:hover ~ p {
color: #ff0;
}
</style>
</head>
<body>
<div id="col1"><span>Hover to view and click to select this color.</span></div>
<div id="col2"><span>Hover to view and click to select this color.</span></div>
<p>This is some text.</p>
<script type="text/javascript">
var pElements = document.getElementsByTagName("p");
$('#col1').click(function(){
for(var i = 0; i < pElements.length; i++) {
pElements[i].style.color = "#f00";
}
});
$('#col2').click(function(){
for(var i = 0; i < pElements.length; i++) {
pElements[i].style.color = "#ff0";
}
});
</script>
</body>
</html>
What i actually want is that when i hover a color div, the color of text in p tag changes for only that time when the color div is hovered. When the color div is clicked the color of text should change permanently.
The problem with is that once i click on 1 of the color divs to finalize it for p tag, and then after that the other color is hovered the color change doesnt take place. The color permanently changes on click as it should happen.

When you set the p elements style with pElements[i].style.color = "#f00"; you are setting a more specific style then the one applied by your hover. In CSS, the most specific style get's applied to the element. The CSS hover class you've got defined will never be applied because it is not specific enough to overwrite the inline styles applied by your javascript code.
You could modify your CSS hover class to use the !important tag, this should allow you to apply the hover style even though it is not as specific as the inline style.
#col2:hover ~ p {
color: #ff0 !important;
}

If its not a problem using JQuery, I think is what you want: Live Example
HTML code snippet
<div id="col1"><span>Hover to view and click to select this color.</span></div>
<div id="col2"><span>Hover to view and click to select this color.</span></div>
<p>This is some text.</p>
CSS code snippet
p {
font-family: Tahoma;
line-height: 170%;
color: #000;
font-size: 15px;
padding: 5px 0px 5px 0px;
text-align: center;
}
#col1 {
//some propeties
}
#col1:hover ~ p {
color: #f00 !important;
}
#col2 {
//some propeties
}
#col2:hover ~ p {
color: #ff0 !important;
}​
JS code snippet
$("#col1").click(function () {
$("p").css("color","#f00");
});
$("#col2").click(function () {
$("p").css("color","#ff0");
});
Hope it helps!

Related

How to reset all buttons colour back to its original and add a new specific colour when a specific button is clicked?

I am trying to make my buttons change colour when clicked. The easy button turns green, medium turns yellow, hard turns red and insane turns black. When I click any button on the first try it works however when I click on another button it is supposed to reset all the buttons back to white and change the button I clicked to the specified colour. Right now my code is resetting it back to default and not showing the clicked button colour.
document.querySelectorAll(".difficulty-button").forEach((gameMode) => {
gameMode.addEventListener("click", function() {
let linkColour = window.getComputedStyle(gameMode);
document.querySelectorAll(".difficulty-button").forEach((item) => {
item.style.backgroundColor = "green";
item.style.color = "black";
});
gameMode.style.backgroundColor = linkColour.backgroundColor;
});
});
ul {
display: flex;
justify-content: center;
}
ul li {
padding: 0;
list-style: none;
}
button {
box-shadow: none;
outline: none;
width: 10em;
height: 3.5em;
transition: 0.25s linear;
cursor: pointer;
background-color: white;
}
li:nth-child(1) button:hover {
background-color: rgb(51, 165, 50);
color: white;
}
li:nth-child(2) button:hover {
background-color: rgb(255, 255, 0);
}
li:nth-child(3) button:hover {
background-color: rgb(204, 50, 50);
color: white;
}
li:nth-child(4) button:hover {
background-color: black;
color: white;
}
<ul>
<li><button class="difficulty-button">Easy</button></li>
<li><button class="difficulty-button">Medium</button></li>
<li><button class="difficulty-button">Hard</button></li>
<li><button class="difficulty-button">Insane</button></li>
</ul>
The reason this only works the first time is to do with the way you get the colour to apply to the button, and how you apply the new colour.
Why it doesn't work:
You are using getComputedStyle to get the colour of the button when it is clicked. The first time it's clicked the hover class is applied, so to use is the one you clicked.
However then the javascript changes all the buttons to green directly using inline styles. These will override any other CSS being applied. Now every time you click, all the buttons are set to green so that colour is getting applied again.
Getting it to work: How to Swap CSS Classes on Click
You could hardcode the colours into the JS function and have an if to check which button it is. But a more flexible way to do this is to use your classes again.
1. Set up your CSS Classes. We already have rules set up for the colours you want, so if we give then a class name we can use them in the js, e.g.
.colorbutton-1, /* give the existing 1st button CSS a class called "colorbutton-1" */
li:nth-child(1) button:hover{
background-color: rgb(51, 165, 50);
color: white;
}
Do this for each button, and also set one up for the default unselected state, e.g.
.colorbutton-0{
background-color:green;
color: black;
}
Note the classes all start with the same name colorbutton - this is important! This is what we will use in the js later.
2. Write a function to swap the classes on the buttons depending on what was clicked. We'll pass in the button and which button number this is (i.e. 1,2,3,4).
In the function we remove all classes starting with colorbutton, and then add the new class - this is made up of the colorbutton- and the number of the button. If we want to apply the unselected style, we use 0.
function swapClass(btnElement, btnNum){
// remove all existing classes starting with "colorbutton"
btnElement.classList.forEach(className => {
if (className.startsWith('colorbutton'))
btnElement.classList.remove(className);
});
// now add the new class
btnElement.classList.add('colorbutton-'+ btnNum);
}
3. Add your click listeners to listen for clicks and change the classes depending on which button was clicked.
// add a "counter" in forEach that passes the index of the element being processed, e.g. 0,1,2 etc
document.querySelectorAll(".difficulty-button").forEach((gameMode, btnNum) => {
// add the click listener for the current button
gameMode.addEventListener("click", function () {
// on a click, remove all 'colorbutton' classes and set them to the default
document.querySelectorAll(".difficulty-button").forEach((item) => {
swapClass(item, 0);
});
// add the class for this button, passing in the class number to generate the classname
swapClass(this, (btnNum+1));
});
});
Working Example Putting this all together:
document.querySelectorAll(".difficulty-button").forEach((gameMode, btnNum) => {
gameMode.addEventListener("click", function () {
document.querySelectorAll(".difficulty-button").forEach((item) => {
changeClass(item, 0);
});
changeClass(this, (btnNum+1));
});
});
function changeClass(btnElement, classRef){
// remove all existing classes starting with "colorbutton"
btnElement.classList.forEach(className => {
if (className.startsWith('colorbutton'))
btnElement.classList.remove(className);
});
// now add the new class
btnElement.classList.add('colorbutton-'+classRef);
}
ul {
display: flex;
justify-content: center;
}
ul li {
padding: 0;
list-style: none;
}
button {
box-shadow: none;
outline: none;
width: 10em;
height: 3.5em;
transition: 0.25s linear;
cursor: pointer;
background-color: white;
}
.colorbutton-0{
background-color:green;
color: black;
}
.colorbutton-1,
li:nth-child(1) button:hover{
background-color: rgb(51, 165, 50);
color: white;
}
.colorbutton-2,
li:nth-child(2) button:hover{
background-color: rgb(255, 255, 0);
}
.colorbutton-3,
li:nth-child(3) button:hover{
background-color: rgb(204,50,50);
color: white;
}
.colorbutton-4,
li:nth-child(4) button:hover{
background-color: black;
color: white;
}
<ul>
<li><button class="difficulty-button">Easy</button></li>
<li><button class="difficulty-button">Medium</button></li>
<li><button class="difficulty-button">Hard</button></li>
<li><button class="difficulty-button">Insane</button></li>
</ul>
Just like the pseudo class you are using for button:hover, CSS also provides pseudo classes for active and visited.
You should be able to do something like the following, which would change the color of the button once it is selected and revert it when new button is selected.
li:nth-child(4) button:active {
background-color: black;
color: white;
}

vaadin-combo-box / vaadin-combo-box-overlay change background color / Polymer API

I'm trying to override the background color present in vaadin-combo-box-overlay element.
Here is the css that I want to override, more specifically the background property, source taken from (https://github.com/vaadin/vaadin-combo-box/blob/master/vaadin-combo-box-overlay.html)
:host {
position: absolute;
#apply(--shadow-elevation-2dp);
background: #fff;
border-radius: 0 0 2px 2px;
top: 0;
left: 0;
.......
}
So I've tried something like:
:root ::content vaadin-combo-box-overlay.vaadin-combo-box-overlay {
background: red !important;
background-color: red !important;
}
Also I've tried with :host but I guess it should be used :root because I use this dropdown in a dialog, and the overlay component doesn't seem to be a child of the dialog. I've tried different combinatons as the one mentioned above without any success.
Also I'm wondering why the background is not parameterized as the text color is:
#selector .item {
cursor: pointer;
padding: 13px 16px;
color: var(--primary-text-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Specifying a different value for --primary-text-color I'm able to change the text color..
Thanks.
you can do it with javascript like that.
ready: function() {
var domElem=Polymer.dom(this).node.$.YOUR-VAADIN-ELEMENT-ID.$.overlay.style.backgroundColor="red";
}
OR
ready: function() {
var css = '#selector .item { background-color:red; }';
var style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(css));
Polymer.dom(this).node.$.tourSelector.$.overlay.$.selector.appendChild(style);
}
Would like to have a working CSS selector, but i cant set breakpoints in CSS to find out the right selectors!
You should use dom-module for styling vaading parts see example below:
<dom-module id="combo-box-overlay-styles" theme-for="vaadin-combo-box-overlay">
<template>
<style>
[part~="content"] {
background-color: red;
}
</style>
</template>
</dom-module>
Read more here https://github.com/vaadin/vaadin-themable-mixin/wiki
Thanks Patrick !!
I wasn't thinking about to do try it this way.
Here's what I did, a hacky solution though.
ready : function(){
var combo = this.$$('#comboid');
combo.addEventListener('vaadin-dropdown-opened'', function() {
var overlay = Polymer.dom(this.root).querySelector('#overlay');
overlay.style.backgroundColor = primaryBackground;
});
},
I only have access to the overlay when the combo is expanded, so in the value change listener the combo would be expanded.

Dynamically add !important to all CSS properties

How can I dynamically add !important for all CSS properties?
For example in my <head></head> section I have:
<style>
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.main-container {
border: 3px solid yellow;
padding: 10px 5px;
margin: 3px;
}
</style>
I need:
<style>
.text-center {
text-align: center !important;
}
.text-left {
text-align: left !important;
}
.main-container {
border: 3px solid yellow !important;
padding: 10px 5px !important;
margin: 3px !important;
}
</style>
I tried to use Window.getComputedStyle(), but I must provide to this method the element for which I want to get the computed style. In my case I can't provide these elements.
I was having an issue with printing (with css styling) in Chrome and Firefox..
even adding -webkit-print-color-adjust: exact!important; didnt work in my case
until i figured out that the style need to have !important attribute. When working with WYSWYG Editor, this could be a problem for printing. So I need to add !important to every css style attribute found in every element.
Here's how I solved it using jQuery
//add !important rule to every style found in each element
//so the browser print render the color/style also
var el = $('.content *');
if (el.length) {
el.each(function(item) {
var _this = $(this);
var attr = _this.attr('style');
var style = '';
if (typeof attr !== typeof undefined && attr !== false) {
if (attr.split(';').length) {
attr.split(';').forEach(function(item) {
if (item.trim() != '') {
style += item.trim() + '!important;-webkit-print-color-adjust: exact!important;';
}
});
_this.attr('style', style);
}
}
});
}
Here's the result in Printing Preview before and After adding the Code Hack
I run into this problem with pandas DataFrame Styler. It generated a <style> tag element with all the styling info. But the styling is overridden by linked css files.
So my solution is to replace all ; with !important; using JavaScript
CSS:
<style type="text/css" >
#T_195822c0_1b0f_11e9_93d2_42010a8a0003row10_col4 {
background-color: yellow;
} #T_195822c0_1b0f_11e9_93d2_42010a8a0003row73_col5 {
background-color: yellow;
} #T_195822c0_1b0f_11e9_93d2_42010a8a0003row100_col2 {
background-color: yellow;
}</style>
Javascript:
var st = document.getElementsByTagName("STYLE")[0];
st.innerHTML = st.innerHTML.replace(/yellow;/g,'yellow !important;')
You can adapt replace rules to your need.

Including style tag in javascript

I want to include style tag in the javascript. ie., I am printing notices and the number of notices change dynamically. I receive the notices in a JSON object and hence require styles to be applied to each notice separately.
For now I just want the border around each notice or text
function retrive()
{
/*var css = ' { border :2px dashed; }',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css'; Not working*/
var myObj = JSON.parse(localStorage.getItem("Notice"));
if(myObj.length == 0)
{
$('#title').append(
'<br><br>Currently There are no Notices to be displayed'
);
}
else
{
for(var i = 0; i < myObj.length; i++)
{
$('#heading').append(
'<br><br><strong><center>'+ myObj[i].title+'</center></strong><br>'+myObj[i].introtext
);
}
}
}
I am printing the notices in the else block using for loop by finding the object length and appending it to the heading. This is where I want to print border to be printed around each block
<div>
<ul id="heading" style = "font-size : 16px;">
</ul>
</div>
If I use style here, border is appears to whole block or a single border to all notices.
<div>
<ul id="heading" style = "font-size : 16px; border : 2px dashed">
</ul>
</div>
,which is obvious.
Thanks.
I believe that you could handle this entirely with CSS and applicable classes. If you need to make changes based on the number of items, you could define classes for the different sets of count values that would result in the same CSS settings and simply apply that class to the header. Based on what you have in your code, that doesn't look to be the case and the example below should approximate what you're trying to achieve.
Note: I'm assuming that you're using a standard CSS reset to remove list styles. If not, then I suggest that you should.
<style>
#title p {
padding-top: 1em;
}
#heading {
font-size: 16px;
}
#heading li {
border: 2px dashed;
}
#heading li span.item_title {
font-weight: bold;
display: block;
text-align: center;
}
#heading li span.item_text {
display: block;
}
</style>
function retrive()
{
var myObj = JSON.parse(localStorage.getItem("Notice"));
if(myObj.length == 0)
{
$('#title').append('<p>Currently There are no Notices to be displayed</p>' );
}
else
{
for(var i = 0; i < myObj.length; i++)
{
$('#heading').append('<li><span class="item_title">'+ myObj[i].title+'</span><span class="item_text"'+myObj[i].introtext+ "</span></li>" );
}
}
}
If you use CSS classes you will be able to change the design more easily later, by modifying the CSS, rather than the JavaScript and HTML.
<style>
.heading
{ font-size : 16px; border : 2px dashed; }
</style>
<div>
<ul id="heading" class="heading">
...
</ul>
</div>
You can put the HTML in your JavaScript as you already have it, and use as many classes as you need.
In addition, try to avoid using <strong> and <br> and use CSS to control the layout.
You can apply a css style to each notice inside of #heading.
Something like this should work fine (place this in your css file or inside of a style tag) :
#heading strong {
border: 2px dashed;
}
I would recommend surrounding each notice in a span and append this to your #heading inside of an li and then applying this style:
#heading li {
list-style:none;
margin: 0 auto;
text-align: center;
}
#heading li span {
border: 2px dashed;
font-weight: bold;
}
you html would look something like this:
<ul id='heading'>
<!-- your newly inserted notice -->
<li><span>text</span></li>
</ul>
This will remove the need for the center and br tags.

Highlighting input in textarea

I'm trying to achieve a highlight effect in my textarea, basically as a user types a sentence, a background color is being added, similar to this effect: http://jsbin.com/josatozeyi/1/edit (I know it's the resizing of textarea but is there any other way?)
<textarea class='animated'>With CSS transition.</textarea>
Any suggestions?
ADDITIONAL INFO
This is what I meant: http://prntscr.com/63xdi9
It's too complicated to me, however I found this, it might be useful:
highlightTextarea aim is to highlight portions of text into a textarea
or a input. It can highlight a set of words or a specific range.
http://mistic100.github.io/jquery-highlighttextarea/
Source: mistic100
Add a css rule that adds a background color to the textarea on focus.
input:focus {
background-color: yellow;
}
You can achieve the affect you want with contenteditable span element, and then applying a background color on focus: http://jsfiddle.net/13L9zudf/
$(document).ready(function(){
var defaultVal = "Type content here...";
$("div.textbox span").keyup(function(){
if($(this).html() == "")
{
$(this).html(defaultVal);
}
}).keydown(function(){
if($(this).html() == defaultVal)
{
$(this).html("");
}
});
});
div.textbox {
border: 1px #000 solid;
padding: .5em;
width: 30em;
height: 10em;
overflow-y: scroll;
}
div.textbox span {
line-height: 1.5em;
max-width:30em;
display: inline-block;
}
div.textbox span:focus {
background: #ff0;
border:0;
outline: 0;
}
div.textbox span:active {
border: 0;
outline: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="textbox">
<span contenteditable="true">Type content here...</span>
</div>

Categories

Resources