I have a button that toggles active class on a div.
When the div has active class it is displayed and when active class is removed the div is hidden.
I want active class removed from the div when the page is loaded, but later when I click the button active class should be applied. The div should be hidden when the page loads.
I don't have access to HTML so it has to be done using jquery.
here is my code:
<button class="btn addclass">Toggle class</button>
<div class="block active">
</div>
my js:
$(document).ready(function(){
$(window).on('load', function(){
if($(".addclass .block").hasClass("active")){
$(this).removeClass("active");
}
});
});
$(document).ready(function(){
$(".addclass").click(function(){
$(".block").toggleClass("active");
});
});
CSS
.block{
display: none;
padding: 50px;
background-color: red;
}
.block.active{
display: block;
}
In this block of code:
$(document).ready(function(){
$(window).on('load', function(){
if ($(".addclass .block").hasClass("active")) {
$(this).removeClass("active");
}
});
this refers to the window so you can't use window here.
You also don't shouldn't nest window.load inside doc.ready (use one or the other). While doc.ready will fire even if the document is already ready, window load will only fire at the one time that it loads and that will be before doc.ready runs, so your code (probably) never runs.
Your code can be shortened to:
$(function() {
$(".addclass .block.active").removeClass("active");
});
Since jQuery specializes in controlling all things DOM it's a shade faster and less flashing if you listen for the "DOMContentLoaded" event on the document object. By that time all of the DOM is loaded and the scripts have been parsed. If you listen to the "load" event on the window object, then everything has been loaded, that includes all the stuff you didn't need to run jQuery.
BTW if you don't already know, it's important that all <script> elements be placed right before the closing </body> tag. Of course this may not be possible for you since you have to deal with 3rd party code at page load. See this article about what was just discussed.
/*
Once document is loaded
Remove .active from .block
*/
$(document).on('DOMContentLoaded', e => $('.block').removeClass('active'));
/* ALTERNATIVE
Once document is loaded
Hide .block
/
$(document).on('DOMContentLoaded', e => $('.block').hide());
*/
/*
When .toggle is clicked...
Toggle .block to hide/show
Toggle the text of .toggle to "SHOW/HIDE"
*/
$('.toggle').on('click', function(e) {
$(this).text($(this).text() === 'SHOW' ? 'HIDE' : 'SHOW');
/*
Toggle .active class on/off on .block
*/
$('.block').toggleClass('active');
/* ALTERNATIVE
Toggle .block show/hide slowly
/
$('.block').toggle('slow');
*/
});
body {
font: 5ch/1 Consolas;
text-align: center;
}
button {
font: inherit;
cursor: pointer;
}
.block {
display: none;
}
.active {
display: block;
}
<button class="btn toggle">SHOW</button>
<div class="block active">ACTIVE</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Related
I'm new to jquery and javascript. I have a website with multiple unique modal/popups that are triggered via a CSS :target selector, which sets them to display: block. I'm trying to use jquery to hide a separate element among other things.
The logic is:
If a modal is visible, then hide element. Else show element. I'm currently using popstate in my jquery. This is because the modals can close if the user presses their browser back button. So I don't want to use any click functions. Everything seems to be working fine, except the if/else statements that detect the visibility of the modals seem to behave differently between Firefox and Chrome? When it hides the element in Firefox, it shows it Chrome. When it hides it in Chrome, it shows it in Firefox. Why the opposite behavior? What am I doing wrong?
$(window).on('popstate', function(event) {
if ($('.modal').is(':visible')) {
console.log("Modal ON");
$('#wrapper').css('overflow-y', 'hidden');
$('#extra_element').css('display', 'none');
} else {
console.log("Modal OFF");
$('#wrapper').css('overflow-y', 'scroll');
$('#extra_element').css('display', 'block');
}
});
.modal {
display: none;
width: 100px;
height: 100px;
background-color: red;
margin: 0 auto;
}
.modal:target {
display: block;
}
#extra_element {
width: 100vw;
height: 20vh;
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="extra_element">This element should hide when modal is open</div>
<div>
Click Me To Open Modal
<div id="content" class="modal">I'm a Modal. Press browser back button to close
</div>
</div>
Alternate jQuery:
Setting the length to 1 works in Firefox and works oppositely in Chrome.
Setting the length to 0 works in Chrome and works oppositely in Firefox.
$(window).on('popstate', function(event) {
if ( $('.modal-overlay:visible').length === 1 ) {
console.log("Modal ON");
$('#wrapper').css('overflow-y', 'hidden');
$('#extra_element').css('display', 'none');
}
else {
console.log("Modal OFF");
$('#wrapper').css('overflow-y', 'scroll');
$('#extra_element').css('display', 'block');
}
});
Is there another way to do this correctly?
This would be a Chrome bug, according to the specs, at the step 10 of the History traversal algorithm the UA should call the "scroll to fragment" algorithm which is responsible for updating the document's target element (:target) and only at the step 18.1 it should fire the popstate event.
Chrome does fire the event before it updates the document's target element, and thus your CSS :target selector doesn't match yet.
I did open an issue so they get this in-line with the standards, but for the time being you can workaround that by waiting just a task after the event fired:
$(window).on('popstate', async function(event) {
await new Promise(res => setTimeout(() => res()));
if ($('.modal').is(':visible')) {
console.log("Modal ON");
$('#wrapper').css('overflow-y', 'hidden');
$('#extra_element').css('display', 'none');
} else {
console.log("Modal OFF");
$('#wrapper').css('overflow-y', 'scroll');
$('#extra_element').css('display', 'block');
}
});
.modal {
display: none;
width: 100px;
height: 100px;
background-color: red;
margin: 0 auto;
}
.modal:target {
display: block;
}
#extra_element {
width: 100vw;
height: 20vh;
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div id="extra_element">This element should hide when modal is open</div>
<div>
Click Me To Open Modal
<div id="content" class="modal">Press browser back button to close
</div>
</div>
I am having trouble making elements hover on a mobile device.
In my CSS, I type something like:
.button:hover {
background-color: #fff;
}
This seems to hover fine on my desktop, however on my iPhone and other touch devices, I can't seem to make the button hover.
There is no hover event on mobile, you can define hover behavior and it will work on desktop. But on mobile, you will see this hover only by click/touch.
Hovers mean one thing on the other. in this case its the mouse cursor over the HTML button or whatever element you use.
In the case of a phone, there is no mouse cursor. its always a click. Hovers in most cases would show only on click or touch. If you really need this you can try the Javascrit onclick() or other functions, so when they click or touch, you can add a bit of something.
For a very quick solution of this problem with jQuery/CSS, I did the following.
wrote styles for my element like this:
.one-block:hover, .one-block.hover { ... }
positioned it:
.one-block { position: relative; }
added the last element in this block -> .mobile-mask:
<div class="one-block">
....
<div class="mobile-mask"></div>
</div>
positioned .mobile-mask:
.mobile-mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
hide it for non-mobile (this part is not precise at all: just with css. if you detect mobile devices by some other means and, for example, give a class to body, than it will be more precise. in this case I just need a quick solution):
#media (min-width: 681px) {
.mobile-mask {
display: none;
}
}
create javascript that will add/remove .hover class:
$('.mobile-mask').on('click', function(){
$('.list .mobile-mask').show();
$('.list .one-block').removeClass('hover');
$(this).hide();
$(this).parent().addClass('hover');
});
$(window).on('resize', function(event){
var windowWidth = $(this).width();
if(windowWidth > 680){
$('.list .one-block').removeClass('hover');
}
});
As the title says I want to show a hidden span "box" when hovering an image, but I can't get it to work, so I was hoping you guys could figure out my mistake.
HTML
<span class="DDAA__bg">
<h1 class="DDAA__headline">DANSK DYREVÆRN ÅRHUS</h1>
</span>
<span class="DDAA__pic">
<img src="img/DDAA-Logo.png" width="980" height="200" alt="Dansk Dyreværn Århus"/>
</span>
CSS
span.DDAA__bg{
height: 200px;
width: 980px;
background-color: #666;
position: absolute;
display: none;
}
span.DDAA__pic{
display:block;
visibility: visible;
}
span.DDAA__pic:hover{
visibility: hidden;
transition-delay: 2s;
}
span.DDAA__pic:hover + span.DDAA__bg{
display:block;
}
You can see here how it works now, not as good :/
http://jsfiddle.net/ary3bt83/3/
element:hover > other_element {
display: block;
}
this is equal to the jQuery code
$(element).on('hover', function() { $(this).css("display", "block"); });
But doing hover on css sometimes is really buggy...
First you need to have jQuery installed ( look for jquery.js / jquery.min.js in source code or google for w3c jquery install )
After this you write following :
<script>
$(document).ready(function() {
// everything here is done once the page is loaded
// define hover event handler for a specific element
$(".the_hovered_element").on('hover', function() {
// show the element
$(".the_element_to_be_shown").css("display","block");
});
});
</script>
Don't forget that you must initially set display: none to the div that is first hidden and then shown. Also instead of .css("display","block") you can have simple animation like .fadeIn("slow");
Is there a method in html which makes the webpage scroll to a specific Element using HTML !?
Yes you use this
<div id="google"></div>
But this does not create a smooth scroll just so you know.
You can also add in your CSS
html {
scroll-behavior: smooth;
}
You should mention whether you want it to smoothly scroll or simply jump to an element.
Jumping is easy & can be done just with HTML or Javascript. The simplest is to use anchor's. The limitation is that every element you want to scroll to has to have an id. A side effect is that #theID will be appended to the URL
Go to Title
<div>
<h1 id="scroll">Title</h1>
</div>
You can add CSS effects to the target when the link is clicked with the CSS :target selector.
With some basic JS you can do more, namely the method scrollIntoView(). Your elements don't need an id, though it is still easier, e.g.
function onLinkClick() {
document.getElementsByTagName('h2')[3].scrollIntoView();
// will scroll to 4th h3 element
}
Finally, if you need smooth scrolling, you should have a look at JS Smooth Scroll or this snippet for jQuery. (NB: there are probably many more).
<!-- HTML -->
<div id="google"></div>
/*CSS*/
html { scroll-behavior: smooth; }
Additionally, you can add html { scroll-behavior: smooth; } to your CSS to create a smooth scroll.
Year 2020. Now we have element.scrollIntoView() method to scroll to specific element.
HTML
<div id="my_element">
</div>
JS
var my_element = document.getElementById("my_element");
my_element.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "nearest"
});
Good thing is we can initiate this from any onclick/event and need not be limited to tag.
If you use Jquery you can add this to your javascript:
$('.smooth-goto').on('click', function() {
$('html, body').animate({scrollTop: $(this.hash).offset().top - 50}, 1000);
return false;
});
Also, don't forget to add this class to your a tag too like this:
Text
Here is a pure HTML and CSS method :)
html {
scroll-behavior: smooth;
/*Adds smooth scrolling instead of snapping to element*/
}
#element {
height: 100px;
width: 100%;
background-color: red;
scroll-margin-block-start: 110px;
/*Adds margin to the top of the viewport*/
scroll-margin-block-end: 110pxx;
/*Adds margin to the bottom of the viewport*/
}
#otherElement {
padding-top: 500px;
width: 100%;
}
Link
<div id="otherElement">Content</a>
<div id="element">
Where you want to scroll
</div>
<div id="otherElement">Content</a>
<nav>
1
2
3
</nav>
<section id="section1">1</section>
<section id="section2" class="fifty">2</section>
<section id="section3">3</section>
<style>
* {padding: 0; margin: 0;}
nav {
background: black;
position: fixed;
}
a {
color: #fff;
display: inline-block;
padding: 0 1em;
height: 50px;
}
section {
background: red;
height: 100vh;
text-align: center;
font-size: 5em;
}
html {
scroll-behavior: smooth;
}
#section1{
background-color:green;
}
#section3{
background-color:yellow;
}
</style>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" >
$(document).on('click', 'a[href^="#"]', function (event) {
event.preventDefault();
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top
}, 500);
});
</script>
I got it working by doing this, consider that top-page is the element that you want to scroll to:
document.getElementById("top-page").scrollTo({ behavior: "smooth", top: 0 });
Yes, you may use an anchor by specifying the id attribute of an element and then linking to it with a hash.
For example (taken from the W3 specification):
You may read more about this in Section Two.
...later in the document
<H2 id="section2">Section Two</H2>
...later in the document
<P>Please refer to Section Two above
for more details.
By using an href attribute inside an anchor tag you can scroll the page to a specific element using a # in front of the elements id name.
Also, here is some jQuery/JS that will accomplish putting variables into a div.
<html>
<body>
Click here to scroll to the myContent section.
<div id="myContent">
...
</div>
<script>
var myClassName = "foo";
$(function() {
$("#myContent").addClass(myClassName);
});
</script>
</body>
Should you want to resort to using a plug-in, malihu-custom-scrollbar-plugin, could do the job. It performs an actual scroll, not just a jump. You can even specify the speed/momentum of scroll. It also lets you set up a menu (list of links to scroll to), which have their CSS changed based on whether the anchors-to-scroll-to are in viewport, and other useful features.
There are demo on the author's site and let our company site serve as a real-world example too.
The above answers are good and correct. However, the code may not give the expected results. Allow me to add something to explain why this is very important.
It is true that adding the scroll-behavior: smooth to the html element allows smooth scrolling for the whole page. However not all web browsers support smooth scrolling using HTML.
So if you want to create a website accessible to all user, regardless of their web browsers, it is highly recommended to use JavaScript or a JavaScript library such as jQuery, to create a solution that will work for all browsers.
Otherwise, some users may not enjoy the smooth scrolling of your website / platform.
I can give a simpler example on how it can be applicable.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
// Add smooth scrolling to all links
$("a").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 800, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
} // End if
});
});
</script>
<style>
#section1 {
height: 600px;
background-color: pink;
}
#section2 {
height: 600px;
background-color: yellow;
}
</style>
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1>Smooth Scroll</h1>
<div class="main" id="section1">
<h2>Section 1</h2>
<p>Click on the link to see the "smooth" scrolling effect.</p>
Click Me to Smooth Scroll to Section 2 Below
<p>Note: Remove the scroll-behavior property to remove smooth scrolling.</p>
</div>
<div class="main" id="section2">
<h2>Section 2</h2>
Click Me to Smooth Scroll to Section 1 Above
</div>
</body>
</html>
Is there a freely available jQuery plugin that changes placeholder behavior to match HTML5 spec?
Before Focus
On Focus Good (Safari)
On Focus Bad (Chrome, Firefox)
You can what your browser does with this simple fiddle.
HTML5 draft spec says:
User agents should present this hint to the user, after having stripped line breaks from it, when the element's value is the empty string and/or the control is not focused (e.g. by displaying it inside a blank unfocused control and hiding it otherwise).
The "/or" is new in current draft so I suppose that's why Chrome and Firefox don't support it yet. See WebKit bug #73629, Chromium bug #103025.
Stefano J. Attardi wrote a nice jQuery plugin that just does that.
It is more stable than Robert's and also fades to a lighter grey when the field gets focused.
See the demo page
Grab it on GitHub
Play with the fiddle
I modified his plugin to read placeholder attribute as opposed to manually creating a span.
This fiddle has complete code:
HTML
<input type="text" placeholder="Hello, world!">
JS
// Original code by Stefano J. Attardi, MIT license
(function($) {
function toggleLabel() {
var input = $(this);
if (!input.parent().hasClass('placeholder')) {
var label = $('<label>').addClass('placeholder');
input.wrap(label);
var span = $('<span>');
span.text(input.attr('placeholder'))
input.removeAttr('placeholder');
span.insertBefore(input);
}
setTimeout(function() {
var def = input.attr('title');
if (!input.val() || (input.val() == def)) {
input.prev('span').css('visibility', '');
if (def) {
var dummy = $('<label></label>').text(def).css('visibility','hidden').appendTo('body');
input.prev('span').css('margin-left', dummy.width() + 3 + 'px');
dummy.remove();
}
} else {
input.prev('span').css('visibility', 'hidden');
}
}, 0);
};
function resetField() {
var def = $(this).attr('title');
if (!$(this).val() || ($(this).val() == def)) {
$(this).val(def);
$(this).prev('span').css('visibility', '');
}
};
var fields = $('input, textarea');
fields.live('mouseup', toggleLabel); // needed for IE reset icon [X]
fields.live('keydown', toggleLabel);
fields.live('paste', toggleLabel);
fields.live('focusin', function() {
$(this).prev('span').css('color', '#ccc');
});
fields.live('focusout', function() {
$(this).prev('span').css('color', '#999');
});
$(function() {
$('input[placeholder], textarea[placeholder]').each(
function() { toggleLabel.call(this); }
);
});
})(jQuery);
CSS
.placeholder {
background: white;
float: left;
clear: both;
}
.placeholder span {
position: absolute;
padding: 5px;
margin-left: 3px;
color: #999;
}
.placeholder input, .placeholder textarea {
position: relative;
margin: 0;
border-width: 1px;
padding: 6px;
background: transparent;
font: inherit;
}
/* Hack to remove Safari's extra padding. Remove if you don't care about pixel-perfection. */
#media screen and (-webkit-min-device-pixel-ratio:0) {
.placeholder input, .placeholder textarea { padding: 4px; }
}
Robert Nyman discusses the problem and documents his approach in his blog.
This fiddle that has all the neccessary HTML, CSS and JS.
Unfortunately, he solves the problem by changing value.
This will not work by definition if placeholder text is itself a valid input.
I found this question by googling out the solution to the same problem. It seems that existing plugins either don't work in elder browsers or hide placeholder on focus.
So I decided to roll on my own solution while trying to combine best parts from existing plugins.
You may check it out here and open an issue if you face any problems.
How about something simple like this? On focus save out the placeholder attribute value and remove the attribute entirely; on blur, put the attribute back:
$('input[type="text"]').focus( function(){
$(this).attr("data-placeholder",$(this).attr('placeholder')).removeAttr("placeholder");
});
$('input[type="text"]').blur( function(){
$(this).attr("placeholder",$(this).attr('data-placeholder'));
});
I wrote my own css3 only solution. See if that fullfills all your needs.
http://codepen.io/fabiandarga/pen/MayNWm
This is my solution:
the input element is set to "required"
an aditional span element for the placeholder is needed. This element is moved on top of the input element (position: absolute;)
with css selectors the input element is tested for validity (required fields are invalid as long as there is no input) and the placeholder is then hidden.
Pitfall: The placeholder is blocking mouseevents to the input! This problem is circumvented by hiding the placeholder element when the mouse is inside the parent (wrapper).
<div class="wrapper">
<input txpe="text" autofocus="autofocus" required/>
<span class="placeholder">Hier text</span>
</div>
.placeholder {
display: none;
position: absolute;
left: 0px;
right: 0;
top: 0px;
color: #A1A1A1;
}
input:invalid + .placeholder {
display: block; /* show the placeholder as long as the "required" field is empty */
}
.wrapper:hover .placeholder {
display: none; /* required to guarantee the input is clickable */
}
.wrapper{
position: relative;
display: inline-block;
}
Maybe you can try with Float Label Pattern :)
See Float labels in CSS