Optimizing jQuery Spoiler Button - javascript

HTML
<!doctype html>
<html>
<head>
</head>
<body>
<button id="b1" type="button">Show Spoiler</button>
<p id="p1" style="display:none"> This is a damn paragraph.</p>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="js/script.js"></script>
</body>
</html>
JS
function bindEvent(element, eventName, eventHandler) {
var el = $(element)[0];
if (el.addEventListener) {
el.addEventListener(eventName, eventHandler, false)
} else if (el.attachEvent) {
el.attachEvent('on'+eventName, eventHandler);
}
}
bindEvent('#b1', 'click', function() {
$('#p1').toggle('blind');
if ($('#b1').text() == 'Show Spoiler') {
$('#b1').text('Hide Spoiler');
} else if ($('#b1').text() == 'Hide Spoiler') {
$('#b1').text('Show Spoiler');
}
});
I'm new to jQuery and Javascript so I made this simple script to show and hide a paragraph and to change the button texts whenever clicked. My problem is that this seems a bit clunky. Is there a better, shorter, and simpler way to achieve the same result?

First of all, jQuery already normalizes DOM event listeners for you across browsers, so your bindEvent function isn't necessary anymore. Here's the short way, using some stuff you can look up yourself in the jQuery API, to do what you're doing.
var $b1 = $('#b1')
, $p1 = $('#p1')
, hideText = 'Hide Spoiler'
, showText = 'Show Spoiler'
$b1.on('click',function() {
var text = $b1.text()
, newText = text === showText ? hideText : showText
$p1.toggle('blind')
$b1.text(newText)
})
Here are a few things to notice:
Your example function assumes a single spoiler #p1 and a single reveal button #b1. In production, this will probably be based on classes, like .spoiler and .spoiler-trigger, and there will be multiple spoilers on a page. In that case, you'll need to get the value of this. In this example let's assume that the reveal button is always a sibling of the spoiler itself.
$('.spoiler-trigger').on('click',function() {
var $this = $(this)
, $thisSpoiler = $this.siblings('.spoiler').eq(0)
, text = $this.text()
, newText = text === showText ? hideText : showText
$thisSpoiler.toggle('blind')
$this.text(newText)
})
The jQuery .on method is the cross-browser event listener function that you'll want to start using.
jQuery selectors we use repeatedly, like $(this) or $('#b1'), should be cached in local variables for performance.
I'm using a ternary conditional instead of an if statement to determine what the show/hide text should be, because in this very simple case I consider it more readable.

You can make this work with simple 3 lines of code using awesome jquery. trigger the button click event, and on click -> toggle the element 'P'. This should help : working demo
$("#b1").click(function () {
$("#p1").toggle('slow');
});​

Related

why is button toggle not working with class?

