jquery simple swap p element? - javascript

Given a p element like so:
<p>Something</p> I want to, when the user mouses over it, we have, instead <p>go here</p>
After hovering if the mouse leaves the p area, return to the previous:
<p>Something</p> state.
Can I have a simple example of something like this?
Thanks a lot,
MEM

Or a simple modification of Ken Redler's original that uses .data() to keep track of things:
$('p#someID').hover(
function() {
var $this = $(this);
$this.data('orig', $this.html()).html('go here');
},
function() {
var $this = $(this);
$this.html($this.data('orig')).removeData('orig');
}
);
http://www.jsfiddle.net/ambiguous/FhET2/1/

Updated: As #Phrogz points out, I missed part of the sense of the question. The suggestions of capturing state with a closure or using data() are good ones, but here's another way (with an amusing number of moving parts):
$(document).ready( function(){
$('p#someID').hover(
function() { // on mouseEnter
$(this)
.contents()
.wrap('<span class="hide"/>') // wrap 'n' hide
.end() // back to 'this'
.append('Fascinating Link!'); // add link
}, function() { // on mouseLeave
$(this)
.find('a')
.remove() // kill the anchor
.end() // back to 'this'
.find('span.hide') // the wrapper
.contents() // the wrapped
.unwrap(); // kill the wrapper, leaving its contents
});
});
This assumes a style like so:
span.hide {
display: none;
}
Updated example: http://www.jsfiddle.net/redler/HAGzH/1/

$('p#IDHERE').hover(
function(){ // on mouseEnter
$(this).contents().replaceWith('go here');
},
function(){ // on mouseLeave
$(this).contents().replaceWith("something");
}
);
This will replace all text

Related

How to remove class after it been added

So I need a little bit of help. I'm playing around with addClass and removeClass and I can't seem to remove a class after it's set. What I basically want is:
When someone clicks an h3, it adds to its parent div class
When someone clicks a div with added class, class needs to be removed
First step I got out of way and it's working
$(function(){
$('div h3.itemTitle').on('click', function(){
$(this).parent().addClass('active').siblings().removeClass('active');
});
});
Now when I define:
$(function(){
$('div.active').on('click', function(){
$(this).removeClass('active');
});
});
It does nothing, as if it doesn't see classes. It sets only those set in onload...
Help, anyone?
The child element "h3.itemTitle" already had a click event listener on it and the parent can't actually capture the click event.
Your $('div.active').on('click', ...) never actually fires because you click the h3 not the div.
I recommend this approach: http://jsfiddle.net/c3Q6Q/
$('div h3.itemTitle').on('click', function () {
// saves time not to write $(this).parent() everything so i store in a _parent var
var _parent = $(this).parent();
if (_parent.hasClass('active')) {
_parent.removeClass('active');
} else {
_parent.addClass('active').siblings().removeClass('active');
}
});
Try
$('body').on('click','div.active', function(){$(this).removeClass('active');});
Instead of
$('div.active').on('click', function(){$(this).removeClass('active');});
I would go with this way:
$('div').on('click', function(e){
var el = e.target;
if($(el).is('h3') && $(el).hasClass('itemTitle')){
$(this).parent().addClass('active').siblings().removeClass('active');
}else if($(el).is('div') && $(el).hasClass('active')){
$(this).removeClass('active');
}
});
Not sure why every is talking about elements generated outside of the initial DOM load.
Here's a JSFiddle showing that it works: http://jsfiddle.net/H25bT/
Code:
$(document).ready(function() {
$('.itemTitle').on('click', function() {
$(this).parent().addClass('active').siblings().removeClass('active');
});
/* $('.parent').on('click', function() {
$(this).removeClass('active');
}); */
$('.clicky').on('click', function() {
$(this).parent().removeClass('active');
});
});
The reason it's not working for you is that if you put the removeClass click event on the parent div itself, clicking on the child text causes a conflict with which click handler to use, and it won't work out. Code works fine if you don't assign the click to the parent div itself.

Defining a single jQuery function for separate DOM elements

