I have three tabs, but when I click on any of them, nothing happens and there is no error in the console. What is wrong?
When I click on any of .tabs-nav-item nothing happens.
function initTab(elem) {
document.addEventListener("click", function(e) {
if (!e.target.matches(elem + " .tabs-nav-item")) return;
else {
if (!e.target.classList.contains("active")) {
findActiveElementAndRemoveIt(elem + " .tabs-nav-item");
findActiveElementAndRemoveIt(elem + " .tab-content-item");
e.target.classList.add("active");
setTimeout(function() {
var panel = document.querySelectorAll(
elem + " .tab-content-item" + e.target.dataset.name
);
Array.prototype.forEach.call(panel, function(el) {
el.classList.add("active");
ckj;
});
}, 200);
}
}
});
}
function findActiveElementAndRemoveIt(elem) {
var elementList = document.querySelectorAll(elem);
Array.prototype.forEach.call(elementList, function(e) {
e.classList.remove("active");
});
}
initTab(".tabs");
<div class="tabs">
<div class="tabs-nav">
<p class="tabs-nav-item active" data-name="profile">Profile</p>
<p class="tabs-nav-item" data-name="messages">Messages</p>
<p class="tabs-nav-item" data-name="settings">Settings</p>
</div>
<div class="tabs-content">
<div class="profile active tab-content-item">
<h3>Lorem</h3>
</div>
<div class="tab-content-item messages">
<h3>ipsum </h3>
</div>
<div class="tab-content-item settings">
<h3>sit amet.</h3>
</div>
</div>
</div>
I think that you have problem in the selector inside setTimeout function.
I have made it work using data attributes
function initTab(elem) {
document.addEventListener("click", function (e) {
if (!e.target.matches(elem + " .tabs-nav-item")) return;
else {
if (!e.target.classList.contains("active")) {
findActiveElementAndRemoveIt(elem + " .tabs-nav-item");
findActiveElementAndRemoveIt(elem + " .tab-content-item");
e.target.classList.add("active")
setTimeout(function () {
var panel = document.querySelectorAll(".tab-content-item[data-name=" + e.target.dataset.name + "]");
Array.prototype.forEach.call(panel, function (el) {
el.classList.add("active");
});
}, 200);
}
}
});
}
function findActiveElementAndRemoveIt(elem) {
var elementList = document.querySelectorAll(elem);
Array.prototype.forEach.call(elementList, function (e) {
e.classList.remove("active");
});
}
initTab(".tabs");
.tabs-nav {
display: flex;
gap: 16px;
}
.tabs-nav-item {
cursor: pointer;
}
.tabs-nav .active {
font-weight: bold;
}
.tabs-content .tab-content-item {
display: none;
}
.tabs-content .active {
display: block;
}
<div class="tabs">
<div class="tabs-nav">
<p class="tabs-nav-item active" data-name="profile">Profile</p>
<p class="tabs-nav-item" data-name="messages">Messages</p>
<p class="tabs-nav-item" data-name="settings">Settings</p>
</div>
<div class="tabs-content">
<div class="active tab-content-item" data-name="profile">
<h3>Lorem</h3>
</div>
<div class="tab-content-item" data-name="messages">
<h3>ipsum </h3>
</div>
<div class="tab-content-item" data-name="settings">
<h3>sit amet.</h3>
</div>
</div>
</div>
I hope that this will help is you didn't solve the issue yet.
Just Run the code snippet to see the result.
Related
I created tabs on JS and my script decided to deny working.
I click on tabs - they don't work and content also is not hidden.
Chrome shows NO bugs. Code should work without doubts but it seems an error somewere. All the classes such as 'hide', 'show' are created on external style.css file.
Please, help !!
var tab;
var content;
window.onload = function() {
content = document.querySelector('.content');
tab = document.querySelector('.tab');
hideTabsContent(1);
}
function hideTabsContent(a) {
for (var i = a; i < content.length; i++) {
content[i].classList.remove('show');
content[i].classList.add("hide");
tab[i].classList.remove('active');
}
}
document.querySelector('.container').onclick = function(event) {
var target = event.target;
if (target.className == 'tab') {
for (var i = 0; i < tab.length; i++) {
if (target == tab[i]) {
showTabsContent(i);
break;
}
}
}
}
function showTabsContent(b) {
if (content[b].classList.contains('hide')) {
hideTabsContent(0);
tab[b].classList.add('active');
content[b].classList.remove('hide');
content[b].classList.add('show');
}
}
.tab {
cursor: pointer;
}
.active {
color: white;
background-color: green;
}
.show {
display: block;
}
.hide {
display: none;
}
<div class="container">
<div class="tab active">Summer</div>
<div class="tab">Autumn</div>
<div class="tab">Winter</div>
<div class="content">
<img src="img/pic-1.jpg">
<img src="img/pic-2.jpg">
<img src="img/pic-3.jpg">
</div>
<div class="content">
<img src="img/pic-4.jpg">
<img src="img/pic-5.jpg">
<img src="img/pic-6.jpg">
</div>
<div class="content">
<img src="img/pic-7.jpg">
<img src="img/pic-8.jpg">
<img src="img/pic-9.jpg">
</div>
</div>
Use querySelectorAll to return an array of elements or it returns just the first found element.
window.onload=function() {
content=document.querySelectorAll('.content');
tab=document.querySelectorAll('.tab');
hideTabsContent(1);
}
Change the selection from querySelctor() to querySelectorAll() working example is below
var tab;
var content;
window.onload = function() {
content = document.querySelectorAll('.content');
tab = document.querySelectorAll('.tab');
hideTabsContent(1);
}
function hideTabsContent(a) {
for (var i = a; i < content.length; i++) {
content[i].classList.remove('show');
content[i].classList.add("hide");
tab[i].classList.remove('active');
}
}
document.querySelector('.container').onclick = function(event) {
var target = event.target;
if (target.className == 'tab') {
for (var i = 0; i < tab.length; i++) {
if (target == tab[i]) {
showTabsContent(i);
break;
}
}
}
}
function showTabsContent(b) {
if (content[b].classList.contains('hide')) {
hideTabsContent(0);
tab[b].classList.add('active');
content[b].classList.remove('hide');
content[b].classList.add('show');
}
}
.tab {
cursor: pointer;
}
.active {
color: white;
background-color: green;
}
.show {
display: block;
}
.hide {
display: none;
}
<div class="container">
<div class="tab active">Summer</div>
<div class="tab">Autumn</div>
<div class="tab">Winter</div>
<div class="content">
<span>1</span>
<span>2</span>
<span>3</span>
</div>
<div class="content">
<span>4</span>
<span>5</span>
<span>6</span>
</div>
<div class="content">
<span>7</span>
<span>8</span>
<span>9</span>
</div>
</div>
I'm trying to search for items using the data-find attribute but my function is just matching the input string with any text inside of the container.
You can see this by adding words to the HTML and then entering the input.
How do I get my function to match what's in the data-find attribute?
$(document).ready(function() {
$("#search-text").keyup(function() {
var n = $("#search-text").val(),
t = ($(".item").attr("[data-find]"),
n.replace(/ /g, "'):finditem('"));
$.extend($.expr[":"], {
finditem: function(n, t, e, i) {
return (
(n.textContent || n.inText || "")
.toLowerCase()
.indexOf((e[3] || "").toLowerCase()) >= 0
);
}
}),
$("#subcat-list div")
.not(":finditem('" + t + "')")
.each(function(n) {
$(this).removeClass("subcat-item");
}),
$("#subcat-list div:finditem('" + t + "')").each(function(n) {
$(this).addClass("subcat-item");
});
});
});
#subcat-list {
display: flex;
}
.subcat-item {
height: 50px;
width: 50px;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search-text" placeholder="search">
<div id="subcat-list">
<div class="subcat-item" style="background:red">
<div class="item" data-find="red"></div>
</div>
<div class="subcat-item blue" style="background:blue">
<div class="item" data-find="blue"></div>
</div>
<div class="subcat-item green" style="background:green">
<div class="item" data-find="green"></div>
</div>
</div>
Use each, toggleClass and includes
$(document).ready(function() {
$("#search-text").keyup(function() {
var n = $("#search-text").val().toLowerCase(); //convert value to lowercase for case-insensitive comparison
$(".item").each( function(){
var $this = $(this);
var value = $this.attr( "data-find" ).toLowerCase(); //convert attribute value to lowercase
$this.parent().toggleClass( "hidden", !value.includes( n ) );
})
});
});
Demo
$(document).ready(function() {
$("#search-text").keyup(function() {
var n = $("#search-text").val();
$(".item").each( function(){
var $this = $(this);
var value = $this.attr( "data-find" ).toLowerCase();
$this.parent().toggleClass( "hidden", !value.includes( n ) );
})
});
});
#subcat-list {
display: flex;
}
.subcat-item {
height: 50px;
width: 50px;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="search-text" placeholder="search">
<div id="subcat-list">
<div class="subcat-item" style="background:red">
<div class="item" data-find="red"></div>
</div>
<div class="subcat-item blue" style="background:blue">
<div class="item" data-find="blue"></div>
</div>
<div class="subcat-item green" style="background:green">
<div class="item" data-find="green"></div>
</div>
</div>
You can use filter to show and hide the divs depending on the data
using .includes you can check weather a data-find contains the characters of the value if the textbox
$(function() {
$("#search-text").keyup(function() {
var n = $(this).val(); /* Get the value of the textbox */
$(".subcat-item").show(); /* Show all .subcat-item */
$(".item").filter(function() { /* Filter all .item and hide*/
return !$(this).data('find').includes(n);
}).parent().hide();
});
});
#subcat-list {
display: flex;
}
.subcat-item {
height: 50px;
width: 50px;
}
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="search-text" placeholder="search">
<div id="subcat-list">
<div class="subcat-item" style="background:red">
<div class="item" data-find="red"></div>
</div>
<div class="subcat-item blue" style="background:blue">
<div class="item" data-find="blue"></div>
</div>
<div class="subcat-item green" style="background:green">
<div class="item" data-find="green"></div>
</div>
</div>
use a simple attribute selector:
$(".item[data-find*='" + n + "']")
will search for .item whose data-find contains the value of n.
I am trying to swap a div's position from top on and when I click another div then top div can be swap.
HTML
<div class="wrap top">
<input type="text" value="div1" class="textbox " />
</div>
<div class="wrap">
<input type="text" value="div2" class="textbox " />
</div>
<div class="wrap">
<input type="text" value="div3" class="textbox " />
</div>
jQuery
(function ($) {
$(".wrap").on("click", function () {
if ($(this).index() == 0) {
} else {
$(this).insertBefore($(this).prev());
}
});
}(jQuery));
The fact is I don't want to remove the div which I click instead want to swap the positions around.
How Can I do this using jQuery itself?
I would suggest using css to position the top div and just swap the class as follows:
(function ($) {
$(".wrap").on("click", function () {
if ($(this).index() == 0) {
} else {
$(".wrap").removeClass("top");
$(this).addClass("top");
}
});
}(jQuery));
this will swap whatever you click with the first element.
$(".wrap").on("click", function () {
var $this = $(this);
if ($this.index() == 0) {
} else {
var first = $this.siblings('.wrap').first();
first.insertBefore($this);
$this.prependTo($this.parent());
}
});
if you just want to move the clicked element to the top, you can simply do
$this.prependTo($this.parent());
To swap the two DOM elements using jQuery, you could use something like this: -
(function($) {
$(".wrap").on("click", function(event) {
var index = $(event.target).index();
var first = $(".wrap").first();
if (index > 0) {
$(first).swapWith(this);
}
});
}(jQuery));
jQuery.fn.swapWith = function(to) {
return this.each(function() {
var copy_to = $(to).clone(true);
var copy_from = $(this).clone(true);
$(to).replaceWith(copy_from);
$(this).replaceWith(copy_to);
});
};
.wrap {
height: 100px;
width: 200px;
margin: 10px 10px 10px 10px;
background-color: #2d8cd0;
}
h2 {
color: white;
text-align: center;
padding-top: 20px;
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="wrap">
<h2>1</h2>
</div>
<div class="wrap">
<h2>2</h2>
</div>
<div class="wrap">
<h2>3</h2>
</div>
<div class="wrap">
<h2>4</h2>
</div>
I currently work with some jQuery, where i have got some problems.
I got this code
if ($(".accordion").length > 0) {
$(".accordion").each(function() {
var item = $(this).find(".accordion-text");
var height = item.outerHeight() + 20;
item.data("height", height + "px").css("height", "0px");
})
}
$(".accordion").on("click", function(e) {
foldOut($(this));
});
function foldOut(accordien) {
console.log(accordien);
var item = $(accordien).find(".accordion-text");
if ($(accordien).hasClass("accordion-open")) {
$(item).stop().transition({
height: '0px'
}, 500, 'in-out');
$(accordien).find(".accordionArrow").removeClass("accordionBgActive");
console.log($(accordien).find(".accordionArrow"));
} else {
$(accordien).find(".accordionArrow").addClass("accordionBgActive");
$(item).stop().transition({
height: item.data("height")
}, 500, 'in-out');
}
$(accordien).toggleClass("accordion-open");
}
But inside the div that is folding out, there may be an a tag, and when i click on the a tag it opens the link but also folds the div..
How can i get the div not to fold when the click is on an a tag?
HTML Where its "closed"
<div class="row">
<div class="overflow-hide rel">
<div class="accordion rel col-md-12 no-pad">
<div class="accordionHeaderDiv">
<h3>Test</h3>
<div class="accordion-header-teaser">
<p>TestTestTestTestTestTestTestTestTestTest</p>
</div>
</div>
<div class="accordion-text" style="height: 0px;">
<p>TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest</p>
<p>Test</p>
</div>
<div class="accordionArrow" style=" position: absolute; top: 0; cursor: pointer; right: 43px; height: 30px;"></div>
</div>
<div class="clearfix"></div>
</div>
</div>
Filter it out regarding event target:
$(".accordion").on("click", function(e) {
if(e.target.tagName.toLowerCase() === "a") return;
foldOut($(this));
});
As anchor can contains other contents, a more relevant way would be:
$(".accordion").on("click", function (e) {
if ($(e.target).closest('a').length) return;
foldOut($(this));
});
I am currently trying to create functionality exactly as displayed in my JSFIDDLE, Basically to hover over a div and then to have a backdrop beneath that div along with a slide down panel also above the backdrop. the only issue is that the functionality is very buggy and barely works in internet explorer.
Here is the JS:
function darken(panelOpen){
if(panelOpen){
if(jQuery('#menu-backdrop').length){
jQuery("#menu-backdrop").stop().fadeIn(300);
}else{
jQuery(document.body).stop().append(jQuery('<div id="menu-backdrop" class="modal-backdrop"></div>').css('opacity',0.7).hide().fadeIn(300));
}
}else{
jQuery(".modal-backdrop").stop().fadeOut(300);
}
} //Backdrop
jQuery(document).ready(function(e) {
var bioId;
jQuery('.personnel').mouseover(function () {
jQuery(this).css('z-index','1050');
darken(true);
bioId = '#personnel-bio-'+this.id.replace( /[^\d.]/g,'');
var bio = '#personnel-bio-'+this.id.replace( /[^\d.]/g,'');
if(jQuery(bio).is(':visible')){
}else{
jQuery(bio).slideDown(300);
}
}); //dropdown function
jQuery(".wrap").mouseleave(function () {
darken(false);
if(jQuery(bioId).is(':visible')){
jQuery(bioId).slideUp(300);
}else{
}
setTimeout(function() {
jQuery('.personnel').css('z-index','0');
}, 300);
}); // slide up function
});
and the CSS:
.personnel {
position:relative;
}
.personnel-bio {
display:none;
padding:1.2em;
position:relative;
z-index:1050;
margin-bottom:15px;
background:#FFF;
}
And then Finally the HTML:
<div class="wrap">
<div id="personnel-1" class="pull-left personnel">
<div class="personnel-inner">
<div class="thumbnail">
<img src="http://placehold.it/330x290"/>
</div>
<div class="thumbnail-title">
<h4>LAbel</h4>
</div>
</div>
</div>
<div class="clearfix"></div>
<div id="personnel-bio-1" class="personnel-bio">
<h5><strong>Pieter Strydom</strong></h5>
<p>loerm ipsum.</p>
</div>
</div>
I am not quiet Sure what I am doing incorrectly. So Any Help at all will be Greatly Appreciated.
I have tidied up the code a bit, removed unnecessary calls to z-index and stop
The modal-backdrop is in the DOM from the beginning now which also helps to speed things up. The initial CSS is set on that with opacity:0.7; and display:none;
Should work a lot more fluid now.
http://jsfiddle.net/hBB97/2/
HTML:
<div id="menu-backdrop" class="modal-backdrop"></div>
<div class="wrap">
<div id="personnel-1" class="pull-left personnel">
<div class="personnel-inner">
<div class="thumbnail">
<img src="http://placehold.it/330x290" />
</div>
<div class="thumbnail-title">
<h4>Label</h4>
</div>
</div>
</div>
<div class="clearfix"></div>
<div id="personnel-bio-1" class="personnel-bio">
<h5><strong>Pieter Strydom</strong></h5>
<p>loerm ipsum.</p>
</div>
</div>
Javascript:
function darken(panelOpen, personnelContainer) {
if (panelOpen) {
personnelContainer.css('z-index', '1050');
jQuery(".modal-backdrop").fadeIn(300);
} else {
jQuery(".modal-backdrop").fadeOut(300);
personnelContainer.css('z-index', '0');
}
} //Backdrop
jQuery(document).ready(function (e) {
var bioId;
jQuery('.personnel').mouseover(function () {
darken(true, $(this));
bioId = '#personnel-bio-' + this.id.replace(/[^\d.]/g, '');
var bio = '#personnel-bio-' + this.id.replace(/[^\d.]/g, '');
if (jQuery(bio).is(':visible')) {} else {
jQuery(bio).slideDown(300);
}
}); //dropdown function
jQuery(".personnel").mouseleave(function () {
darken(false, $(this));
if (jQuery(bioId).is(':visible')) {
jQuery(bioId).slideUp(300);
}
}); // slide up function
});
CSS:
.personnel {
position:relative;
}
.personnel-bio {
display:none;
padding:1.2em;
position:relative;
z-index:1050;
margin-bottom:15px;
background:#FFF;
}
.modal-backdrop {
display:none;
opacity:0.7;
}