I have this working jQuery + inline javascript which causes a conflict with existing jQuery.
<script>
var jq=jQuery.noConflict();
function goto(id, t){
jq(".contentbox-wrapper").animate({"left": -(jq(id).position().left)}, 600);
jq('#slide a').removeClass('active');
jq(t).addClass('active');
}
</script>
<a class="active" href="#" onClick="goto('#kr', this); return false">
<a class="active" href="#" onClick="goto('#en', this); return false">
(I've tried to resolve the conflict as you can see but I believe the conflict arises from the inline javascript.)
How can I convert this inline javascript? Thanks.
You can bind it like:
<script>
//var jq=jQuery.noConflict();
function goto1(id, t){
...
return false; // return false to prevent the link's default action
}
// means once your DOM is ready, and a.active is available to be bound
$(document).ready(function() {
// bind all clicks on a.active to the function 'goto1'
$('a.active').click(goto1);
});
</script>
Variable names like goto can be potential causes of confusion later on. Changed it above to goto1.
Inline JS (embed into HTML) is hardly maintainable, I'd suggest:
HTML:
<div id="parent"> <!-- or any other parent el. -->
Anchor
</div>
jQuery:
(function($){ // remap $ to jQuery
$(function(){ // DOM ready
$('#parent').on('click', 'a', function( ev ){
ev.preventDefault();
var krPos = $('#kr').position().left;
$(".contentbox-wrapper").animate({"left": -krPos }, 600);
$('#slide a').removeClass('active');
$(this).addClass('active');
});
});
})(jQuery);
$('.active').on('click', function() {
var $this = $(this);
var id = $this.attr('href');
$(".contentbox-wrapper").animate({"left": -($(id).position().left)}, 600);
$('#slide a').removeClass('active');
$this.addClass('active');
return false;
});
huangism answered it for me.
https://stackoverflow.com/users/1058134/huangism
Related
So what I want to achieve is just change the classes of a HTML link on every click like this:
Remove .first class if it is present, then add .second class
Remove .second class if it is present, then add .third class
Remove .third class if it is present, then add .fourth class
And so forth...
No luck so far. What could I be doing wrong?
Here's the single line of HTML code where I'm trying my jQuery code on:
<a class="first" href="#">Test 1</a>
Here's my jQuery:
$( "#menu li a.first" ).click(function() {
$( "#menu li a.first" ).removeClass("first").addClass("second");
}
$( "#menu li a.second" ).click(function() {
$( "#menu li a.second" ).removeClass("second").addClass("third");
}
$( "#menu li a.third" ).click(function() {
$( "#menu li a.second" ).removeClass("third").addClass("fourth");
}
Thanks in advance!
The problem is you're trying to attach the event handler before it even has the class second or third.
Besides this approach is pretty verbose. I suggest simply providing an array of classes. Like so:
var classNames = ['first', 'second', 'third'];
Then add a different identifier to the button, for instance add a class class-changer. And attach the following event handler.
$('.class-changer').on('click', function() {
var $el = $(this)
for (var i= 0; i < classNames.length; i++) {
if ($el.hasClass(classNames[i]) && classNames[i+1]) {
$el.removeClass(classNames[i]).addClass(classNames[i+1]);
break;
}
}
});
Put all classes in an array and on click of the link add class one by one like following.
var classes = ["first", "second", "third", "fourth"];
$("#menu li a").click(function () {
var index = classes.indexOf(this.className);
var newIndex = (index + 1) % classes.length; //return to first after reaching last
$(this).removeClass(classes[index]).addClass(classes[newIndex]);
});
.first { color: red; }
.second { color: green; }
.third { color: blue; }
.fourth { color: purple; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
<li>
<a class="first" href="#">Test 1</a>
</li>
</ul>
Assuming you actually only have 1 link whose state you're trying to change, instead of a bunch of links in your menu that you want to ALL be moved from ".first" to ".second" when one is clicked, I would suggest this as the most idiomatic way (pun not intended).
// Only select the menu once
var $menu = $('#menu');
// Delegate to elements with the correct class.
// Specifying the "li a" is probably unnecessary,
// unless you have other elements with the same classes in "#menu".
$menu.on('click', '.first', function(e) {
// Inside a jQuery event handler,
// `this` refers to the element that triggered the event.
// If the event is delegated, it's the delegation target
// (".first" in this instance), not the bound element ("#menu").
$(this).removeClass('first').addClass('second');
});
$menu.on('click', '.second', function(e) {
$(this).removeClass('second').addClass('third');
});
$menu.on('click', '.third', function(e) {
$(this).removeClass('third').addClass('fourth');
});
Resources:
Why should you cache jQuery selectors?
Event Delegation in jQuery
"this" in jQuery events
General jQuery Optimization
You can do it with the usage of .data()
HTML:
<a class="first" href="#" id="test">Test 1</a>
JS:
$(".first").data("classes",["one","two","three","four"]).click(function() {
var elem = $(this);
var cnt = (elem.data("cnt") || 0)
var classes = elem.data("classes");
elem.removeClass().addClass(classes[cnt % classes.length] + " first").data("cnt",++cnt);
});
Demo
$(".first").data("classes",["one","two","three","four"]).click(function() {
var elem = $(this);
var cnt = (elem.data("cnt") || 0)
var classes = elem.data("classes");
elem.removeClass().addClass(classes[cnt % classes.length] + " first").data("cnt",++cnt);
});
.one{
color:red;
}
.two{
color:yellow;
}
.three{
color:green;
}
.four{
color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<a class="first" href="#" id="test">Test 1</a>
Not sure if this would solve your issue but I would shoot for a conditional statement and only one delegated event listener:
$("#menu li").on("click", "a", function () {
if ($(this).hasClass("first")) {
$(this).removeClass("first").addClass("second");
} else if ($(this).hasClass("second")) {
$(this).removeClass("second").addClass("third");
}
// etc...
});
If you want to bind an event the selected element must exist previously.
To bind an event handler to elements that does not yet exist (ex. dynamically created or modified) you can do this:
$(document).on('click', '#menu li a.first', function() {
$( "#menu li a.first" ).removeClass("first").addClass("second");
});
$(document).on('click', '#menu li a.second', function() {
$( "#menu li a.second" ).removeClass("second").addClass("third");
});
$(document).on('click', '#menu li a.third', function() {
$( "#menu li a.third" ).removeClass("third").addClass("fourth");
});
<a class="changable first" href="#">Test 1</a>
$( ".changable" ).click(function(event) {
classes = ['first','second','third','fourth']
changed=false
for (c in classes){
if (event.target.classList.contains(classes[c]) && changed==false){
$(this).removeClass((classes[c]));
index_to_add=classes.indexOf(classes[c])+1
class_to_add=classes[index_to_add]
$(this).addClass(class_to_add);
changed=true;
}
}
});
Okay so there is a few workaround for this, which wasn't mentioned yet.
You can use Javascript object for this not just array. Object could make it easier if you want a chain instead of list.
var classNames = {first:'second', second:'third', third:'fourth'};
$('#menu li a').on('click', function() {
if(typeof classNames[this.className] !== 'undefined'){
this.className = classNames[this.className];
}
});
Second method is to use .on('click', [selector], handler) instead click which can handle dynamicly loaded, added or changed elements.
$('#menu li').on('click', 'a.first', function() {
$(this).removeClass("first").addClass("second");
});
$('#menu li').on('click', 'a.second', function() {
$(this).removeClass("second").addClass("third");
});
$('#menu li').on('click', 'a.third', function() {
$(this).removeClass("third").addClass("fourth");
});
Not even close to perfect but still a working solution.
You can use if .. else or switch .. case inside a function to create a decision tree.
So basically there is a lot of solution. Pick the best.
Try binding event to parent,
My try,
var $classes = ['first', 'second', 'third'];
$(function(){
$('#subject').click(function(){
current = $(this).find('a:first');
index = $.inArray(current.attr('class'), $classes);
if($classes.length > index+1)
current.removeClass($classes[index]).addClass($classes[index+1])
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='subject'>
<a class="first" href="#">Test 1</a>
</div>
No, you can't. As JavaScript only runs after the page loads ( if you put them inside the $( document ).ready() function ), further functions down below will never be executed. It can only detect the <a class="first" href="#">Test 1</a> but not the <a class="second" href="#">Test 1</a> because the <a class="second" href="#">Test 1</a> are generated after the page loads and, therefore, will never be executed, unless you are using Ajax.
Update: This can be done. Please see #i3b13's comment below.
I want to attach an onclick event to a, but cannot seem to achieve it with this:
$("[class^=field-promote_image_]").each(function() {
var a = $(this).find('.file-upload > a');
a.on('click', function(e){
e.preventDefault();
alert(a.attr('href'));
});
});
nor with this:
$("[class^=field-promote_image_] .file-upload > a").on('click', function(e) {
e.preventDefault();
alert($(this).attr('href'));
});
what am I missing?
Use attribute contains selector.
$('.field-row[class*="field-promote_image_"] .file-upload > a').on('click', , function() {
Warning: This will match all the elements whose class contains field-promote_image_. Ex. anything-field-promote_image_
I assume the class field-promote_image_de is dynamic that is why you are going for the attribute starts with selector, but it won't work because that is not the starting of the attribute value.
A right approach here will be is to add an additional class to that element like
<div class="form-row field-promote_image field-promote_image_de">
...
</div>
then just use the new class
$('.field-promote_image a').click(function(){
//your handler code
})
You can use this:
$(".file-upload > a").on('click', function(e) {
e.preventDefault();
alert($(this).attr('href'));
});
This question already has answers here:
Events triggered by dynamically generated element are not captured by event handler
(5 answers)
Closed 8 years ago.
doing a accordion, structure is as follows, few divs are coming dynamically, not working.
parent div
<div id="resultarea" class="accordion">
</div>
Inside the parent tag the following tags are coming dynamically.
<div class="accordion-item">
Item 1
<div class="type"></div>
</div>
<div class="data">
my data related to item 1
</div>
<div class="accordion-item">
Item 2
<div class="type"></div>
</div>
<div class="data">
my data related to item 2
</div>
Below is the javascript
$(function($) {
var allAccordions = $('.accordion div.data');
var allAccordionItems = $('.accordion .accordion-item');
$('.accordion > .accordion-item').click(function() {
if($(this).hasClass('open'))
{
$(this).removeClass('open');
$(this).next().slideUp("slow");
}
else
{
allAccordions.slideUp("slow");
allAccordionItems.removeClass('open');
$(this).addClass('open');
$(this).next().slideDown("slow");
return false;
}
});
});
but its not working when the items data is coming dynamically, if static page it is working. please help me to solve this
static one is in jsfiddle find below
http://jsfiddle.net/ea6xX/
Try to use event-delegation on dynamically created elements,
$('.accordion').on('click','.accordion > .accordion-item',function() {
Full code:
$('.accordion').on('click','.accordion > .accordion-item',function() {
if($(this).hasClass('open'))
{
$(this).removeClass('open');
$(this).next().slideUp("slow");
}
else
{
allAccordions.slideUp("slow");
allAccordionItems.removeClass('open');
$(this).addClass('open');
$(this).next().slideDown("slow");
return false;
}
});
Use event delegation - .on() : it binds events to object existing or those which will be added later.
$(document).on('click','.accordion > .accordion-item',function() {
if($(this).hasClass('open'))
{
$(this).removeClass('open');
$(this).next().slideUp("slow");
}
else
{
allAccordions.slideUp("slow");
allAccordionItems.removeClass('open');
$(this).addClass('open');
$(this).next().slideDown("slow");
return false;
}
});
- You need to include jQuery reference in your fiddle.
Because the elements are being appended to the page after DOMReady has fired you need to use a delegated event handler using on(). Try this:
$('#resultarea').on('click', '> .accordion-item', function() {
var allAccordions = $('.accordion div.data');
var allAccordionItems = $('.accordion .accordion-item');
if ($(this).hasClass('open')) {
// your code...
}
});
Note that your variable declarations must go inside the click handler, as on page load the items being selected will not exist.
$(document).on('click', '.accordion .accordion-item', function(e) {
if($(this).hasClass('open'))
{
$(this).removeClass('open');
$(this).next().slideUp("slow");
}
else
{
allAccordions.slideUp("slow");
allAccordionItems.removeClass('open');
$(this).addClass('open');
$(this).next().slideDown("slow");
return false;
}
});
Demo:
http://jsfiddle.net/ea6xX/4/
Use .on as this binds event handler to the selected elements.
For more information click here.
$(function($) {
var allAccordions = $('.accordion div.data');
var allAccordionItems = $('.accordion .accordion-item');
$('.accordion').on("click",".accordion-item",function() {
if($(this).hasClass('open'))
{
$(this).removeClass('open');
$(this).next().slideUp("slow");
}
else
{
allAccordions.slideUp("slow");
allAccordionItems.removeClass('open');
$(this).addClass('open');
$(this).next().slideDown("slow");
return false;
}
});
});
Working JSFiddle
First of all you have to include jQuery in your jsFiddle example. As for dynamic data, you could try to use jQuery on for click event binding.
$('.accordion > .accordion-item').on('click', function() {
...
});
Fixed jsFiddle example
I have a code
var prev;
function addClass( classname, element ) {
prev = cn;
var cn = document.getElementById(element);
$(cn).addClass("selected");
}
The element in the dom look like this:
<div class="arrowgreen">
<ul>
<li>Manager</li>
<li>Planner</li>
<li>Administrator</li>
</ul>
</div>
For 'arrowgreen' I have a styling which changes the li styling on rollover and click.
When an element is clicked on, I want to apply the 'selected' classname to the element.
It does this for a split second and then reverts back.
The css looks like
.arrowgreen li a.selected{
color: #26370A;
background-position: 100% -64px;
}
Working jsFiddle Demo
In usage of $ in your code, I see that you are using jQuery.
There is no need to set onclick internally.
Let's jQuery handle it for you:
// wait for dom ready
$(function () {
// when user clicks on elements
$('.arrowgreen li a').on('click', function (e) {
// prevent default the behaviour of link
e.preventDefault();
// remove old `selected` classes from elements
$('.arrowgreen li a').removeClass('selected');
// add class `selected` to current element
$(this).addClass('selected');
});
});
Working JSFiddle
There was an error in your HTML, a " that opened a new string after onclick.
var prev;
function addClass(classname, element) {
var cn = document.getElementById(element);
prev = cn; //does nothing useful really
$(cn).addClass("selected");
}
<div class="arrowgreen">
<ul>
<li>Manager
</li>
<li>Planner
</li>
<li>Administrator
</li>
</ul>
</div>
Remember to include jQuery in your page!
There is a way to do this without jQuery anyway:
function addClass(classname, element) {
var cn = document.getElementById(element);
prev = cn; //does nothing useful really
cn.className += " " + classname;
}
Similar way to do it:
(function ($) {
$('.arrowgreen > ul > li > a').on('click', function (e) {
e.preventDefault();
$(this).addClass('selected').siblings().removeClass('selected');
});
}(jQuery));
Im trying to grab the "title" on the <li> when it is clicked. It keeps returning undefined.
html
<div id="sidebar">
<div class="navigation">
<ul>
<li title="../../000_Movies/_assets/playlist.html">فیلم ها</li>
</ul>
</div>
</div>
js
$('.navigation li').click(function () {
$('.slider').animate({
marginLeft: 0
}, 500,function() {
var test = $(this).attr('title');
alert(test);
location.href = '';
});
});
This doesn't work?
$('li').click(function(){
alert($(this).attr('title'));
});
"this" maybe is not the li. Or the browser have a bug (IE?). Your code seems correct to me.
You should create a closure on the clicked li element. You're getting this inside another function in the click handler function, so the definition of this will be different than the original function.
$('.navigation li').click(function () {
// cache the element here
var that = $(this);
$('.slider').animate({
marginLeft: 0
}, 500, function() {
// then access that instead here
// (we're creating a closure on the that variable)
var test = that.attr('title');
alert(test);
location.href = '';
});
});
If you have two nested functions, their this variables will be different:
function foo () {
// this here ...
function bar () {
// ... is different from this here
}
}
So building on that...
$('li').click(function () {
// $(this) here ...
$('something').slider({},100, function () {
// ... is different from $(this) here
});
});
$("li").on('click',function () {alert($(this).attr('title');)});
How are you attaching the click handler on the li element? Are you sure this inside the handler is poiting to li element.
I would try to log this and find out what it points to.
If this points to li then $(this).attr('title') should work perfectly fine.
I'm guessing it would be:
$("li.clickMe").click(function () {
$("this").attr("title").whateverYouNeedToDo("");
});