Remove a:hover in javascript - javascript

I have the following javascript code:
$('#s2 a').click(function(){
var cB = $(this);
var f = parseInt(cB.attr('data-f'));
var r = parseInt(cB.attr('data-r'));
var c = parseInt(cB.attr('data-c'));
if (pA == false && !isClickAllowed(f,r,c)) {
return false;
}
// more stuff comes here
}
This makes a link not clickable. This all works. I also want to remove the hover effect. The CSS code for this is:
.pc a:hover {
background-color: #FFF;
I thought removing the class would do it like: cB.removeClass('pc'); but this doesn't work.
Any suggestions on how to do this?
Thank you for your time
--EDIT--
Hmm I think I see why it aint working. At the top of the document I have this:
$(document).ready(function() {
setScale();
$(window).resize(setScale);
if (!('ontouchstart' in document)) {
$('body').addClass('pc');
}
more code here
This sets the .pc a:hover for all links when opened the page on a pc rather then a touch device (e.g. iPad). I need to disable this pc hover ONLY on the links are not clickable like in:
if (pA == false && !isClickAllowed(f,r,c)) {
return false;
}
Hope this helps!

cB is the anchor which isn't being references by the CSS class you indicate, the parent would have the class pc for this to work. cB.parent().removeClass('pc'); would do it.
-- EDIT --
Following the erudite comments below it would seem that cb.parents('.pc').removeClass('pc') or cb.parents().removeClass('pc') (I've not benchmarked to see which is quicker) would be the comprehensive solution.
Good catch to James, Anthony, and Tadeck!
-- EDIT 2 --
Following the question update, I'd suggest adding another class to your links, i.e. clickable, then your CSS becomes:
.pc a.clickable:hover {
background-color: #FFF;
and you can just remove the clickable class on those links that you don't want to show the highlight. The better course of action may be to simply replace the links that are disabled with either raw text or as spans with an identifying class, i.e. disabled_link if you want to have the option to enable them later.

Though there was no HTML provided, based on the code, cB does not appear to be the element which has the class of pc but rather an ancestor of cB. You would need to remove the class from that.
If the direct parent is the only ancestor with the class of pc, you can do the following:
cB.parent().removeClass("pc")
If only one ancestor other than the direct parent has the class of pc and the parent does not, you can do the following:
cB.closest(".pc").removeClass("pc")
If multiple ancestors have the pc class, you can use the following:
cB.parents(".pc").removeClass("pc")
And finally, if multiple a tags exist within .pc then you cannot use the approach of removing the class, as this will affect all a tags within that .pc.

cB.removeClass('pc') should indeed remove aclass. Make sure your css behaves correctly in all scenarios. Also try targeting the parent

I would add a disabled class to the CSS that comes after the :hover rule and overrides it with the disabled styles, which may or may not be the default. Then, you can just do:
cB.addClass('disabled');
The reason your existing solution doesn't work is because you're removing the class from the element when its parent has the class.

Since your CSS issue was already solved, I want to point out another improvement:
I see that you are using cB.attr('data-f') to store some data, but attr should only be used for valid HTML attributes. You should consider using the jQuery data method which was created just for the purpose of storing non-attribute data into an element.
http://api.jquery.com/jQuery.data/

<p id="example">This is an example.</p>
<script>
document.getElementById('example').style.borderWidth = '4px';
</script>
Note that borderWidth is different than border-width. This can be used for the other styles. As a rule of thumb, take away the dash and make the first letter of the second word capital. If it doesn't work, Google it.

Related

Need help to find id of a specific element (external) to override styling by CSS

I'm trying to modify (by CSS) the dark gray "Contact Us" button that's at the bottom right side of the following site: coloraddicted.com.
This is a button created by an external app, so the code is inaccessible. I only have the following (external) page to refer to for the possibility of finding the right id: https://icf.improvely.com/icf-button.js?v=1479350309&shop=coloraddicted-com.myshopify.com
How can I find the "id" of the specific element in order to apply the
"overriding" CSS to it?
BTW, I have already tried several versions of the id's I see on the above mentioned external page but still haven't found the right one.
I can't remember all of them, but some I have already tried are:
#icf_button
#icf.click_button
#icf_contact_form button {
#icf_contact_form add_button {
Style Contact button by css has no effect, because right after user hover, js code excuted & override on.
You can put js code at the end of the body, to re-override on the library code (not the good way, but have to), example
let contactButton = document.querySelector('#shop-colorful-products-printed-on-demand-just-for-you > div:nth-child(38)');
contactButton.style.backgroundColor = 'white';
Demo image https://tinker.press/images/change-style-by-js-to-override-2017-01-17_090946.png
If you can't modify the button.js script you linked to, I don't think you can target this (reliably) in CSS. They style everything with that button using inline styles and just append it to body.
You could potentially use :nth-of-type (like https://icf.improvely.com/icf-button.js?v=1479350309&shop=coloraddicted-com.myshopify.com) but that would be super unreliable as I'm assuming you have a bunch of scripts and stuff on the site that dynamically append to the page, creating a variable number of divs as direct descendants of body. FWIW, nth-of-type(13) worked for me.
The element doesn't have an id, so you can't select it that way. But the site appears to be using jQuery, so you could try using :contains() to target the element based on its contents:
$( "div:contains('Contact Us')" ).css( "font-size", "2em" );
But that would target any div containing the text "Contact Us". You can use :filter to select divs that contain only the text "Contact Us":
$("div").filter(function() {
return $.trim($(this).text()) === "Contact Us";
}).css("font-size", "2em");
You could use jQuery to either apply CSS directly, or to give the element an id. This solution is kind of kludgy, but might work in a pinch.

How do I put specific words into their own div class using jQuery? (making a Chrome extension)

I am making a chrome extension, and I want to find all occurrences of a certain word, and put them inside a new div class so I can change them with CSS.
Right now my content.js file looks like this:
(function() {
function change() {
var words = new Array("color");
var html = document.body.innerHTML;
for(var i = 0; i < words.length; i++) {
var reg = new RegExp(words[i], 'ig');
var html = html.replace(reg, '<div class="colorClass">'+words[i]+'</div>');
}
document.body.innerHTML = html;
}
change();
})();
But when I do that, entire web pages get messed up and become unrecognizable (for example, the "Color" wikipedia page).
When I try something simpler like:
var html = html.replace(reg, '<i>'+words[i]+'</i>');
It works just fine. Why is this whole page getting messed up when I try to add divs?
How can I fix this?
One reason the styles are messed up are because the native web page's CSS is overriding the styles loaded from your content script.
The second reason is that you need to be very careful when modifying HTML. You need be careful only to modify text. The current method you are using - you are possibly modifying html classes, ids, etc.
I've actually built an extension (Source code for reference) that does something very similar. I'll share my learnings:
JS
I had used NodeIterator which is fairly unknown. I discovered this API a year ago from another extension: https://code.google.com/p/chrome-type-ahead/
NodeIterator will help you filter out the true text elements that you want to add styles to. This will help you avoid modifying any valid html(classes, ids, etc.) that matches your regex.
CSS
I would suggest adding a class to the html tag in addition to the html you are inserting. The reason for this is that you'll need to be very specific in your styles.
You want to avoid at all cost any chance of a collision with a selector of an existing page.
In addition you need to make sure to add your own css resets that are not only namespaced but also have !important on each attribute.
You CANNOT assume anything about the html tag that you are inserting. Sites can have very generic selectors that will completely mess up your styles. And also the sites can have very specific selectors (using id) that are more specific than you're styles (hence the need for important)
html.very-specific-class .very-specific-color-class {
/*
padding, margin, border, etc.
difficult to add all properties but add all the common ones at the very least
*/
padding: 0px !important;
margin: 0px !important;
border: 0px !important;
...
}
This is happening because a <div> is a block-level element, and it pushes other elements to a new line.
<i> however, is an inline element, so it will not change the page layout at all.
I would recommend using a <span>,instead of a <div>, as span's have no default styling in browsers.
Because divs are block elements. You can use spans, which are inline elements:
var html = html.replace(reg, '<span class="colorClass">'+words[i]+'</span>');
If you want use div,you can add some css styles,like this:
.colorClass{display:inline-block;}

Access class with specific text content and display:none

I have a large Joomla CMS Website I'm working on.
Problem: I need to hide a menu tab globally across the entire site. The menu item I need to have does not have a unique ID or class; but instead shares the same class as the other tabs I need to keep on the page. 70% of the tab I need to remove shows in 4th order so I started with the below.
.tabs:nth-of-type(4)
{
display:none !important;
}
But! Seeing as how the rest is in different order, this wont work. The tab in question I need to remove looks like the below across the mark-up.
Update: This is what I currently have via the suggestions below but it isn't working:
$(document).ready(function() {
$('.djaccTitle:contains("Location").css( "display: none;" )')
});
<span class="tabs">Location</span>
Is there a way to write an if statement or similar lightweight solution that can sniff out text content within the class, so if it says Location, then hide?
I would like to find a solution like this, as opposed to going through 1000 files of mark-up removing manually. Cheers for any pointers
Update: This is what I have via the current suggestions below but it isn't working!
$(document).ready(function() {
$('.tabs:contains("Location").css( "display: none;" )')
});
I do not believe what you are asking for exists with pure CSS at this time.
What I would do is use jQuery's :contains() selector:
$('span.tabs:contains("Location")')
or even better:
$('#idOfTabsContainer span.tabs:contains("Location")')
And of course, don't forget to put this in a document.ready to ensure that your DOM element has been loaded successfully:
$(document).ready(function() {
$('#idOfTabsContainer span.tabs:contains("Location")')
});
Jquery :contains() Selector should work. I think you have an error in .css() function syntax.
Please try with:
jQuery(document).ready(function(){
$( '.tabs:contains("Location")' ).css( 'display', 'none' );
});
Hope this helps
There used to be a :contains selector that they were going to add to CSS.
But alas, you may have to resort to some JS, as addressed already here
jQuery's got your back though:
$('.tabs:contains("Location")')
Problem: I need to hide a menu tab globally across the entire site.
Solution 1: Disable the menu item. Boom, it is gone from your menus, site wide.
Solution 2: Hide the menu item with css by adding a unique class to the menu item itself and then hiding it with css.
.hide-me-with-css {display: none;}

Updating visited status of a link when changing its href attribute, under Chrome

When I am updating links with JavaScript
$('#link_id').attr('href', some_new_url)
the color theme for visited/non-visited links persists, regardless of the status of the new url address.
Is there a way to change link address forcing browser to re-check its visited status?
Further notes:
I am (on OSX 10.8) experiencing this problem in Chrome (32) and Safari (6.1). In Firefox (26) the links status gets updated automatically, as desired.
The example above is in jQuery, but the problem is the same way with with vanilla JavaScript, i.e. document.getElementById and setAttribute.
(I would prefer to avoid deleting and adding <a></a>, if possible.)
EDIT:
Minimal (non-)working example (by Joeytje50): http://jsfiddle.net/3pdVW/
Definitive answer
What you could do to fix this, is simply forcing the browser to recalculate the styles by completely removing the href attribute, and then re-adding it back again immediately afterwards. That will make the browser first calculate the styles, since the <a> is no longer a link without the href, and then you add the href you want to give it. The code would then be:
$('#link_id').removeAttr('href').prop('href', some_new_url);
Demo
PS: in this case, using .attr('href', some_new_url); would probably work equally fine.
Previous attempts
What I'm thinking is that this is a rendering glitch. It doesn't recalculate the styles when the :visited state changes because of the script. This minimal example of your problem shows this well. What you could try is either of the following:
Using the element's properties
What the problem might be is that you're changing the attribute, which in turn changes the href property. If you directly change the href property it might work. You can do this via jQuery.prop, which would use the following code to change the link:
$('#link_id').prop('href', some_new_url);
Demo. I don't really have very high hopes about this one, but it's worth trying. What I do suspect will work much better is:
Forcing to recalculate the styles
If you want to force a recalculation of the styles, you can simply change a class on the highest element you want updated. Since you're updating the <a> element alone, you'd need something like this:
$('#link_id').prop('href', some_new_url).toggleClass('webkit-force-recalculate');
Demo
I think that is quite likely to do the trick.
If neither of these approaches work for you, you could of course use maximgladkov's solution.
You can change it like this:
$('#link_id').replaceWith($('' + $('#link_id').text() + ''));
It should do the trick. Tested: http://jsfiddle.net/maximgladkov/L3LMd/
Frequently experience similar issues, e.g. when setting size of elements with border, there are stray borders left etc.
Though this is not directly the same, I have found that hiding the element does the trick. Have not had any trouble with it.
Simple fiddle
$("#change_link").on("click", function(e) {
$("#anchor1").hide();
$("#anchor1").attr('href', $("#url").val());
$("#anchor1").show();
});
This should force a redraw of the element.
I think what you might be looking for is the following CSS code:
a:link {
text-decoration: none;
color: #00F;
}
a:visited {
color: #00F;
}

create css class on the fly in codebehind

I have a search page that is used in multiple places with multiple 'themes' throughout my site. I have a few divs that can have their background color changed based on a radio button selection (whether they are enabled or not). I can do this just fine by changing the css class of the div on the fly with javascript.
However, these themes could potentially change, and the background color is grabbed from a database when the page is created. Right now I do this in the C# codebehind:
string bgStyle = "background-color:" +theme.searchTextHeaderColor +";";
OwnerSearchHeader.Attributes.Add("style", bgStyle);
In the Javascript I need to change this color to make it look disabled, and when the user clicks back to this div I need to re-enable it by changing it back to its original color. But since I only knew this color in the code-behind, I don't know what it was in the Javascript.
So my thought was to create a css class in the resulting HTML page when the page is loaded with the background color I need. Then I could simply switch from the divEnabled and divDisabled class in the javascript. But I'm not exactly sure how to do that.
Alternatively I could create a hidden element, assign it the 'enabled' style, and use that as a reference in the JavaScript when enabling my div. This seems like a hack but maybe its the easiest way. I'm still new to a lot of this, so I'd appreciate any suggestions. Thanks for the input!
So my thought was to create a css class in the resulting HTML page when the page is loaded with the background color I need. Then I could simply switch from the divEnabled and divDisabled class in the javascript. But I'm not exactly sure how to do that.
Yes, this is the anser; do this. In the <head> of your document add a <style> and put your CSS in there like so: (my Asp.NET is a little rusty so forgive me if it has some hicups ;) )
<style>
<!--
.divEnabled {
background-color:<%=theme.searchTextHeaderColor%>;
}
.divDisabled {
background-color:gray; /* or wtv */
}
-->
</style>
You could also put it in an external CSS file, which may be a good idea.
Then write some JavaScript to add/remove the class attribute (I'm going to ask that you don't call is the "CSS Class" ;) )
var ownersearchheader = document.getElementById("<%=OwnerSearchHeader.ClientId%>");
// changing the class attribute to `divDisabled`
var newClassAttribute = ownersearchheader.getAttribute("class").replace(/\bdivEnabled\b/, "divDisabled")
ownersearchheader.setAttribute("class", newClassAttribute);
// ... or,
// changing the class attribute to `divEnabled`
var newClassAttribute = ownersearchheader.getAttribute("class").replace(/\bdivDisabled\b/, "divEnabled")
ownersearchheader.setAttribute("class", newClassAttribute);
This is indeed a mouthfull, so, like #Haydar says, you might want to use jQuery, which offers easy-as-pie addClass(), removeClass() and toggleClass() methods.
You can use the jquery .toggleClass method.
Description: Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the switch argument.
Here is the link to the api doc.
Jquery API

Categories