I have several jQuery click functions- each is attached to a different DOM element, and does slightly different things...
One, for example, opens and closes a dictionary, and changes the text...
$(".dictionaryFlip").click(function(){
var link = $(this);
$(".dictionaryHolder").slideToggle('fast', function() {
if ($(this).is(":visible")) {
link.text("dictionary ON");
}
else {
link.text("dictionary OFF");
}
});
});
HTML
<div class="dictionaryHolder">
<div id="dictionaryHeading">
<span class="dictionaryTitle">中 文 词 典</span>
<span class="dictionaryHeadings">Dialog</span>
<span class="dictionaryHeadings">Word Bank</span>
</div>
</div>
<p class="dictionaryFlip">toggle dictionary: off</p>
I have a separate click function for each thing I'd like to do...
Is there a way to define one click function and assign it to different DOM elements? Then maybe use if else logic to change up what's done inside the function?
Thanks!
Clarification:
I have a click function to 1) Turn on and off the dictionary, 2) Turn on and off the menu, 3) Turn on and off the minimap... etc... Just wanted to cut down on code by combining all of these into a single click function
You can of course define a single function and use it on multiple HTML elements. It's a common pattern and should be utilized if at all possible!
var onclick = function(event) {
var $elem = $(this);
alert("Clicked!");
};
$("a").click(onclick);
$(".b").click(onclick);
$("#c").click(onclick);
// jQuery can select multiple elements in one selector
$("a, .b, #c").click(onclick);
You can also store contextual information on the element using the data- custom attribute. jQuery has a nice .data function (it's simply a prefixed proxy for .attr) that allows you to easily set and retrieve keys and values on an element. Say we have a list of people, for example:
<section>
<div class="user" data-id="124124">
<h1>John Smith</h1>
<h3>Cupertino, San Franciso</h3>
</div>
</section>
Now we register a click handler on the .user class and get the id on the user:
var onclick = function(event) {
var $this = $(this), //Always good to cache your jQuery elements (if you use them more than once)
id = $this.data("id");
alert("User ID: " + id);
};
$(".user").click(onclick);
Here's a simple pattern
function a(elem){
var link = $(elem);
$(".dictionaryHolder").slideToggle('fast', function() {
if (link.is(":visible")) {
link.text("dictionary ON");
}
else {
link.text("dictionary OFF");
}
});
}
$(".dictionaryFlip").click(function(){a(this);});
$(".anotherElement").click(function(){a(this);});
Well, you could do something like:
var f = function() {
var $this = $(this);
if($this.hasClass('A')) { /* do something */ }
if($this.hasClass('B')) { /* do something else */ }
}
$('.selector').click(f);
and so inside the f function you check what was class of clicked element
and depending on that do what u wish
For better performance, you can assign only one event listener to your page. Then, use event.target to know which part was clicked and what to do.
I would put each action in a separate function, to keep code readable.
I would also recommend using a unique Id per clickable item you need.
$("body").click(function(event) {
switch(event.target.id) {
// call suitable action according to the id of clicked element
case 'dictionaryFlip':
flipDictionnary()
break;
case 'menuToggle':
toggleMenu()
break;
// other actions go here
}
});
function flipDictionnary() {
// code here
}
function toggleMenu() {
// code here
}
cf. Event Delegation with jQuery http://www.sitepoint.com/event-delegation-with-jquery/

Prototype event handler

I've defined the following HTML elements
<span class="toggle-arrow">▼</span>
<span class="toggle-arrow" style="display:none;">▶</span>
When I click on one of the elements the visibility of both should be toggled. I tried the following Prototype code:
$$('.toggle-arrow').each(function(element) {
element.observe('click', function() {
$(element).toggle();
});
});
but it doesn't work. I know everything would be much simpler if I used jQuery, but unfortunately this is not an option:
Instead of iterating through all arrows in the collection, you can use the invoke method, to bind the event handlers, as well as toggling them. Here's an example:
var arrows = $$('.toggle-arrow');
arrows.invoke("observe", "click", function () {
arrows.invoke("toggle");
});
DEMO: http://jsfiddle.net/ddMn4/
I realize this is not quite what you're asking for, but consider something like this:
<div class="toggle-arrow-container">
<span class="toggle-arrow" style="color: pink;">▶</span>
<span class="toggle-arrow" style="display:none; color: orange;">▶</span>
</div>
document.on('click', '.toggle-arrow-container .toggle-arrow', function(event, el) {
var buddies = el.up('.toggle-arrow-container').select('.toggle-arrow');
buddies.invoke('toggle');
});
This will allow you to have multiple "toggle sets" on the page. Check out the fiddle: http://jsfiddle.net/nDppd/
Hope this helps on your Prototype adventure.
Off the cuff:
function toggleArrows(e) {
e.stop();
// first discover clicked arow
var clickedArrow = e.findElement();
// second hide all arrows
$$('.toggle-arrow').invoke('hide');
// third find arrow that wasn't clicked
var arw = $$('.toggle-arrow').find(function(a) {
return a.identify() != clickedArrow.identify();
});
// fourth complete the toggle
if(arw)
arw.show();
}
Wire the toggle arrow function in document loaded event like this
document.on('click','.toggle-arrow', toggleArrows.bindAsEventListener());
That's it, however you would have more success if you took advantage of two css classes of: arrow and arrow-selected. Then you could easily write your selector using these class names to invoke your hide/show "toggle" with something like:
function toggleArrows(e) {
e.stop();
$$('.toggle-arrow').invoke('hide');
var arw = $$('.toggle-arrow').reject(function(r) {
r.hasClassName('arrow-selected'); });
$$('.arrow-selected').invoke('removeClassName', 'arrow-selected');
arw.show();
arw.addClassName('arrow-selected');
}

Changing from .live to .on

I know .live was depreciated and recently I was updating a page and realized I was using .live I would like to switch to .on but do not understand what to change. Here is my current code:
//Script for Choosing which form to display
$("#email-button, #text-button").live('click',
function(){
//figure out what button was clicked.
if(this.id === "email-button"){
var btnA = $(this);
var btnB = $("#text-button");
var divA = $('#email-form');
var divB = $('#text-form');
}
else{
btnA = $(this);
btnB = $("#email-button");
divA = $('#text-form');
divB = $('#email-form');
}
//make sure it is not already active, no use to show/hide when it is already set
if(btnA.hasClass('dark_button_span')){
return;
}
//see if div is visible, if so hide, than show first div
if(divB.is(":visible")){
divB.fadeOut("slow", function(){
divA.fadeIn("slow");
});
}
else{//if already hidden, just show the first div
divA.fadeIn("slow");
}
//Add and remove classes to the buttons to switch state
btnA.addClass('dark_button_span').removeClass('light_button_span');
btnB.removeClass('dark_button_span').addClass('light_button_span');
}
);
I had assistance writing the above script and do not know what to change. Simply changing .live to .on doesn't work.
Any help would be greatly appreciated!
Thanks!
The syntax for on is
$("containerElement").on("click", "targetElement(s)", function(){ });
So in your case it could be
$("body").on("click", "#email-button, #text-button", function(){ });
But being more specific than body is a good idea.
$(document).on('click', '#email-button, #text-button', function() {
// Your code
});
Should do the trick. See http://api.jquery.com/live/ and http://api.jquery.com/on/.
However, since you're using IDs, you probably don't even need .live() or delegating .on(). So the way I'd write that would be simply:
function doButtons(btnA, btnB, divA, divB) {
btnA = $(btnA); btnB = $(btnB); divA = $(divA); divB = $(divB);
// Make sure it is not already active, no use to show/hide when it is already set
if (btnA.hasClass('dark_button_span'))
return;
// See if div is visible, if so hide, then show first div.
if (divB.is(":visible")) {
divB.fadeOut("slow", function (){
divA.fadeIn("slow");
});
}
else // If already hidden, just show the first div.
divA.fadeIn("slow");
// Add and remove classes to the buttons to switch state.
btnA.addClass('dark_button_span').removeClass('light_button_span');
btnB.removeClass('dark_button_span').addClass('light_button_span');
}
$('#email-button').click(function () {
doButtons(this, '#text-button', '#email-form', '#text-form');
});
$('#text-button').click(function () {
doButtons(this, '#email-button', '#text-form', '#email-form');
});
jQuery's .on doesn't use event delegation unless you provide it a selector. In the above code, .live listens for events at the document, but that's far too much bubbling. If we were to implement it with .on though we would do the following:
var handler = function( e ) {
console.log( "Clicked" );
};
$( document ).on( "click", "#email-button, #text-button", handler );
Again though, it isn't really all that wise to listen for events on the document; ideally you would pick an element just above your selector. So if #email-button and #text-button have a common parent, you should use that in place of document.

jQuery: hijack a link and find its parent

I know how to hijack a link in jQuery, and I know how to find an element's parent, but I can't seem to combine the two. I have multiple divs, each of which contains a link. I want to hijack the link and update the parent div's content.
<div class="container-1">
Add content
</div>
<div class="container-2">
Add content
</div>
Here's what I have with jQuery:
$(function() {
$(".pager A").live("click",
function() {
$.get($(this).attr("href"),
function(response) {
$(this).parent().attr("id").replaceWith(response); // This is wrong
});
return false;
});
});
The line with the "This is wrong" comment doesn't have what I want for $(this). It appears to contain the result from the previous expression, not the element I selected (".pager A").
How can I do this?
Bonus question: Visual Studio complains that ".get is a reserved word and should not be used as an identifier". What exactly is the problem?
EDIT: Sorry, I meant <div id="container-1">, not <div class="container-1">. Ditto for the 2nd div.
Try saving the reference to the current execution context where it points to the anchor to refer to later in the callback:
$(function() {
$(".pager A").live("click",
function() {
var el = this;
$.get($(el).attr("href"),
function(response) {
$(el).parent().html( response ); // is this what you want? .attr('id') would return a string and you can't call jQuery methods on a string.
});
return false;
});
});
First of all:
$(function() {
$(".pager A").live("click",
function() {
var $link = $(this);
$.get($(this).attr("href"),
function(response) {
$link.parent().attr("id").replaceWith(response); // This is wrong
});
return false;
});
});
You shouldn't use $(this) in callback function.
And the second - your link's parent element doesn't have id attribute. If you want to replace it's content use something like html() or text()

Categories