How do I check if a jQuery object exists in the DOM? - javascript

I want to check if a jQuery object exists in the DOM (with Internet Explorer). I tried this code:
observeEditor = function(editor) {
function update_position() {
console.log("update_position");
var $editor = jQuery(editor);
if (jQuery(document).find($editor).length > 0) {
// call our function
setTimeout(update_position, 250);
}
}
setTimeout(update_position, 250);
};
But the problem is that even after I close the editor (it doesn't exist in the DOM), I still get this console.log every 250 ms. How do I check if the element exists in the DOM? I receive the variable editor as a parameter.
Please notice, the editor may also be inside an <iframe>.

I found a solution, it's not ideal but it works. I gave every editor a unique data attribute:
if (($editor.length === 1) && (typeof($editor.attr('data-editor-id')) === 'undefined')) {
$editor.attr('data-editor-id', Math.floor((Math.random() * 900000000000000) + 100000000000000));
}
And then I changed the function:
observeEditor = function(editor) {
var $editor = jQuery(editor);
var editor_id = undefined;
if (($editor.length === 1) && (!(typeof($editor.attr('data-editor-id')) === 'undefined'))) {
editor_id = $editor.attr('data-editor-id');
}
function update_position() {
console.log("update_position");
if (jQuery(document).find('[data-editor-id="' + editor_id + '"]').length > 0) {
// call our function
setTimeout(update_position, 100);
}
}
setTimeout(update_position, 100);
};
By the way, I changed the timout to 100 ms because it's too slow with 250.

Related

do something when js element is loaded , is not working

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

inserting a .on(load) timeout

I'm attempting to load some images dynamically via .on('load') - via the following script:
.on('load', function() {
if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {
alert('broken image!');
} else {
$("#rateholder").append(img);
}
});
Sometimes, however, the attempt fails for some reason or other. I'd like to put a timeout on it so if the image hasn't loaded within say...10 seconds...it runs a different function.
How would I append a timeout to this?
You can create a function that checks your image exists every 10 seconds.
Then do what you need if it doesn't.
var oneSecond = 1000;
var checkExist = setInterval(function() {
if ($('#the-image').length) {
console.log("Exists!");
clearInterval(checkExist);
}
else{
console.log('Does not Exist');
clearInterval(checkExist);
}
}, oneSecond*10);

How to keep Skrollr-Menu at an even speed?

I'm using Skrollr-menu to animate down a page on a button press using the following
HTML
<div class="trigger-scroll left">></div>
... the page i want to reveal, using scrolling ...
<section id="End" class="scroll-here">
<div class="hsContainer bottom"></div>
</section>
JavaScript
var s = skrollr.init();
skrollr.menu.init(s, {
animate: true,
//How long the animation should take in ms.
duration: function(currentTop, targetTop) {
//By default, the duration is hardcoded at 500ms.
return 18000;
//But you could calculate a value based on the current scroll position (`currentTop`) and the target scroll position (`targetTop`).
//return Math.abs(currentTop - targetTop) * 10;
},
//This event is triggered right before we jump/animate to a new hash.
change: function(newHash, newTopPosition) {
//Do stuff
},
//Add hash link (e.g. `#foo`) to URL or not.
updateUrl: false //defaults to `true`.
});
What happens when I click the button is that it works, that is not the problem.
The problem is that it seems to change speed as skrollr-menu animates the page. It starts off quite quickly, which means that the first few elements on the page (about the first 2000px) flash past without being readable. Then the speed evens out and is fine right until the last 3000px (approximately) where skrollr-menu is very slow. What I want is for the click of the button to resemble holding the down arrow on the keyboard or the scroll sidebar, which by default it seems skrollr-menu does not do.
I've tried using math equations to change the speed but the issue persists no matter what i try, and there doesn't seem to be any "simple" way to change the acceleration speed, and I suspect the problem is somewhere within the Skrollr.menu.js file, but I can't see where.
Is there any way which I can make the scrolling an even speed, rather than fast at the start and slow at the end?
Note: I'm not very experienced in JavaScript or jQuery, so it's probably something simple I've overlooked.
skrollr menu on github
https://github.com/Prinzhorn/skrollr-menu
Skrollr.menu.js
/*!
* Plugin for skrollr.
* This plugin makes hashlinks scroll nicely to their target position.
*
* Alexander Prinzhorn - https://github.com/Prinzhorn/skrollr
*
* Free to use under terms of MIT license
*/
(function(document, window) {
'use strict';
var DEFAULT_DURATION = 500;
var DEFAULT_EASING = 'sqrt';
var DEFAULT_SCALE = 1;
var MENU_TOP_ATTR = 'data-menu-top';
var MENU_OFFSET_ATTR = 'data-menu-offset';
var MENU_DURATION_ATTR = 'data-menu-duration';
var MENU_IGNORE_ATTR = 'data-menu-ignore';
var skrollr = window.skrollr;
var history = window.history;
var supportsHistory = !!history.pushState;
/*
Since we are using event bubbling, the element that has been clicked
might not acutally be the link but a child.
*/
var findParentLink = function(element) {
//We reached the top, no link found.
if(element === document) {
return false;
}
//Yay, it's a link!
if(element.tagName.toUpperCase() === 'A') {
return element;
}
//Maybe the parent is a link.
return findParentLink(element.parentNode);
};
/*
Handle the click event on the document.
*/
var handleClick = function(e) {
//Only handle left click.
if(e.which !== 1 && e.button !== 0) {
return;
}
var link = findParentLink(e.target);
//The click did not happen inside a link.
if(!link) {
return;
}
if(handleLink(link)) {
e.preventDefault();
}
};
/*
Handles the click on a link. May be called without an actual click event.
When the fake flag is set, the link won't change the url and the position won't be animated.
*/
var handleLink = function(link, fake) {
var hash;
//When complexLinks is enabled, we also accept links which do not just contain a simple hash.
if(_complexLinks) {
//The link points to something completely different.
if(link.hostname !== window.location.hostname) {
return false;
}
//The link does not link to the same page/path.
if(link.pathname !== document.location.pathname) {
return false;
}
hash = link.hash;
} else {
//Don't use the href property (link.href) because it contains the absolute url.
hash = link.getAttribute('href');
}
//Not a hash link.
if(!/^#/.test(hash)) {
return false;
}
//The link has the ignore attribute.
if(!fake && link.getAttribute(MENU_IGNORE_ATTR) !== null) {
return false;
}
//Now get the targetTop to scroll to.
var targetTop;
var menuTop;
//If there's a handleLink function, it overrides the actual anchor offset.
if(_handleLink) {
menuTop = _handleLink(link);
}
//If there's a data-menu-top attribute and no handleLink function, it overrides the actual anchor offset.
else {
menuTop = link.getAttribute(MENU_TOP_ATTR);
}
if(menuTop !== null) {
//Is it a percentage offset?
if(/p$/.test(menuTop)) {
targetTop = (menuTop.slice(0, -1) / 100) * document.documentElement.clientHeight;
} else {
targetTop = +menuTop * _scale;
}
} else {
var scrollTarget = document.getElementById(hash.substr(1));
//Ignore the click if no target is found.
if(!scrollTarget) {
return false;
}
targetTop = _skrollrInstance.relativeToAbsolute(scrollTarget, 'top', 'top');
var menuOffset = scrollTarget.getAttribute(MENU_OFFSET_ATTR);
if(menuOffset !== null) {
targetTop += +menuOffset;
}
}
if(supportsHistory && _updateUrl && !fake) {
history.pushState({top: targetTop}, '', hash);
}
var menuDuration = parseInt(link.getAttribute(MENU_DURATION_ATTR), 10);
var animationDuration = _duration(_skrollrInstance.getScrollTop(), targetTop);
if(!isNaN(menuDuration)) {
animationDuration = menuDuration;
}
//Trigger the change if event if there's a listener.
if(_change) {
_change(hash, targetTop);
}
//Now finally scroll there.
if(_animate && !fake) {
_skrollrInstance.animateTo(targetTop, {
duration: animationDuration,
easing: _easing
});
} else {
defer(function() {
_skrollrInstance.setScrollTop(targetTop);
});
}
return true;
};
var jumpStraightToHash = function() {
if(window.location.hash && document.querySelector) {
var link = document.querySelector('a[href="' + window.location.hash + '"]');
if(!link) {
// No link found on page, so we create one and then activate it
link = document.createElement('a');
link.href = window.location.hash;
}
handleLink(link, true);
}
};
var defer = function(fn) {
window.setTimeout(fn, 1);
};
/*
Global menu function accessible through window.skrollr.menu.init.
*/
skrollr.menu = {};
skrollr.menu.init = function(skrollrInstance, options) {
_skrollrInstance = skrollrInstance;
options = options || {};
_easing = options.easing || DEFAULT_EASING;
_animate = options.animate !== false;
_duration = options.duration || DEFAULT_DURATION;
_handleLink = options.handleLink;
_scale = options.scale || DEFAULT_SCALE;
_complexLinks = options.complexLinks === true;
_change = options.change;
_updateUrl = options.updateUrl !== false;
if(typeof _duration === 'number') {
_duration = (function(duration) {
return function() {
return duration;
};
}(_duration));
}
//Use event bubbling and attach a single listener to the document.
skrollr.addEvent(document, 'click', handleClick);
if(supportsHistory) {
skrollr.addEvent(window, 'popstate', function(e) {
var state = e.state || {};
var top = state.top || 0;
defer(function() {
_skrollrInstance.setScrollTop(top);
});
}, false);
}
jumpStraightToHash();
};
//Expose the handleLink function to be able to programmatically trigger clicks.
skrollr.menu.click = function(link) {
//We're not assigning it directly to `click` because of the second ("private") parameter.
handleLink(link);
};
//Private reference to the initialized skrollr.
var _skrollrInstance;
var _easing;
var _duration;
var _animate;
var _handleLink;
var _scale;
var _complexLinks;
var _change;
var _updateUrl;
//In case the page was opened with a hash, prevent jumping to it.
//http://stackoverflow.com/questions/3659072/jquery-disable-anchor-jump-when-loading-a-page
defer(function() {
if(window.location.hash) {
window.scrollTo(0, 0);
}
});
}(document, window));
The problem was the easing function found here
//Now finally scroll there.
if(_animate && !fake) {
_skrollrInstance.animateTo(targetTop, {
duration: animationDuration,
easing: _easing
});
} else {
defer(function() {
_skrollrInstance.setScrollTop(targetTop);
});
}
return true;
It seems that, even though Skrollr states that easing's default is linear (no easing), the default is ACTUALLY set to sqrt (or at least it was in my case). The problem can be solved by forcing easing to linear in skrollr.menu.init, or chaning the skrollr.menu.js file to remove easing from the function. The first of these two solutions is cleaner, and won't cause issues later.
skrollr.menu.init(s, {
duration: function(currentTop, targetTop) {return 20000;},
easing: 'linear'
});

bug in closing tooltip on esc

I am just a beginner in jquery. I have used the tooltip script from this site. http://www.twinhelix.com/dhtml/supernote/demo/#demo4 .They used the following function to close the tooltip on clicking the close button.
<script type="text/javascript">
// SuperNote setup: Declare a new SuperNote object and pass the name used to
// identify notes in the document, and a config variable hash if you want to
// override any default settings.
var supernote = new SuperNote('supernote', {});
// Available config options are:
//allowNesting: true/false // Whether to allow triggers within triggers.
//cssProp: 'visibility' // CSS property used to show/hide notes and values.
//cssVis: 'inherit'
//cssHid: 'hidden'
//IESelectBoxFix: true/false // Enables the IFRAME select-box-covering fix.
//showDelay: 0 // Millisecond delays.
//hideDelay: 500
//animInSpeed: 0.1 // Animation speeds, from 0.0 to 1.0; 1.0 disables.
//animOutSpeed: 0.1
// You can pass several to your "new SuperNote()" command like so:
//{ name: value, name2: value2, name3: value3 }
// All the script from this point on is optional!
// Optional animation setup: passed element and 0.0-1.0 animation progress.
// You can have as many custom animations in a note object as you want.
function animFade(ref, counter)
{
//counter = Math.min(counter, 0.9); // Uncomment to make notes translucent.
var f = ref.filters, done = (counter == 1);
if (f)
{
if (!done && ref.style.filter.indexOf("alpha") == -1)
ref.style.filter += ' alpha(opacity=' + (counter * 100) + ')';
else if (f.length && f.alpha) with (f.alpha)
{
if (done) enabled = false;
else { opacity = (counter * 100); enabled=true }
}
}
else ref.style.opacity = ref.style.MozOpacity = counter*0.999;
};
supernote.animations[supernote.animations.length] = animFade;
// Optional custom note "close" button handler extension used in this example.
// This picks up click on CLASS="note-close" elements within CLASS="snb-pinned"
// notes, and closes the note when they are clicked.
// It can be deleted if you're not using it.
addEvent(document, 'click', function(evt)
{
var elm = evt.target || evt.srcElement, closeBtn, note;
while (elm)
{
if ((/note-close/).test(elm.className)) closeBtn = elm;
if ((/snb-pinned/).test(elm.className)) { note = elm; break }
elm = elm.parentNode;
}
if (closeBtn && note)
{
var noteData = note.id.match(/([a-z_\-0-9]+)-note-([a-z_\-0-9]+)/i);
for (var i = 0; i < SuperNote.instances.length; i++)
if (SuperNote.instances[i].myName == noteData[1])
{
setTimeout('SuperNote.instances[' + i + '].setVis("' + noteData[2] +
'", false, true)', 100);
cancelEvent(evt);
}
}
});
// Extending the script: you can capture mouse events on note show and hide.
// To get a reference to a note, use 'this.notes[noteID]' within a function.
// It has properties like 'ref' (the note element), 'trigRef' (its trigger),
// 'click' (whether its shows on click or not), 'visible' and 'animating'.
addEvent(supernote, 'show', function(noteID)
{
// Do cool stuff here!
});
addEvent(supernote, 'hide', function(noteID)
{
// Do cool stuff here!
});
// If you want draggable notes, feel free to download the "DragResize" script
// from my website http://www.twinhelix.com -- it's a nice addition :).
</script>
I have tried to edit this function for closing the tooltip on clicking the esckey too. But i couldn't. How can i modify the function?

How to detect if some text box is changed via external script?

I have some jQuery plugin that changes some elements, i need some event or jQuery plugin that trigger an event when some text input value changed.
I've downloaded jquery.textchange plugin, it is a good plugin but doesn't detect changes via external source.
#MSS -- Alright, this is a kludge but it works:
When I call boxWatcher() I set the value to 3,000 but you'd need to do it much more often, like maybe 100 or 300.
http://jsfiddle.net/N9zBA/8/
var theOldContent = $('#theID').val().trim();
var theNewContent = "";
function boxWatcher(milSecondsBetweenChecks) {
var theLoop = setInterval(function() {
theNewContent = $('#theID').val().trim();
if (theOldContent == theNewContent) {
return; //no change
}
clearInterval(theLoop);//stop looping
handleContentChange();
}, milSecondsBetweenChecks);
};
function handleContentChange() {
alert('content has changed');
//restart boxWatcher
theOldContent = theNewContent;//reset theOldContent
boxWatcher(3000);//3000 is about 3 seconds
}
function buttonClick() {
$('#theID').value = 'asd;lfikjasd;fkj';
}
$(document).ready(function() {
boxWatcher(3000);
})
try to set the old value into a global variable then fire onkeypress event on your text input and compare between old and new values of it. some thing like that
var oldvlaue = $('#myInput').val();
$('#myInput').keyup(function(){
if(oldvlaue!=$('#myInput').val().trim())
{
alert('text has been changed');
}
});
you test this example here
Edit
try to add an EventListner to your text input, I don't know more about it but you can check this Post it may help
Thanks to #Darin because of his/her solution I've marked as the answer, but i have made some small jQuery plugin to achieve the same work named 'txtChgMon'.
(function ($) {
$.fn.txtChgMon = function (func) {
var res = this.each(function () {
txts[0] = { t: this, f: func, oldT: $(this).val(), newT: '' };
});
if (!watchStarted) {
boxWatcher(200);
}
return res;
};
})(jQuery);
var txts = [];
var watchStarted = false;
function boxWatcher(milSecondsBetweenChecks) {
watchStarted = true;
var theLoop = setInterval(function () {
for (var i = 0; i < txts.length; i++) {
txts[i].newT = $(txts[i].t).val();
if (txts[i].newT == txts[i].oldT) {
return; //no change
}
clearInterval(theLoop); //stop looping
txts[i].f(txts[i], txts[i].oldT, txts[i].newT);
txts[i].oldT = $(txts[i].t).val();
boxWatcher(milSecondsBetweenChecks);
return;
}
}, milSecondsBetweenChecks);
}

Categories