Can I reference a click event on a variable? - javascript

The assignment is to create a click event that will cause the headers to slide up, I am trying to accomplish this task with only one click event reference however this will only work on the first header. Is there a was to accomplish this with out multiple click events?
<h1 id="h1">Heading-1</h1>
<h2 id="h2">Heading-2</h2>
<h3 id="h3">Heading-3</h3>
<div id = "result"></div>
<script src="jquery.js"></script>
<script>
var i= 1;
$("h" + i).bind('click', function () {
var thisID = '#h' + i;
$(thisID).slideUp("slow");
i++;
});

Try to use class instead of ID. Something like
<h1 id="h1" class="sliderHeading">Heading-1</h1>
<h2 id="h2" class="sliderHeading">Heading-2</h2>
<h3 id="h3" class="sliderHeading">Heading-3</h3>
If you need only header that was clicked on to slide up:
$(".sliderHeading").bind('click', function () {
var thisID = $(this).attr('id');
$(thisID).slideUp("slow");
});
If you need all headers to slideup on one click:
$(".sliderHeading").bind('click', function () {
$(".sliderHeading").slideUp("slow");
});

You could try adding a class to all of them and use that in your script.

Try to do it inside the loop, if the number of headers (id) is known.
for (var i=1; i<=3; i++) {
$("h" + i).bind('click', function () {
var thisID = '#h' + i;
$(thisID).slideUp("slow");
});
}

Related

How to prevent click event on second times on a button

