All,
I am really stuck/ confused at this point.
I have an array with 6 items in it. Each item in the array is dynamically filled with elements using jquery '.html' method. However, I cannot seem to be able to attach/ bind an event to this dynamically created variable.
As soon as the browser gets to the problem line (see the area labeled 'PROBLEM AREA'), I get a 'undefined' error, which is really confusing as all the previous code on the very same variable works just fine.
var eCreditSystem = document.getElementById("creditSystem");
var i = 0;
var eCreditT = new Array(6); // 6 members created which will be recycled
function createCreditTransaction () // func called when a transaction occurs, at the mo, attached to onclick()
{
if (i < 6)
{
eCreditT[i] = undefined; // to delete the existing data in the index of array
addElements (i);
} else
if (i > 5 || eCreditT[i] != undefined)
{
...
}
}
function addElements (arrayIndex) // func called from within the 'createCreditTransaction()' func
{
eCreditT[i] = $(document.createElement('div')).addClass("cCreditTransaction").appendTo(eCreditSystem);
$(eCreditT[i]).attr ('id', ('trans' + i));
$(eCreditT[i]).html ('<div class="cCreditContainer"><span class="cCreditsNo">-50</span> <img class="cCurrency" src="" alt="" /></div><span class="cCloseMsg">Click box to close.</span><div class="dots"></div><div class="dots"></div><div class="dots"></div>');
creditTransactionSlideOut (eCreditT[i], 666); // calling slideOut animation
console.log(eCreditT[i]); // this confirms that the variable is not undefined
/* ***** THE PROBLEM AREA ***** */
$(eCreditT[i]).on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn (eCreditT[i], 150); // slide back in animation
});
return i++;
}
Try this:
$(eCreditT[i]).bind('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
Edit: use ++i instead of i++ like this:
return ++i;
/*
or
i += 1;
return i;
*/
retrurn ++i performs the increment first then return i after the increment.
While return i++ return i then icrement it.
Try to add click event out of addElements() function and try once.
Nonsense create an element using JavaScript and then use jQuery function to transform it into a jQuery object. You can let jQuery create the element directly for you.
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
Also, since eCretitT[i] is already a jQuery element, no need to call the jQuery function again.
eCreditT[i].on('click', function () {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
If you already tried on, bind, live and click methods, then maybe the called function is your problem. Try to put a console.log() or an alert() inside the function to make sure the click event is actually happening. If it happens then the function creditTransactionSlideBackIn() is your problem.
EDIT
The problem is when the event takes place, i is not the original variable anymore.
function addElements (arrayIndex)
{
eCreditT[i] = $('<div>').addClass("cCreditTransaction").appendTo(eCreditSystem);
eCreditT[i].attr ('id', ('trans' + i));
eCreditT[i].data ('id', i); // Store the id value to a data attribute
Then when you call the function you can refer to the data attribute instead of the i variable:
/* ***** THE PROBLEM AREA ***** */
eCreditT[i].on ('click', function () // if user clicks on the transaction box
{
creditTransactionSlideBackIn ($(this).data('id'), 150); // slide back in animation
});
return i++;
}
try to bind parent div and then use if($e.target).is('some')){}, it will act as .live, like this:
$(eCreditSystem).bind('click', function (e){
if($(e.target).is('.cCreditTransaction')) {
creditTransactionSlideBackIn ($(e.target), 150);
}
});
of course you'll need in a minute larger if for checking if clicked dom el is a child of .cCreditTransaction, like this:
if($(e.target).parents().is('.cCreditTransaction')){}
Try this:
$(eCreditT[i]).live('click', function() {
creditTransactionSlideBackIn(eCreditT[i], 150);
});
Related
I have a few links. When I hover mouse over the links I would like to get the values stored in data attributes. I need to pick the t values and pass them into function
HTML
<a href="#" data-lat="23.333452" data-lon="-97.2234234">
JS
var loc = document.querySelectorAll("a[data-lat]");
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
function locOver() {
// do something
}
function locOut() {
// do something else
}
It's been a while since I used vanilla JS and it's been a long day so I'm sure it's pretty close but I'm stuck. I keep getting:
Uncaught TypeError: loc.addEventListener is not a function
What am I missing here?
You need to loop through the nodes that you obtained with document.querySelectorAll("a[data-lat]") for adding events.
Working example.
Node
<script>
var loc = document.querySelectorAll("a[data-lat]");
loc.forEach(node => {
node.addEventListener("mouseover", locOver);
node.addEventListener("mouseout", locOut);
})
function locOver(event) {
// do something
console.log('mouseover', event.target.dataset)
}
function locOut() {
// do something
console.log('locOut')
}
</script>
const loc = document.querySelector("a[data-lat]");
const locOver = () => {
console.log("Mouse is over the link");
}
const locOut = () => {
console.log("Mouse is out of the link");
}
loc.addEventListener("mouseover", locOver);
loc.addEventListener("mouseout", locOut);
Link
Explanation:
I target the link using .querySelector method that returns a single node.
After that i created two event handler for mouseOver and mouseOut and than i added the eventListener to the link.
I have this Jquery function to click on an element when its ready. its an interval doing it , the following function:
MonitorAndClick(selector) {
var ele = $(selector);
if (ele.length == 0) {
var intervalid = setInterval(function () {
var ele = $(selector);
if (ele.length > 0) {
ele[0].click();
clearInterval(intervalid);
return true;
}
}, 500);
} else {
ele[0].click();
return true;
}
}
the problem is in some cases , its not working. however this is an interval , and it's checking the element to be ready every 0.5 sec, so how can it be possible ? is there any other way to check the element is ready ?
additional note:
I have an accordion. I have a function to open the accordion->open one of the items->open the tab page in detail section
this is the function :
//--reach to this point, open accordion index 2--------
ShowAccordion(2);
//----open the item with specific Id in accordion items------
setTimeout(function () {
var selector = "tr[gacategory = '/myprotection/mywills/item_" + parseInt(willId) + "]";
MonitorAndClick(selector);
}, 500);
the point is this element SHOULD be there , sometimes its not loading fast enough , and I WANT TO HAVE A WAY TO CHECK IF ITS LOADED, THEN CLICK ON THAT.
Updated code after comments
var selector = "tr[gacategory = '/myprotection/mywills/item_" + parseInt(willId) + "]";
$("#selector").ready(function () {
console.log('**********.... selector is loaded ....*****');
if (!$("#selector").hasClass('selected'))
MonitorAndClick(selector);
});
still not working.
Why do you want to rely on 0.5 seconds delay to make sure your element is present in DOM. You should be invoking this function only after your element is present in the DOM. If there is another condition that drives when this element is added to the DOM, then call this function once that condition is achieved.
You may want to try https://api.jquery.com/ready/
It seems like jquery ready function can be applied on individual elements too
I am using the combination of a data attribute and class name to fire a function to modify the content of the element with the particular class name.
Below function fires at $(document).ready
$('.accessControlled').each(function(){
var accessLevel = parseInt($(this).attr("data-accesslevel"));
if((user.role !== 0) && (accessLevel !== role)){
$(this).remove();
} else {
$(this).removeAttr('data-accesslevel');
$(this).removeClass('accessControlled');
}
});
Now I want to fire this function, on elements returned by ajax calls too.
I know I can bind the functions permanently by jquery on(), live(), delegate(), etc, but which event to use and how to go about it?
Just execute the code above against returned code:
eg:
function doit(obj){
$(obj).each( // rest of your function
}
// ...
$.get(...).done(function(data){
var obj = $(data);
doit(obj);
// rest of your injection
}
Try this:
// obviously user.role and role must be defined for this to work
function access(){
$('.accessControlled').each(function(){
var accessLevel = parseInt($(this).attr("data-accesslevel"));
if((user.role !== 0) && (accessLevel !== role)){
$(this).remove();
}
else{
$(this).removeAttr('data-accesslevel');
$(this).removeClass('accessControlled');
}
});
}
// assign each ajax call to a variable
var ajx1 = $.post({/*object stuff here*/});
// put the ajax variables in an Array
var ajxA = [ajx1, ajx2, ajx3, ajx4, ajx5, ajx6, ajx7];
$.each(ajxA, function(i, v){
v.done(access);
});
There is a function ajaxSuccess in jQuery which can be used to do something after all ajax calls.
$(document).ajaxSuccess(function() {
accessControl.checkAccessControl();
});
I am trying to make a mouse roll-over. i.e when user places the pointer on the image mouse over event is triggered and the next image from the array comes over.But nothing is happening when i am running this script :
window.onload = startRollOver;
var pictures = new Array("1.jpg","2.jpg","3.jpg","4.jpg","5.jpg","6.jpg","7.jpg","8.jpg");
var i = 0;
function startRollOver() {
document.getElementById("picture").src.onmouseover = createRollOver();
}
function createRollOver() {
if(i<=7)
return pictures[i++];
if(i>7) {
i=0;
return pictures[i];
}
}
Where am i going wrong ?
.src.onmouseover does not make much sense. You should assign a function to onmouseover so that the function gets called when the mouse moves over the element:
document.getElementById("picture").onmouseover = function() { // is executed when mouse is over element
this.src = createRollOver(); // each time it is called, change the src
};
Also, you can use a more convenient way of declaring arrays:
["1.jpg", "2.jpg", ...]
You're setting "onmouseover" on the string "src" instead of on the DOM element. You need to set the event on the DOM element.
window.onload=startRollOver;
function startRollOver() {
document.getElementById("picture").onmouseover = function (e) {
e.target.src = createRollOver();
};
}
function createRollOver() {
// ...
}
The script below adds items to an array when you click the link, and generates a list of items as html output. You can see an example here: http://jsfiddle.net/dqFpr/
I am trying to create a function to delete items from the list. Not a difficult task with splice(), but somehow clicking the delete link doesn't trigger the test_function() function.
Can someone tell me what I am doing wrong, or show me another way of triggering the function? Your help is really appreciated ;-)
<script language="javascript">
$(document).ready(function() {
function test_function( number ) {
/* This function is not triggered, nothing works inside here!! */
}
});
var lines = [];
function update_list( lines ) {
var thecode = '';
for(var i = 0; i < lines.length; i++) {
thecode = thecode + lines[i] + ' <a onclick="javascript:test_function('+i+')" href="#">(delete)</a><br />';
}
$('div#display').html(thecode);
}
$('a#new').click(function() {
lines.push('another line');
update_list(lines);
});
</script>
<div id="display"></div>
Add a new line
Because in the text assigned to display's innerHTML, *test_function* is just plain text that is evaluated by the HTML parser. At that point, its scope is global, not within the IIFE passed to $(document).ready(). You can fix that by making the function global:
$(document).ready(function(){
window.test_function = function (number) {
// do stuff
}
....
});
or
var test_function;
$(document).ready(function(){
test_function = function (number) {
// do stuff
}
....
});
Or whatever method you like to get access to the function. But while it is declared inside an anonymous function's scope, you can only get access to it from a function that has a closure to the variables in that scope.