I have 5 css classes with different type of colors in a buttons for on hover function, in my page might be have 5 buttons with diffenent classes. When i hover the each button, color should be set as per respective class name so far its working fine for me. but now i can see huge code, i want to make it smaller. Please suggest anyone.
$('[class^="button"]').parent().each(function(){
var parentElement = $(this);
var buttonfullwidth = $(parentElement).hasClass('buttonfullwidth');
var buttonfullwidth_1 = $(parentElement).hasClass('buttonfullwidth_1');
var buttonfullwidth_2 = $(parentElement).hasClass('buttonfullwidth_2');
var buttonfullwidth_3 = $(parentElement).hasClass('buttonfullwidth_3');
var buttonfullwidth_4 = $(parentElement).hasClass('buttonfullwidth_4');
if(buttonfullwidth_1 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_1');
}, function(){
$(this).removeClass('buttonfullwidth_1');
});
}
if(buttonfullwidth_2 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_2');
}, function(){
$(this).removeClass('buttonfullwidth_2');
});
}
if(buttonfullwidth_3 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_3');
}, function(){
$(this).removeClass('buttonfullwidth_3');
});
}
if(buttonfullwidth_4 !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth_4');
}, function(){
$(this).removeClass('buttonfullwidth_4');
});
}
if(buttonfullwidth !== false) {
$(parentElement).hover(function(){
$(this).addClass('buttonfullwidth');
}, function(){
$(this).removeClass('buttonfullwidth');
});
}
});
You need CSS for this job by using the :hover pseudo selector
The :hover CSS pseudo-class matches when the user interacts with an element with a pointing device, it is generally triggered when the user hovers over an element with the mouse pointer.
For example, if you want this button to turn blue when hovered:
.myButton {
background-color: lightgreen;
}
.myButton:hover {
background-color: lightblue;
}
<button class="myButton">Hover this button</button>
Notice how I can set properties to the element when it is in his hover state.
So for your code you simply need to use the following selectors:
buttonfullwidth
buttonfullwidth:hover
buttonfullwidth_1
buttonfullwidth_1:hover
buttonfullwidth_2
buttonfullwidth_2:hover
buttonfullwidth_3
buttonfullwidth_3:hover
buttonfullwidth_4
buttonfullwidth_4:hover
in the same manner as I did in my example.
Related
Here is my code for a class called Toggle, that toggles multiple components in my site. The HTML has a data attribute on it called data-expand-content, and the css is set up to say that when data-expand-content is true, display: block or whatever this content. And the JS is what toggles the data attribute on click. It works fine on all browsers except for IE11, please help me figure out what is wrong?
Thanks!
Here's the JS
class Toggle {
constructor(control, el) {
const toggleLink = document.querySelector('.primary-nav__toggle-link');
control = document.querySelector(control);
el = document.querySelector(el);
if(el) {
control.addEventListener('click', function(e) {
if(el.dataset.expandContent == "false") {
el.dataset.expandContent = "true"
if(e.target == document.querySelector('.primary-nav__toggle-icon')) {
document.querySelector('.primary-nav__toggle-icon').setAttribute('src', '../assets/close-menu.svg');
}
} else {
el.dataset.expandContent = "false";
if(e.target == document.querySelector('.primary-nav__toggle-icon')) {
document.querySelector('.primary-nav__toggle-icon').setAttribute('src', '../assets/burger-menu.svg');
}
}
})
}
}
}
// new instances of class that get passed a control and a the element that gets toggled
const menu = new Toggle('.primary-nav__toggle-link', '#primary-nav');
const bannerEl = new Toggle('.banner', '.banner');
I want to detect clicking outside an element using class name as
selector
<div id="popOne" class="pop">...</div>
<div id="popTwo" class="pop">...</div>
...
<div id="popLast" class="pop">...</div>
<script>
var popElement = document.getElementById("pop");
document.addEventListener('click', function(event) {
var isClickInside = popElement.contains(event.target);
if (!isClickInside) {
alert("Outside");
//the click was outside the popElement, do something
}
});
</script>
As an alternative to iterating over all possible .pop elements for every click event, just traverse the DOM looking to see if the node or any ancestor thereof has the desired class:
document.addEventListener('click', function(e) {
var node = e.target;
var inside = false;
while (node) {
if (node.classList.contains('pop')) {
inside = true;
break;
}
node = node.parentElement;
}
if (!inside) {
alert('outside');
// click was outside
} else {
alert('inside');
}
});
This would make the performance scale relative to the depth of the DOM tree, rather than by the number of .pop elements.
Made the following changes to the script
var popElement = document.getElementsByClassName("pop");
document.addEventListener('click', function(event) {
for(i=0; i < popElement.length; i++){
popEl = popElement[i];
var isClickInside = popEl.contains(event.target);
if (!isClickInside) {
alert("Outside");
} else {
alert("Inside");
break;
}
}
});
First of all you are using the incorrect function to get Element. It should be getElementsByClassName("pop") and not getElementsById("pop") and also getElementsByClassName returns a HTMLCollection of elements having that class. So you need to loop over them and check whether clicked inside any of them or not. Here is the demo. Have added some style to divs so that it easy to differentiate between them. And also if need to check whether the click was on any of the divs then you need to check for that and as soon as you find that it was clicked inside a div having class pop. Break from the loop and continue with you conditions. But if for all the elements the IsClickedInside comes out to be false then you can handle it accordingly
document.addEventListener('click', function(event) {
var popElement = document.getElementsByClassName("pop");
var isClickInside;
for (var i = 0; i < popElement.length; i++) {
isClickInside = popElement[i].contains(event.target);
if (isClickInside) {
break;
//alert("Outside of" + popElement[i].id);
//the click was outside the popElement, do something
}
}
if(isClickInside){
alert("Clicked inside one of the divs.");
}else{
alert("Clicked outside of the divs.");
}
});
div {
height: 100px;
border:2px solid black;
}
<div id="popOne" class="pop">...</div>
<div id="popTwo" class="pop">...</div>
...
<div id="popLast" class="pop">...</div>
Hope it helps :)
Ok so I'm using Jquery UI Selectable to highlight some cells in a table. I would like to be able to add a border around the highlighted cells using like a 2px border. This way each time you highlight a section you can tell the separation between each section that has been highlighted. I am also hoping I can achieve this result with overlapping sections.
I've done quite a bit of reading and haven't really seen anyone trying to do this yet. So I'm wondering if someone might be able to point me in the right direction on how to achieve this effect.
Here's a fiddle of my example and some code below.
var shadeColor = $(".color-pallet > .active").css("background-color");
applySelectable = function() {
$(".block-tools > .shade-btn").click(function() {
var $this = $(this);
if (!$this.hasClass("active")) {
$this.siblings().removeClass("active");
$this.addClass("active");
}
});
$(".color-pallet > span").click(function() {
var $this = $(this);
if (!$this.hasClass("active")) {
$this.siblings().removeClass("active");
$this.addClass("active");
shadeColor = $(this).css("background-color");
}
});
// keep selected shade color selected after new question
if (shadeColor !== $(".color-pallet > .active")) {
$(".color-pallet > span").filter(function(){
var color = $(this).css("background-color");
if (color === shadeColor) {
$(this).click();
};
});
}
$(".blocks").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
filter: "td",
selecting: function (event, ui) {
if ($('.block-shade').hasClass("active")) {
$(ui.selecting).addClass('marked').css("background-color", shadeColor);
} else {
$(ui.selecting).removeClass('marked').css("background-color", "");
}
userAns = $('.marked').length+"";
}
});
};
applySelectable();
Thank you in advance for you time.
EDIT: For bonus points, can someone tell me when im dragging a selection, why is the containers height growing and creating a scroll bar? This has been seriously bugging me for some time and I chose to ignore it but I guess while I'm here maybe someone could explain this as well?
Huh... here is some kind of solution, i've added 4 css classes, and some ugly code... but it is working...
$(".blocks").bind("mousedown", function(e) {
e.metaKey = true;
}).selectable({
filter: "td",
selecting: function (event, ui) {
if ($('.block-shade').hasClass("active")) {
$(ui.selecting).addClass('marked').css("background-color", shadeColor);
$(ui.selecting).addClass('top');
$(ui.selecting).addClass('left');
$(ui.selecting).addClass('bottom');
$(ui.selecting).addClass('right');
if($(ui.selecting).prev().hasClass('marked')) {
$(ui.selecting).removeClass('left');
$(ui.selecting).prev().removeClass('right');
}
if($(ui.selecting).next().hasClass('marked')) {
$(ui.selecting).removeClass('right');
$(ui.selecting).next().removeClass('left');
}
top_elem=$(ui.selecting).parent().prev('tr').find('td');
// console.log(top_elem);
$(top_elem).each(function(i) {
if($(this).hasClass('marked')) {
if($(this).offset().left==$(ui.selecting).offset().left)
{
$(this).removeClass('bottom');
$(ui.selecting).removeClass('top');
}
}
});
bottom_elem=$(ui.selecting).parent().next('tr').find('td');
$(bottom_elem).each(function(i) {
if($(this).hasClass('marked')) {
if($(this).offset().left==$(ui.selecting).offset().left)
{
$(this).removeClass('top');
$(ui.selecting).removeClass('bottom');
}
}
});
} else {
$(ui.selecting).removeClass('marked').css("background-color", "");
$(ui.selecting).removeClass('top');
$(ui.selecting).removeClass('left');
$(ui.selecting).removeClass('bottom');
$(ui.selecting).removeClass('right');
}
userAns = $('.marked').length+"";
}
});
};
applySelectable();
});
DEMO: http://jsfiddle.net/wh2ehzo3/10/
However, overlapping is really, really tricky IF YOU WANT to KEEP borders on overlapping parts.. test... (just OUTER border of both shapes is saved, i hope you will see what i mean)
Idea: check siblings -> remove classes accordingly, if there is .marked element, check up and down rows -> do the same...
Couldn't find a solution that actually worked, but I want that on a click, a div shows.
Now this works when I load the page, but then after that first click, I have to click twice every time for the div to show.
Any ideas?
$(document).ready(function () {
setMenu();
});
function setMenu()
{
var headerExtIsOpen = false;
$('#headerExt').hide();
$('#header').click(function () {
if (!headerExtIsOpen) {
$('#headerExt').show();
headerExtIsOpen = true;
} else {
$('#headerExt').hide();
headerExtIsOpen = false;
}
});
}
There is no need to remember the state, just use toggle()
$(function () {
setMenu();
});
function setMenu()
{
$('#headerExt').hide();
$('#header').on("click", function (e) {
e.preventDefault();
$('#headerExt').toggle();
});
}
You said you want to toggle other things.
Best thing would be to toggle a class to change the color
$('#header').on("click", function (e) {
e.preventDefault();
$(this).toggleClass("open");
$('#headerExt').toggle();
});
another way is to check the state
$('#header').on("click", function (e) {
e.preventDefault();
var child = $('#headerExt').toggle();
var isOpen = child.is(":visibile");
$(this).css("background-color" : isOpen ? "red" : "blue" );
});
if the layout is something like
<div class="portlet">
<h2>Header</h2>
<div>
<p>Content</p>
</div>
</div>
You can have CSS like this
.portlet h2 { background-color: yellow; }
.portlet > div { display: none; }
.portlet.open h2 { background-color: green; }
.portlet.open > div { display: block; }
And the JavaScript
$(".portlet h2 a").on("click", function() {
$(this).closest(".portlet").toggleClass("open");
});
And there is layouts where it would be possible to have zero JavaScript involved.
Turns out I had some script hidden in my .js file that closes the menu again when the user clicks elsewhere, that I forgot about.
function resetMenu(e) {
var container = $('#headerExt');
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
$('#header').css("background-color", "inherit");
container.hide();
headerExtIsOpen = false;
}
}
I forgot to set the headerExtIsOpen back to false again after closing it in this function (code above shows the fix). Now it works fine :)
I want to toggle a div#featuredout using a button .featToggle and I want the browser to remember via cookies whether the div#featuredout should be hidden or shown. If possible, I'd like it to be so that if #featuredout is hidden, .featToggle should have an additional class of "hidden" and if #featuredout is shown, .featToggle should have an additional class of "shown".
I'm very very inexperienced with Javascript so any help would be great.
This is my current code:
$(document).ready(function() {
// When the toggle button is clicked:
$('.featToggle').click(function() {
$('#featuredout').slideToggle(550);
var featuredoutC = $.cookie('featuredout');
if (featuredoutC == null) {$.cookie('featuredout', 'expanded');};
else if (featuredoutC == 'expanded') {$.cookie('featuredout', 'collapsed');};
});
});
// COOKIES
// state
var featuredout = $.cookie('featuredout');
// Set the user's selection for the left column
if (featuredout == 'collapsed') {
$('#featuredout').css("display","none");
$.cookie('featuredout', 'collapsed');
};
});
Something along the lines of this should work
$(function() {
$('.featToggle').click( function() {
$('#featuredout').slideToggle(550);
$.cookie('featuredout',$('#featuredout').is(':visible'););
});
var vis = $.cookie('featuredout');
if(vis) {
$('.featToggle').removeClass('hidden').addClass('shown');
} else {
$('#featuredout').hide();
$('.featToggle').removeClass('shown').addClass('hidden');
}
});