I have few buttons, when I click on those buttons some divs are creating automatically, but here I need to prevent to create any div when I click on next time on the same button on which I already clicked.
Code is below
HTML
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="details">
<button id="append">button1</button>
<button id="append">button2</button>
<button id="append">button3</button>
<div id="parent"></div>
</div>
SCRIPT
(function(){
var count = 0;
$('button').click(function(){
$('#parent').append('<div id="first'+count+'">text</div>');
count++;
});
});
Use the .one() method. This binds a handler that only runs once for each element.
$(function() {
var count = 0;
$('button').one("click", function() {
$('#parent').append('<div id="first' + count + '">text</div>');
count++;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="details">
<button id="append">button1</button> <button id="append">button2</button> <button id="append">button3</button>
<div id="parent"></div>
</div>
Basic idea is creating click flag.
Flag is set to true once clicked and set to false if action is finished.
The action should be performed only if flag is false.
Like this:
(function(){
var count = 0;
var flag = false;
$('button').click(function(){
if(flag) return false; // Disable when action is on
// Action starts
flag = true;
$('#parent').append('<div id="first'+count+'">text</div>');
count++;
// Action ends
flag = false;
});
});
Here are three possible solutions:
Disable the button that was clicked by adding $(this).attr('disabled',true); inside anonymous click function.
Adding a data-enabled attribute to the buttons and checking it. Your HTML for a button becomes like this: <button id="append" data-enabled="true">button1</button> and then you add this to the anonymous click function:
(function(){
var count = 0;
$('button').click(function(){
if ( $(this).data('enabled') == 'false' ) return;
else
{
$(this).data('enabled', 'false');
$('#parent').append('<div id="first'+count+'">text</div>');
count++;
}
});
});
Create an array that with the button as keys and their enabled/disabled boolean value as their value and refer to that in the anonymous click function.
1- Your code needs a $ in first of your js to calling it after document.ready: $(function(){...}), or adding () at end of it for calling Immediately ((function(){...})();).
2- You can use off to remove a listener from an element.
other things is ok in your code. please look at result:
$(function(){
var count = 0;
$('button').click(function(){
$('#parent').append('<div id="first'+count+'">text</div>');
count++;
$(this).off("click");//One of benefits of this way is: you can add some conditions for removing this event. > if(...) $(this).off("click");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="details">
<button id="append">button1</button> <button id="append">button2</button> <button id="append">button3</button>
<div id="parent"></div>
</div>
Just unbind it after first click.
$(function(){
var count = 0;
$('button').click(function(){
count = Number($(this).data('click')||0);
if(count>0){
$(this).unbind("click");
}
count = count+1;
$(this).data('click',count);
$('#parent').append('<div id="first'+count+'">text</div>');
});
});

Read id with jquery and apply action to corresponding div

I want a certain button to show a certain div. Now I need to update my javascript for every new button & div. As this will be connected to a cms, for every post it needs to work automatically. How can I read the id/class from the button dynamically to apply an action to the corresponding div?
Way of thinking:
button_xxx opens div with id xxx
button_xxx_close closes it
Here's the html:
Button 001
Button 002
...
Button 099
<div id="001">
<p>CLOSE</p>
<p>Content</p>
</div>
<div id="002">
<p>CLOSE</p>
<p>Content</p>
</div>
<div id="099">
<p>CLOSE</p>
<p>Content</p>
</div>
And the javascript:
$(document).ready(function() {
// SHOWS DIV
$('#button_001').on('click', function(){
$('#001').removeClass('movedown');
$('#001').addClass('moveup');
});
$('#button_002').on('click', function(){
$('#002').removeClass('movedown');
$('#002').addClass('moveup');
});
$('#button_099').on('click', function(){
$('#099').removeClass('movedown');
$('#099').addClass('moveup');
});
// HIDES DIV
$('.button_001_close').on('click', function(){
$('#001').removeClass('moveup');
$('#001').addClass('movedown');
});
$('.button_002_close').on('click', function(){
$('#002').removeClass('moveup');
$('#002').addClass('movedown');
});
$('.button_099_close').on('click', function(){
$('#099').removeClass('moveup');
$('#099').addClass('movedown');
});
});
You can reduce your code using startswith attribute selector in jquery
$("a[id^=button_]").click(function () {
var id = this.id.split("_")[1];
$("#" + id).removeClass("movedown").addClass("mouseup");
});
$('[class^=button_]').on('click', function () {
var id = $(this).attr("class").split("_")[1];
$("#" + id).removeClass("mouseup").addClass("movedown");
});
First snippet will select all anchor elemets with id starts with button_ and bind click event to them.
Second snippet will select all elemets with class starts with button_ and bind click event to them.
Note
If your elements are created dynamically, use the below code
$(document).on("click", "a[id^=button_]", function () {
var id = this.id.split("_")[1];
$("#" + id).removeClass("movedown").addClass("mouseup");
});
$(document).on('click', '[class^=button_]', function () {
var id = $(this).attr("class").split("_")[1];
$("#" + id).removeClass("mouseup").addClass("movedown");
});
Edit
$('[class^=button_]').on('click', function () {
// var id = this.id.split("_")[1]; <-- changedd this line
var id = $(this).attr("class").split("_")[1];
$("#" + id).removeClass("mouseup").addClass("movedown");
});
I changed the line, Because that element doesnt have id. So you should pick the classname instead.
You can use $(this).attr("class") to get the current element's class name. Then split the classname to extract the div id
Simply with toggleClass
$("a[id^=button_] , [class^=button_]").click(function () {
var id = this.id.split("_")[1];
$("#" + id).toggleClass("movedown mouseup");
});
Try with this:
$(document).ready(function() {
// SHOWS DIV
var elem = '';
$('a[id*="button_"]').on('click', function(){
elem = this.id.split('_')[1];
$('#'+elem).toggleClass('movedown moveup');
});
// HIDES DIV
$('.button_'+elem+'_close').on('click', function(){
$('#'+elem).toggleClass('movedown moveup');
});
});
You could do this without the need for regular expressions with a small change to your html
Button 001
<div id="001">
<p>CLOSE</p>
<p>Content</p>
</div>
and then add click handlers for both
$('.button_open_div').on('click', function(ev){
$('#'+$(this).data('divid')).removeClass('movedown').addClass('moveup');
});
$('.button_close_div').on('click', function(){
$('#'+$(this).data('divid')).removeClass('moveup').addClass('movedown');
});
or a toggle function
$('.button_open_div, .button_close_div').on('click', function(ev){
$('#'+$(this).data('divid')).toggleClass('movedown moveup');
});
example: http://jsfiddle.net/XXE2R/

How to add class with data-attribute?

I am working on some data buttons but can't figure out how to get the function working. I'm trying to add a class to an element via a data-attribute and a corresponding ID. I then want to stop the event propagation with the button inside the subject.
So far this is what I have:
HTML:
<div class ="subject" id="subject1">
<button class="remove">Remove</button>
The Subject
</div>
<div class ="subject" id="subject2">
<button class="remove">Remove</button>
The Subject 2
</div>
<div class ="subject" id="subject3">
<button class="remove">Remove</button>
The Subject
</div>
<button class="trigger" data-subject="subject1">Trigger</button>
<button class="trigger" data-subject="subject2">Trigger</button>
<button class="trigger" data-subject="subject3">Trigger</button>
CSS:
.active {
color:red
}
JS:
var subject = document.querySelector('.subject');
var trigger = document.querySelector('.trigger');
var remove = subject.querySelector('.close');
var data = trigger.getAttribute("data-subject");
var datajs = (function () {
function init() {
[].forEach.call(trigger),function(btn) {
btn.onclick = function() {this.classList.add("active");}
});
remove.addEventListener('click', function (ev) {
ev.stopPropagation();
removeModalHandler();
});
});
}
init();
})();
and here's a fiddle: http://jsfiddle.net/tNS62/1/
My JS isn't that great as you can probably see.
Try this. First we select all the buttons :
var triggers = document.querySelectorAll('.trigger');
var removes = document.querySelectorAll('.remove');
Then we apply the behavior on each button :
for (var i =0; i < triggers.length; i++) {
var btn = triggers[i];
btn.addEventListener('click', function () {
var id = this.dataset.subject;
document.querySelector('#' + id).classList.toggle('active');
}, false);
}
Use dataset to get the id attached to, then search the corresponding element in order to toogle the active class.
I made the same thing for the remove buttons.

Unable to attach event listeners to dynamically created elements in IE8

OVERVIEW:
When I click a button i want to
insert a new row at the end of a table
copy the cells and contents from the first row of the table
give unique ids to the elements within the cells
assign a focus event listener to all inputs in the page.
PROBLEM:
The event handlers are not firing on the correct elements in IE8. For example if I focus on the last input in the table, the first input gets highlighted.
CLARIFICATION:
This works in IE10, Chrome.
Does not work in IE8 which is my target browser.
I know of ways
to get around this.My aim is NOT to find a workaround but to
understand what my mistake is, in the given code.
The example code is just a quick simplified version of the problem. I am not asking for code optimization thats not relevant to the question.
Change event does not work too.
CODE:
HTML:
<table width="200" border="1" id="myTable">
<tr>
<td>
<input type='text' id='row0col0' name='row0col0'>
</td>
</tr>
</table>
<button id="addRow">Add Row</button>
JS:
function addFocusListener() {
$("input").unbind();
$("input").each(function () {
var $this = $(this);
$this.focus(function () {
var newThis = $(this);
newThis.css('background-color', 'red');
});
});
}
function addRowWithIncrementedIDs() {
var table = document.getElementById("myTable");
var newRow = table.insertRow(-1);
var row = table.rows[0];
var rowNum = newRow.rowIndex;
for (var d = 0; d < row.cells.length; d++) {
var oldCell = row.cells[d];
newCell = oldCell.cloneNode(true);
newRow.appendChild(newCell);
for (var c = 0; c < newCell.childNodes.length; c++) {
var currElement = newCell.childNodes[c];
var id = "row" + rowNum + "col" + d;
$(currElement).attr('name', id);
$(currElement).attr('id', id);
}
}
}
$(document).ready(function () {
$("#addRow").click(function () {
addRowWithIncrementedIDs();
addFocusListener();
});
});
OTHER APPROACHES THAT WORK:
changing from jQuery binding to regular JS binding. I.e from
$this.focus(function () {....});
to
this.onfocus =function () {....};
Attaching the event handler as they are rendered.
FIDDLE:
http://jsfiddle.net/sajjansarkar/GJvvu/
RELATED LINKS IN SO:
jQuery event listener doesn't work in IE 7/8
EDIT
Sorry, I just noticed your comment that you want to understand the error in your code.
I can quickly tell you one error, and that is mixing jQuery and native DOM methods. If you have dedicated yourself to using a very powerful library, then use all of it's features, not just the ones you understand.
The below code uses event delegation (to fix your focusing problem) and jQuery methods to more simply add a row to the table than with native methods.
If you're going to use jQuery, then you might as well use it all the way:
var t = $('#myTable');
$(document)
.on('focus','#myTable input',function() {
$(this).css('background','red')
})
.on('click','#addRow',function() {
//create a new row
var
newIndex,
r = t.find('tr').eq(0).clone();
//append it to the table
r.appendTo(t);
//update newIndex - use it for later
newIndex = r.index();
//update the name/id of each of the inputs in the new row
r.find('input').each(function() {
var
el = $(this),
id = 'row'+newIndex+'col'+el.closest('td').index();
el.attr('id',id).attr('name',name);
});
});
http://jsfiddle.net/GJvvu/1/
You don't need to loop through your inputs and bind a focus handler to each of them, jQuery automatically collects all DOM elements that match the selector and performs it's focus API function on each of them:
Change this:
function addFocusListener() {
$("input").unbind();
$("input").each(function () {
var $this = $(this);
$this.focus(function () {
var newThis = $(this);
newThis.css('background-color', 'red');
});
});
}
To this
function addFocusListener() {
$('input')
.unbind()
.focus(function(){
$(this).css('background-color','red');
});
}
$("#addRow").live("click", function(){
addRowWithIncrementedIDs();
addFocusListener();
});
Try out above code... this should work..

Jquery: trying to hide and show on hover on multiple divs with same id plus number

Trying to get a div that looks like <a id="thumblink-10"> to show and hide another div on hover, but no luck.
jQuery(document).ready(function() {
jQuery(document).find("a[id^='thumblink-']").live('hover', function(){
var num = this.id.split('-')[1];
jQuery('#thumb-hover-' + num).show();
}, function(){
//var num = this.id.split('-')[1];
jQuery('#thumb-hover-' + this.num).hide();
});
});
Thanks
This should work for you:
jQuery("a[id^='thumblink-']").live('hover', function(){
var num = this.id.split('-')[1];
jQuery('#thumb-hover-' + num).toggle();
});
Fixed the initial selector to not use find, only need to supply and single function for the hover and use the toggle function to show/hide the content.
http://jsfiddle.net/Zy2Ny/
But the way I would actually do it is to add data attributes to your links (can then change the selector to a class one instead) and use those to find the correct div to toggle like this:
JS
jQuery("a.thumblink").live('hover', function(){
var num = $(this).data('contentid');
jQuery('#thumb-hover-' + num).toggle();
});
HTML
<a class="thumblink" data-contentid="10">Hover</a>
<div id="thumb-hover-10" style="display: none;">Content</div>
http://jsfiddle.net/Zy2Ny/1/
You can't really do traversal methods like find and then use live. You should just use a standard selection. Also, you can't use live with hover and give two functions.
$("a[id^='thumblink-']").live('hover', function(){ // simple selector
Better still would be to use delegate and a map of events and handlers:
$(document).delegate('a[id^="thumblink-"]', {
mouseenter: function() {
},
mouseleave: function() {
}
});
I haven't been able to test it unfortunately, but I believe the following should work:
var id = 10;
$('#thumblink-' + id).hover(function(id) {
return function () {
$('#thumb-hover-' + id).show();
};
}(id),
function(id) {
return function () {
$('#thumb-hover-' + id).hide();
};
}(id)
);

Categories