Why doesn't my div swap by .class work? - javascript

Having trouble converting the following code from dealing with IDs to Classes.
Basicly what the code does is reveals one Div while hiding another.
In the original version it was simple because the div location was absolute.
With the classes version I need to reveal the next instance of 'product-specs' based on which DIV the onClick was located.
NOTE/EDIT: Their are multiple versions of the same classes on the page. So references to the classes must be specific to the closest instance of the class, based on the location of the link that was clicked.
HTML:
<div id="product-details">
<area shape="rect" onClick="swap3('product-details','product-specs');">
</div>
<div id="product-specs">
<p>Content</p>
</div>
Javascript:
function swap3(oldDivId, newDivId) {
var oldDiv = document.getElementById(oldDivId);
var newDiv = document.getElementById(newDivId);
oldDiv.style.display = "none";
newDiv.style.display = "block";
}
However now I need to add multiple instances of product details Div & Products specs
New HTML:
<div class="product-details">
<area shape="rect" onClick="swap3('product- details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
<div class="product-details">
<area shape="rect" onClick="swap3('product- details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
New Javascript:
????????

Note: (I explain the complete code befoe here, so just put the updated here) remember that when your selector is a className, you will got an array! change the code like this and test again:
function swap3(currentDivId ,oldDivId, newDivId) {
var oldDiv = $(currentDivId).nextAll("div." + oldDivId);
var newDiv = $(currentDivId).nextAll("div." + newDivId);
$(oldDiv).each(function(){ $(this).css({"display" : "none"}); });
$(newDiv).each(function(){ $(this).css({"display" : "block"}); });
}

In native JavaScript, you'd use getElementsByClassName() -- but it's not supported in IE up thru version 8. You can use a purpose-built wrapper script like this one, or use a library like jQuery to abstract away the browser differences.
In jQuery, try something like
function swap( oldClassName, newClassName ) {
$("'." + oldClassName + "'").hide();
$("'." + newClassName + "'").show();
}

To hide the 'details' div and show the immediately-following div, assumed to be 'specs', try this jQuery snippet. It attaches a click handler to every 'product-details' div, and when it fires, it hides that div and shows its immediate sibling:
$(".product-details").click( function() {
$(this).hide();
$(this).next().show();
});
The reverse behavior (hiding the specs and showing the details) is left as an exercise for the reader ;-)

Original:
function swap3(oldDivId, newDivId) {
var oldDiv = document.getElementById(oldDivId);
var newDiv = document.getElementById(newDivId);
oldDiv.style.display = "none";
newDiv.style.display = "block";
}
jQuery:
function swap3(oldDivId, newDivId) {
var $oldDiv = $('#' + oldDivId);
var $newDiv = $('#' + newDivId);
$oldDiv.hide();
$newDiv.show();
}
jQuery Classes:
function swap3(oldDivClass, newDivClass) {
var $oldDiv = $('.' + oldDivClass);
var $newDiv = $('.' + newDivClass);
$oldDiv.hide();
$newDiv.show();
}