When I change my button toggle from ID-Name to Class-Name, the function is not working anymore. Does anyone know why?
I need a class since this button is multiple times on the page and loads in separately via css and sliders. The function and content is still the same.
$(document).ready(function(){
$('.infoBtn').on('click', function () {
var text=$('.infoBtn').text();
if(text === "info"){
$(this).html('close');
} else{
$(this).text('info');
}
});
});
The issue is your use of selector inside the click event:
$('.infoBtn').text();
Pointy:
Your code should use $(this), not $('.infoBtn') inside the handler.
What you have now will get the text only from the first one on the
page.
If you change that to $(this), it should work as required:
$(this).text();
$(document).ready(function(){
$('.infoBtn').on('click', function(){
//REM: Use $(this) and not $('.infoBtn')!
let text = $(this).text();
$(this).text((text === 'info') ? 'close' : 'info')
})
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class = 'infoBtn'>initial</button>
<button class = 'infoBtn'>initial</button>

Replace button text onclick JS

I'm trying to change button text on button click so that the text changes from 'Copy' to 'Copied!' as part of a custom clipboard setup. Here is the code I'm using:
HTML:
<button id="copyButton2">Copy</button>
JS:
<script>
jQuery(".copyButton2").click(function () {
jQuery(this).text(function(i, v){
return v === 'Copy' ? 'Copied!' : 'Copy'
})
});
</script>
which doesn't appear to be working correctly.
I have also tried modifying this solution to no avail. Is there an obvious reason why this isn't working?
You've set copyButton2 as the id of the element, yet you're using a class selector. You need to prefix the selector with #, not .
Also note that, depending on where you're running the jQuery code, you may also need to include a document.ready handler. Try this:
jQuery(function($) {
$("#copyButton2").click(function() {
$(this).text(function(i, v) {
return v === 'Copy' ? 'Copied!' : 'Copy'
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="copyButton2">Copy</button>
Please use id selector ("#copyButton2") instead of class selector as you have used id for the close button.
Here's a javascript solution while we're at it.
<script>
var testDiv = document.getElementById('test');
testDiv.onclick = function(){
testDiv.innerHTML = "Copied!"
};
</script>

get the href value by clicking on anchor in multiple anchors using jquery

i'm trying to get the href value in multiple links or tag a.and i tried with this code
var val;
$(document).ready(function() {
$("a").click(function() {
window.val = $(this).attr("href");
alert(window.val);
});
it is working fine for the multiple links and which is inside the file that is local, here few demo links
a
b.....
but problem is i want that href value globally available because i'm using that in other file . My problem is how to make it global, or is there any other way to do it.
and how to write our own function to work the same thing without using $(document).ready function.
this whole thing in one html page but i want only href value in other html page , so if we write our own js function we can use this in both html pages . And that function should return href. but here i dono how to return to $(document).ready function.
You can create an object-based variable:
var screen = {
link:''
};
And then assign / access on click:
$('a').on('click',function(){
screen.link = this.href;
alert(screen.link);
});
I advocate this over assigning variables to the window ... a little more control this way.
Notice I used this.href instead of $(this).attr('href'). As the most interesting man in the world says, I don't always use vanilla JS, but when I do it's about 600,000 times faster.
EDIT So you want to get rid of $(document).ready() huh? Now you're venturing into the shark-infested waters of pure vanilla JS.
var screen = {
link:'',
assignLink:function(href){
screen.link = href;
alert(href);
}
},
links = document.getElementsByTagName('a');
if(window.addEventListener){
for(i = links.length; i--;){
links[i].addEventListener('click',function(){
screen.assignLink(this.href);
});
}
} else {
for(i - links.length; i--;){
links[i].attachEvent('onclick',function(){
screen.assignLink(this.href);
});
}
}
This is just winging it, so don't scathe me if it isn't flawless, its more to make a point. See why jQuery is so handy? All that extra crap is done in the background for you, so that you just need to deal with the burden of $(document).ready() and not have to deal with the rest of this kind of stuff.
EDIT AGAIN So ... you want to access this value across pages?
var screen = {
link:((localStorage['link'] !== null) ? localSorage['link'] : ''),
setLink:function(href){
screen.link = href;
localStorage['link'] = href;
alert(href);
},
getLink:function(){
return screen.link;
}
};
$('a').on('click',function(){
screen.setLink(this.href);
});
This use of localStorage is just an example ... you can get more elaborate or use cookies if you want IE7- to work, but this just providing ideas. You can set the value whenever you want using the screen.setLink function passing the href, or you can get the value whenever you want using the screen.getLink function.
Take a look at this example:
<!DOCTYPE html>
<html>
<head>
<title>Try jQuery 1.9.1 Online</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script>
var val;
$(document).ready(function() {
$("a").on('click', function() {
window.val = $(this).attr("href");
alert(window.val);
return false;
});
$("div").on('click', function() {
alert (val);
});
});
</script>
</head>
<body>
a
b
<div>click here</div>
</body>
</html>
Once you click either the link a or b val will be set. Clicking the div tag will alert you the current reference of val.
Declare val outside to make it global and you can use the val inside the function to set the href globally
var val;
$(document).ready(function() {
$("a").click(function(e) {
e.preventDefault();
val = $(this).attr("href");
alert(val);
});
});
jsfiddle

How to hide a div on document ready, and then call it dynamically from Javascript?

I'm using this code to hide a div container where I'm placing text dynamically.
$(document).ready(function(){
$(".slidingDiv").hide();
$(".show_hide").show();
$('.show_hide').click(function(){
$(".slidingDiv").slideToggle();
});
});
The problem I have is that I want to trigger the show div from a javascript function instead of a predefined click event. I've found this example which mateches the function I want, but I'm not sure how to trigger it from javascript instead of a click function.
JSFiddle Here
just hide the div using css
display:none;
.slidingDiv{
display:none;
}
and show it when ever you want using
.show()
$(".slidingDiv").show();
edit:
after you question edit, you can always trigger the click event programatically like
function yourFunction(){
$(".show_hide").click();
}
At any point in your script you can call the jQuery object with your div's id/class and run the show() function. i.e.
var javascript = "cool";
var foo = "I'm doing stuff";
var bar = "And some more stuff";
if (javascript === "cool")
jQuery(".slidingDiv").show();
else
$(".slidingDiv").show();
<script>
$(document).ready(function(){
$("input[type='file']").on("change", function () {
if(this.files[0].size > 1000000) //file size less than 1MB {
{
$("#fileAlert").show(); //calling a bootstrap 4 alert
}
$(this).val('');
}
});
});
</script>

iOS automatic hover fix?

Is there a jQuery plugin or JavaScript script that automagically loops through each CSS hover (found in an external stylesheet) and binds it with a double touchdown event?
Touchdown 1 - CSS :hover is triggered
Touchdown 2 - Click (link following or form action)
If there isn't something like this yet, can it be made and how (guidelines)?
EDIT:
To be clear, I am not in search of a double tap. Touchdown 1 is a single tab just like Touchdown 2 is. There can be as less as 0 seconds between both or as much as 3 minutes, that's the user's choice.
No touch:
:hover -> element becomes visible
click -> following link or other action
Touch (iOS):
touchdown 1 -> element becomes visible
touchdown 2 -> following link or other action
Try this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>iPad Experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
if(navigator.platform == "iPad") {
$("a").each(function() { // have to use an `each` here - either a jQuery `each` or a `for(...)` loop
var onClick; // this will be a function
var firstClick = function() {
onClick = secondClick;
return false;
};
var secondClick = function() {
onClick = firstClick;
return true;
};
onClick = firstClick;
$(this).click(function() {
return onClick();
});
});
}
});
</script>
<style type="text/css">
a:hover {
color:white;
background:#FF00FF;
}
</style>
<body>
Google
stackoverflow.com
</body>
</html>
... or check out the demo on my web site. Note that it's set up to only work its magic on the iPad - detecting all versions of the iOS is another question in my books ;)
It works on the basis of the fact that...
After you click a link on the iphone or ipad, it leaves a simulated mouse hover that triggers the a:hover css styling on that link. If the link has a javascript handler that keeps you on same page, the hover state will not change until you click on another link.
Citation: Safari iphone/ipad “mouse hover” on new link after prior one is replaced with javascript
I've used this:
$(document).ready(function() {
$('.hover').bind('touchstart touchend', function(e) {
e.preventDefault();
$(this).toggleClass('hover_effect');
});
});
Before, to allow hover on certain elements. Obviously you'll need to tweak it for your own use, but it's a nice way to allow a touch and hold hover effect.
Here is a further optimized version that also handles closing the :hover
You'll have to encapsulate your site with a
<div id="container"></div>
for it to work. Just putting the closing event on the body did nothing
var bodyBound = false;
var container;
if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i) || navigator.userAgent.match(/iPad/i))
{
container = $("#container");
// Provoke iOS :hover event
$("a.someLink").on("mouseover", handleHoverClick);
}
function handleClose(event)
{
container.off("click", handleClose);
bodyBound = false;
}
function handleHoverClick(event)
{
if (!bodyBound)
{
bodyBound = true;
// Somehow, just calling this function—even if empty—closes the :hover
container.on("click", handleClose);
}
}
I created this update apon Richard JP Le Guens solution. It works GREAT, but my version fixes the issue recognized by DADU.
Also I fixed his workaround to detect iPads. My solution detects any other touch devices too (except IE10 on MS surface, I didn't remember the MS special treatment).
My fix is not a 100% perfect solution, but it resets the hover fix at least when hovering another link.
<!DOCTYPE html>
<html>
<head>
<title>TouchDevice Experiment</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
if(document.createEvent("TouchEvent")) { // using document.createEvent is more reliable than navigator (Modernizr uses this practice)
$("a").each(function() { // have to use an `each` here - either a jQuery `each` or a `for(...)` loop
var onClick; // this will be a function
var firstClick = function() {
$("a").trigger("JWUnhover"); // triggering hoverfix reset if any link gets touched
onClick = secondClick;
return false;
};
secondClick = function() {
onClick = firstClick;
return true;
};
onClick = firstClick;
$(this).click(function() {
return onClick();
});
$(this).bind('JWUnhover', function(){ onClick = firstClick; });
});
}
});
</script>
<style type="text/css">
a:hover {
color:white;
background:#FF00FF;
}
</style>
</head>
<body>
Google
stackoverflow.com
</body>
</html>
There is no jQuery plugin that I know of to do such a thing.
You cannot trigger a css psuedo class such as ":hover". You can however loop through the anchor elements and add a css class ".hover" on touchstart and touchend events as follows:
var pageLinks = document.getElementsByTagName('a');
for(var i = 0; i < pageLinks.length; i++){
pageLinks[i].addEventListener('touchstart', function(){this.className = "hover";}, false);
pageLinks[i].addEventListener('touchend', function(){this.className = "";}, false);
}
To add a double finger tap gesture recognizer, you can use a plugin such as:
http://plugins.jquery.com/project/multiswipe
This worked for me!
// Ipad Navigation Hover Support
$('#header .nav li a').bind('touchstart touchend', function(e) {
if( $(this).attr("href") != "" ){
window.location = $(this).attr("href");
}
});
Here's an optimized version of the jQuery code provided by Richard JP Le Guen:
$(document).ready(function() {
$('a').each(function() {
var clicked = false;
$(this).bind('click', function() {
if(!clicked) return !(clicked = true);
});
});
});
There is a more simpler way to fix the issue with iOS and hover states, using CSS. For the link you have an issue with set the cursor property to pointer and the hover state will be ignored on iOS. For all links to function as expected, see below:
a
{cursor: pointer;}

Categories