Something else you can do is to wrap each of your products inside a div without any class or id. It does make sense to group them like that, something like
<div>
<div class="product-details">
<area shape="rect" onClick="swap3('product-
details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
</div>
<div>
<div class="product-details">
<area shape="rect" onClick="swap3('product-
details','product-specs');">
</div>
<div class="product-specs">
<p>Content</p>
</div>
</div>
Note the extra wrapping divs. Now, you can use the parent element to identify the product specs that you have to show. E.g.: (Maybe there's a better way to do it)
$('.product-details').click(function() {
// Find the specs to show
var $specs = $(this).siblings('.product-specs');
// Hide the other ones
$('.product-specs').not($specs).hide();
// Show the one that you want
$specs.show();
});
Hope it works!

Related

creating a link to images

I am trying to create a jquery code which can wrap an img tag with a link:
My code is like this:
http://prntscr.com/iuw6hc
I will paste my HTML here but basically it is a loop of many items showing within each col.
<div class="car-item gray-bg text-center first" style="height: 357px;">
<div class="car-image">
<img class="img-responsive" src="http:///wp-content/uploads/2018/03/20180214_090633-265x190.jpg" alt="" width="265" height="190">
<div class="car-overlay-banner">
<ul>
<li><i class="fa fa-link"></i></li>
I am trying like this:
var wrapped = false;
var original = $(".img-responsive");
$(".img-responsive").click(function(){
if (!wrapped) {
wrapped = true;
var gURL = $('.car-overlay-banner').find('a').attr('href');
$(".img-responsive").wrap("");
}
});
$(".img-responsive").click(function(){
if (wrapped) {
wrapped = false;
$(".img-responsive").parent().replaceWith(original);
}
});
Trying to use a href of car overlay to apply to the image too.
jQuery provides a method named "wrap()", which can be used to insert any HTML structure in set of matched elements. In simple words, if you want put wrapper around your div element then you can use wrap() method. For example, you have a div with ID "Child".
<div id="Child"></div>
And want to wrap this div with any parent then you can use "wrap()" method to insert HTML.
$('#Child').wrap('<div id="Parent"></div>');
<div id="parent">
<div id="child"></div>
</div>
Same way, we will use the wrap() method to insert hyperlink to image tag so that the image becomes clickable. See below.
$(document).ready(function() {
$("#imgLogo").wrap('');
});
In this example, I have used ID as selector but you can use class selector to find all the images with same class and then wrap them with tag. You can also assign target="_blank" in the above tag to open the link in new window.
I think you need code like this?
var wrapped = false;
var original = $(".img-responsive");
$(".img-responsive").click(function(){
if (!wrapped) {
var wrapped = true;
// find link href in .car-image(img-responsive's parent)
var gURL = $(this).parent().find('a').attr('href');
// use $(this) instead of $(".classname") to apply link only clicked image
$(this).wrap("");
}
});
$(".img-responsive").click(function(){
if (wrapped) {
var wrapped = false;
$(this).parent().replaceWith(original);
}
});

How can I properly use '$(this)' to call a DOM element that triggered the event?

I wrote the following script that resets the the Iframe Source, removes a class (.play) and adds an image placeholder when .b-close is clicked. I got it to work but the problem is that I have multiple modals and I would like only like to affect the modal that's clicked. I figured that I should use the '$(this)' DOM element in order to achieve this.
<script>
(function($){
var ivid = $('.pretty-embed iframe').attr('src');
$(document).ready(function() {
$(".b-close").click(function(e){
e.preventDefault();
var vidID = $(this).parent().find('.pretty-embed').attr('data-pe-videoid');
var vidImg = "//img.youtube.com/vi/"+vidID+"/maxresdefault.jpg";
var vidImgUrl = '<img src="'+vidImg+'" width="100%" alt="YouTube Video Preview">';
$('.pretty-embed').removeClass('play').empty();
$('.pretty-embed').html(vidImgUrl);
$('.b-modal').click(); /// Just trying to close modal..... $.modal.close();
});
});
})(jQuery);
</script>
Here's is the the Modal that I will be calling. Keep in mind that there will be multiple modals, so I would only like to affect the modal that's clicked
<div id="element_to_pop_up" display: block;">
<a class="b-close">x</a>
<h3 class="pop-hd">Header</h3>
<p>Test Video</p>
<div class="pretty-embed play" data-pe-allow-fullscreen="false">
<iframe width="330" height="186" style="border:none;" src="//www.youtube.com/embed/nGSfaMxCu-U?autoplay=1&rel=1"></iframe>
</div>
</div>
The problem is in your $('.pretty-embed') selector which selects all the embed elements in all modals If I understood your problem correctly. To fix that take the id of the modal and prepend it to the selectors like below:
(function($){
var ivid = $('.pretty-embed iframe').attr('src');
$(document).ready(function() {
$(".b-close").click(function(e){
e.preventDefault();
var vidID = $(this).parent().find('.pretty-embed').attr('data-pe-videoid');
var vidImg = "//img.youtube.com/vi/"+vidID+"/maxresdefault.jpg";
var vidImgUrl = '<img src="'+vidImg+'" width="100%" alt="YouTube Video Preview">';
var parent_id = $(this).parent().attr(id);
// Prepend the parent id before the .pretty-embed selector
$('#'+parent_id+' .pretty-embed').removeClass('play').empty();
$('#'+parent_id+' .pretty-embed').html(vidImgUrl);
$('#'+parent_id+' .b-modal').click(); /// Just trying to close modal... $.modal.close();
});
});
Also you can use the same way you did it in the previous lines:
$(this).parent().find('.pretty-embed').removeClass('play').empty();
You can get the current modal with
var current_modal = $(this).parent().find('.pretty-embed');
Then remove the class play, and add your image like this:
current_modal.removeClass('play').empty();
current_modal.html(vidImgUrl);
See your complete code in this jsfiddle

jquery : how to apply same changes inside mulitple container with same class name

i am trying to move a .details outside of .buttons
<div class="product-actions">product 1
<div class="buttons buttons_3 group">buttons
<a class="details" title="Détails" rel="nofollow" >link</a>
</div>
</div>
<div class="product-actions">product 2
<div class="buttons buttons_3 group">buttons
<a class="details" title="Détails" rel="nofollow" >link</a>
</div>
</div>
this do the trick
if ($('.product-actions').length )
{
$('.product-actions').prepend("<div id='new_details_location'></div>");
$(".details").prependTo("#new_details_location");
$('.buttons_3').attr('class','buttons buttons_2 group');
}
the problem is there is more than one product and all a.details get moved to the first product div instead of being prepend at the beginning of each div .product-actions:
http://jsfiddle.net/upKhq/2/
any idea?
Try this FIDDLE
$('.product-actions').each(function () {
$new = $(this).prepend("<div class='new_details_location'></div>");
$(".details", $(this)).prependTo($new);
$('.buttons_3', $(this)).attr('class', 'buttons buttons_2 group');
});
You made a few mistakes:
your selectors were not context sensitive and you were using id in prependTo which has to be unique, but you had 2 divs with the same id.
Did you mean to do this instead?
$('.product-actions').each(function() {
$elem = $("<div class='new_details_location'></div>");
$(this).find(".details").prependTo($elem);
$(this).prepend($elem);
});
$('.buttons_3').attr('class', 'buttons buttons_2 group');
http://jsfiddle.net/samliew/upKhq/4/
You can use each jquery method:
$('.product-actions').each(function() {
var self = $(this);
var new_location = $("<div id='new_details_location'></div>").prependTo(self);
self.find(".details").prependTo(new_location);
self.find('.buttons_3').attr('class','buttons buttons_2 group');
});
And you should not use the same id for two elements.
use .each, and use $(this) to refer to the current .product-actions element. Also you cant have multiple ids that are the same, only the first one would ever be used
if ($('.product-actions').length ) {
$('.product-actions').each(function() {
var newDetailLocation = $('<div></div>');
$(this).prepend(newDetailLocation);
$(".details",$(this)).prependTo(newDetailLocation);
$('.buttons_3',$(this)).attr('class','buttons buttons_2 group');
});
}

Jquery onmouseover() function on dynamic html images and span

I have some images and some span text on my page. Each image has his text and those elements are added dynamicaly with javascript.
Now, I would like to show the right message when mouseover on an image is detected.
It is not easy to explain, so here is the example:
var len = article_affiliations.length;
for (var affiliation_id = 0; affiliation_id < len; affiliation_id++)
{
$('#country_warning' + affiliation_id).mouseover(function () {
document.getElementById('country_warning_message' + affiliation_id)
.style.visibility = 'visible';
}).mouseout(function () {
document.getElementById('country_warning_message' + affiliation_id)
.style.visibility = 'hidden';
});
}
The problem is that when the onmouseover function will be called, the affiliation_id will have the maximum value and the message will be shown near the last image, and not near the clicked one.
Thank you very much for your help.
Closure should do the trick:
for(var affiliation_id=0; affiliation_id<article_affiliations.length; affiliation_id++) {
(function(i){
$('#country_warning'+i).mouseover(function() {
$('#country_warning_message'+i).css('visibility','visible');
}).mouseout(function(){
$('#country_warning_message'+i).css('visibility','hidden');
});
})(affiliation_id);
}
You'll need to bind your for loop in a closure for this to work. This way, all indices of #country_warning_i will be affected.
$(function () {
$.each(article_affiliations, function (i, v) {
$('#country_warning' + i).mouseover(function (affiliation_id, affiliation_iddddd) {
$('country_warning_message' + i).style.visibility = 'visible';
}).mouseout(function (i, affiliation_iddddd) {
$('country_warning_message' + i).style.visibility = 'hidden';
});
});
});
Enjoy and good luck!
You shouldn't do it with a loop that will just go through everyone of your elements. The best way of doing something like this is using the 'event.target'(built in jQuery) and 'this' objects.
Instead attach a mouseover event handler to the parent of your . The best is if your markup looks something like this:
<div class="item">
<img src="someimage.jpg" />
<span>some text</span>
</div>
<div class="item">
<img src="someimage.jpg" />
<span>some text</span>
</div>
<div class="item">
<img src="someimage.jpg" />
<span>some text</span>
</div>
That way you can use a script similar to this one:
$('.item').on('mouseover', function() {
$(this).find('span').show();
});
This will search for a span (every span) inside the element you attached the mouseover event to (for this ex the ).
Another way is to use simple css like this:
span {
visibility: hidden;
}
item:hover span {
visibility: visible;
}
This is an extremely simple solution and works beautifully, but unfortunately IE6 doesn't support hover on elements different from .

Selecting a single class from a multi class element

I'm trying to select a specific class (in this case page1, page2, page3 etc.)
I've written this code that works fine for a single class, i've tried using .match() to exclude the .plink class picked up in dis but can't get it working.
$(function(){
$("a.plink").click(function() {
var dis = $(this).attr("class"); // This is the problem line, I need it to contain 'page1' ONLY. Not 'page1 plink'.
$("#page1,#page2,#page3").hide();
$("#" + dis).show();
return false;
});
});
The HTML that is associated with this is:
<div id="page-links">
<a class="page1 plink" href="#">About</a>
<a class="page2 plink" href="#">History</a>
<a class="page3 plink" href="#">Backstage</a>
</div>
EDIT:
These are the DIV's being shown and hidden:
<div id="page1">
<?php include_once("page1.php");?>
</div>
<div id="page2">
<?php include_once("page2.php");?>
</div>
<div id="page3">
<?php include_once("page3.php");?>
</div>
Is there a simple way to achieve this without regular expression matching?
$(function(){
var pages = $('div[id^=page]');
$("a.plink").click(function() {
var dis = $(this).attr("class").replace(' plink', '');
pages.hide().filter('#' + dis).show();
return false;
});
});
This should be
$("." + dis).show();
for class and in your example there are all classes.
As you mentioned simple way so it could be
$("a.plink").click(function() {
$(".plink").hide();
$(this).show();
return false;
});
According to your question after edit
$("a.plink").click(function() {
$('div[id^="page"]').not('#page-links').hide();
pid=$(this).attr('class').split(' ')[0];
$('#'+pid).show();
return false;
});
Here is a fiddle.
The JavaScript code is not correct. With the "#" you select ids from the html-element.
As you have only classes, the right way is to do it with "."
So this would be correct:
$(function(){
$("a.plink").click(function() {
var dis = $(this).attr("class");
$(".page1,.page2,.page3").hide();
$("." + dis).show();
return false;
});
});
I didn't test it, but I think you have to change something with the var dis.
If you click on .page1, the variable dis would contain "page1 plink".
$("." + dis).show();
would be
$(".page1 plink").show();
So I recommend to split the two classes, as it should be like
$(".page1 .plink").show();
You are trying to associate functionality of a click by appending classes. It would make more sense to put id of the div you want to show in the href
html:
<div id="page-links">
<a class="plink" href="#page1">About</a>
<a class="plink" href="#page2">History</a>
<a class=" plink" href="#page3">Backstage</a>
</div>
<div id="page1">
Content 1
</div>
<div id="page2">
Content 2
</div>
<div id="page3">
Content 3
</div>
​javascript:
jQuery(function ($) {
var pages = [];
function showPage(page) {
var i;
for(i = 0; i < pages.length; i++)
{
if(page === pages[i]) {
$(pages[i]).show();
} else {
$(pages[i]).hide();
}
}
}
// Store each href in a pages array and add handlers
$('.plink').each( function() {
var page = $(this).attr('href');
pages.push(page);
$(this).attr('href', '#');
$(this).click(function () {
showPage(page);
});
});
// show the first page
if(pages.length > 0) {
showPage(pages[0]);
}
});​
Example:
http://jsfiddle.net/38qLB/
And just so I don't avoid the actual question, which is how do you select a class from a multi class element, you should follow this example of splitting up the class name Get class list for element with jQuery if you truly insist on using classes to make your link/div association
You don't really want to exclude the plink class, because that will bring you confusion and trouble when you need to add another class. Instead you want to extract just the pageX class:
// Regex for extracting pageXX
var reg = /^(.*\s)?(page\d+)([^\d].*)?$/;
dis = reg.exec(dis)[2];
I haven't testet this 100%, but put these two lines in right after var dis = $(this).attr("class"); and you should hopefully be good to go.
i down't know if i get your question right
to get all classes with class plink u can use
var klasses $("a.plink");
now u can loop true the items
var yourClasses = Array();
for(var klass in klasses)
{
var word = klass.attr('class').replace(" plink", "");
yourClasses.push(word);
}
now you have all the classes wich have the class plink
hope this was where u where looking for
If I was just doing a minor tweak to fix your existing structure I would do something like this:
$(document).ready(function() {
$('a.plink').click(function() {
var id = $.trim(this.className.replace('plink', ''));
/*adding a "page" class to each of the page divs makes hiding the visible one a bit easier*/
$('div.page').hide();
/*otherwise use the version from sheikh*/
//$('div[id^="page"]').not('#page-links').hide();
$('div#' + id).show();
});
});
The main change I would recommend to your existing markup would be to add a common "page" class to each of the page divs. Here is a fiddle
If I was starting on this from scratch I would probably take a slightly different approach in which I define an "active" class and toggle which elements have it rather than using show/hide on the divs. And that would end up looking something like this:
Markup:
<div id="page-links">
<a class="plink active" href="#page1">About</a>
<a class="plink" href="#page2">History</a>
<a class="plink" href="#page3">Backstage</a>
</div>
<div id="page1" class='page active'> </div>
<div id="page2" class='page'> </div>
<div id="page3" class='page'> </div>
CSS:
div.page
{
height: 300px;
display:none;
}
div.page.active
{
display:block;
}
a.plink
{
padding-left:5px;
padding-right:5px;
}
a.plink.active
{
background-color:#ddd;
}
div#page1
{
background-color:blue;
}
div#page2
{
background-color:green;
}
div#page3
{
background-color:red;
}
Script:
$(document).ready(function() {
$('a.plink').click(function() {
var id = $(this).attr('href');
$('.active').removeClass('active');
$(this).addClass('active');
$('div' + id).addClass('active');
});
});
Or the fiddle here.
Oh and to answer the title question rather than just the end behavior described...
var classes = this.className.split(' ');
var id;
for (var i = 0; i < classes.length; i++) {
if(classes[i].substring(4) === classes[i].replace('page', '')) {
id = classes[i];
break;
}
}
should end up with id containing the "page#" value associated with the link that was clicked regardless of its position in the list of classes.

Categories