I am using this code to dynamically change the text of a span element. It works in chrome, only changing the content of the span once, but does an infinite loop in IE (the count keeps updating and the html text keeps changing). Anyone know how I can fix it or why its happening?
bindFlagUpdate();
function bindFlagUpdate(){
$(document).bind('flagGlobalAfterLinkUpdate', function(event, data) {
var string = $('#like-' + data.contentId).html();
var getNum = string.match(/[0-9]+/g);
var count = getNum[0];
if(data.flagStatus == 'flagged') {
count++;
} else {
count--;
}
$('#like-' + data.contentId).html("1 user likes this");
$(document).unbind();
bindFlagUpdate();
return false;
});
}
Description of the event:
The flagGlobalAfterLinkUpdate event This event is triggered
immediately after a flag link has been updated. (Flag links appear in
two flavors: "Bookmark this!" and "Unbookmark this!", and when we
speak of "update" we mean this change in appearance).
The even is attached to a "flag" button
To answer this we need to know more about the event flagGlobalAfterLinkUpdate and how it is triggered. It sounds like something in the callback function for the event is triggering the event, so once it's triggered once, it triggers itself continuously.
Related
My code:
$('#search-form').on('keyup change paste', function(event) {
$('#songs').empty();
$('#aplayer').css('display', 'none');
var keyword = $('#keyword').val();
if (keyword.trim() === '') {
return;
}
const relatedSongs = songs.filter(function(song) {
return song.name.includes(keyword);
});
$('#songs').append(relatedSongs.map(function(song) {
return '<li class="list-group-item" data-index="' + song.index + '">name:' + song.name + '</li>';
}));
});
$('#songs').on('click', '.song-name', function() {
const index = $(this).parent().data('index');
const song = songs[index];
ap.list.clear();
ap.list.add(song);
$('#aplayer').css('display', 'block');
});
The point is $('#songs').append, I dynamically create elements and append them into the #songs element.
All dynamically created elements have a link of class song-name, and you can notice I bind a click event callback on them.
The problem is:
When user clicks the link first time, the callback does not get called. The callback will be called only when the user clicks on it one more time.
I can't understand why is it happened? Can anyone help me?
Thanks a lot.
The problem happens because when you click on a song, you simultaneously lose the focus on the text box. This fires the "change" event of the textbox, which then clears the song list, so the song element you just clicked on no longer exists, and this occurs before its "click" handler has chance to execute.
Of course the song is instantly replaced by one which looks identical, giving you an optical illusion which might lead you to believe you're still looking at the same HTML element, when actually it's just a twin.
In my opinion the best option here is simply to remove the "change" event from the list of handled events - it's superfluous because keyup and/or paste already fire before it whenever any text is entered. So your search event handler will become:
$('#search-form').on('keyup paste', function(event) {
See http://jsfiddle.net/0j15ruz9/26/ for a demonstration.
Just remove the keyup event from your initial handler. The change event will cover the cases you need and it will work correctly on first click.
On your first click the first event handler is triggered first and something gets messed.
I was suffer the same issue several times, I don't know what is the reason of that (I supose that it happeng for something related to the DOM's actualization), but I resolve it that way
function song_name_click(e){
const index = $(this).parent().data('index');
const song = songs[index];
ap.list.clear();
ap.list.add(song);
$('#aplayer').css('display', 'block');
}
...
$('#songs').append(relatedSongs.map(function(song) {
return '<li class="list-group-item" data-index="' + song.index + '">name:' + song.name + '</li>';
}));
$(".song-name").off('click');
$(".song-name").on('click', song_name_click);
...
I've encountered a situation where some script changes a select/radio/checkbox. That fires the change event. However I need, separately, an event to tell me the user changed the element, and obviously when change fires from the script it registers as a user change.
Is there a way to prevent a script from firing the change event when you alter the value of a select/radio/checkbox?
Use jQuery.trigger() and pass an additional parameter when triggering the event from code.
For example:
$('select').bind('change', function(e, isScriptInvoked) {
if (isScriptInvoked === true) {
// some code for when artificial
} else {
// some code for when organic
}
});
// Trigger the event.
$('select').trigger('change', [true]);
Try:
function changeEvent(){
if(this.type.toLowerCase()=='select' || this.type.toLowerCase()=='radio' || this.type.toLowerCase()=='checkbox')
return false;
else{
//Your code here
}
}
I have the following html code:
<input type="text" id="theInput" value=""/>
Click me
I want to detect when the input changes and perform an operation in this case, but ONLY when the user has not clicked in the link. I have tried this:
$('#theLink').live('click', function(){
alert('click');
});
$('#theInput').live('change', function(){
alert('change');
});
However change is always executed before click when the value in the input changed, due to Javascript event precedence rules, and therefore only "change" message is displayed.
I would like it to display change only if the input value changed and the user exited the input clicking in any other place instead of the link. In that last case I would like to display click.
The example is here.
I use jQuery 1.6.4.
As far as I know, the click event fires after the blur and change events in every browser (have a look at this JSFiddle). The order of blur and change is different across browsers (source: Nicholas Zakas).
To solve your problem, you could listen to click events on the document and compare the event's target with #theLink. Any click event will bubble up to the document (unless it is prevented).
Try this:
var lastValue = '';
$(document).click(function(event) {
var newValue = $('#theInput').val();
if ($(event.target).is('#theLink')) {
// The link was clicked
} else if (newValue !== lastValue) {
// Something else was clicked & input has changed
} else {
// Something else was clicked but input didn't change
}
lastValue = newValue;
});
JSFiddle: http://jsfiddle.net/PPvG/TTwEG/
Both events will fire but in your example the alert in the onchange event handler fired when the onmousedown event occurs will stop the onmouseup event required for the onclick event to fire. Using console.log will show both events firing.
http://jsfiddle.net/hTqNr/4/
Ok, now i got it, you could do
$('#theLink').live('click', function(e){
alert('click');
});
$('#theInput').live('change', function(e){
//Check if the change events is triggerede by the link
if(e.originalEvent.explicitOriginalTarget.data === "Click me"){
//if this is the case trigger the click event of the link
$('#theLink').trigger("click");
}else{
//otherwise do what you would do in the change handler
alert('change');
}
});
Fiddle here http://jsfiddle.net/hTqNr/19/
why you dont pick the value of input box. you have to store initial value of input box on ready function
initialvalue= $('#theInput').val();
then compare the value
$('#theLink').live('click', function(){
var newvalue =$('#theInput').val();
if(newvalue!=initialvalue) {
//do something
}
});
I have a GeoExt map panel with a zoom control. I'd really like to disable some of the nodes in a tree panel when the layers on my map are "out of range" aka their setVisibility is set to false. I have my zoomend event working and I also have a checkchange event working, but the checkchange event gets evaluated more than once if the user pushes the zoombar more than one level and the other problem is that even after the zoomend event is over the checkchange still gets fired every time the user merely clicks the node's checkbox on or off. I really need a way to control this checkchange event to only run once and to stop it from firing if the user is not using the zoombar...
map.events.on({ "zoomend": function (e) {
layerTree.on("checkchange", function (node, checked) {
alert(node.text + "Inside event");
if(checked == false)
node.disable();
else if(checked == true)
node.enable();
});
if (this.getZoom() > 7) {
tib_villages.setVisibility(true);
tib_lakes.setVisibility(true);
tib_townships.setVisibility(true);
}
else {
tib_villages.setVisibility(false);
tib_lakes.setVisibility(false);
tib_townships.setVisibility(false);
if (this.getZoom() > 5) {
infrastructure.setVisibility(true);
geography.setVisibility(true);
geography2.setVisibility(true);
tib_countys.setVisibility(true);
}
else{
infrastructure.setVisibility(false);
geography.setVisibility(false);
geography2.setVisibility(false);
tib_countys.setVisibility(false);
}
}//end else
}//end function (e)
}); //end map.events.on
Thank you for all your time and feedback :)
elshae
It turns out that the work has already been done for us :). There is a patch at http://trac.geoext.org/attachment/ticket/235/autoDisableLayerNode.patch which will automatically disable/enable nodes based on their minScale/maxScale properties etc. I applied the patch by putting this file in my GeoExt directory and running the following command in my GeoExt directory:
patch -p0 < autoDisableLayerNode.patch
I hope this helps! It worked wonders for me :)
elshae
I'm creating a popup window that has a beforeunload handler installed. When the "Close" file menu item is used to close the popup, the beforeunload handler is called twice, resulting in two "Are you sure you want to close this window?" messages appearing.
This is a bug with Firefox, and I've reported it here, but I still would like a way to prevent this from happening. Can you think of a sane way of detecting double beforeunload to prevent the double message problem? The problem is that Firefox doesn't tell me which button in the dialog the user elected to click - OK or cancel.
<script type="text/javascript">
var onBeforeUnloadFired = false;
window.onbeforeunload = function ()
{
if (!onBeforeUnloadFired) {
onBeforeUnloadFired = true;
event.returnValue = "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
}
window.setTimeout("ResetOnBeforeUnloadFired()", 10);
}
function ResetOnBeforeUnloadFired() {
onBeforeUnloadFired = false;
}
</script>
Set a variable in the handler to prevent the dialog coming up the second time. Use setTimeout to reset it afterwards.
This is definitely a FF bug. I've reported it at https://bugzilla.mozilla.org/show_bug.cgi?id=531199
The best solution I've found is to use a flag global variable that is reset after so many milliseconds, say 500 (this ensures that the function can be called again, but not immediately after its appearance).
See last code in:
http://social.msdn.microsoft.com/Forums/en/sharepointinfopath/thread/13000cd8-5c50-4260-a0d2-bc404764966d
I've found this problem in Chrome 21, Firefox 14, IE 7-9, Safari 5 (on PC).
The following works on all of these browsers. If one removes the window.onbeforeunload function during the event this will prevent the second call. The trick is to reset the window.onbeforeunload function if the user decides to stay on the page.
var window_on_before_unload = function(e) {
var msg;
// Do here what you ever you need to do
msg = "Message for user";
// Prevent next "window.onbeforeunload" from re-running this code.
// Ensure that if the user decides to stay on the page that
// this code is run the next time the user tries to leave the page.
window.onbeforeunload = set_on_before_unload;
// Prepare message for user
if (msg) {
if (/irefox\/([4-9]|1\d+)/.test(navigator.userAgent))
alert(msg
+ '\n\nThe next dialog will allow you to stay here or continue\nSee Firefox bug #588292');
(e = e || window.event).returnValue = msg;
return msg;
}
};
// Set window.onbeforeunload to the above handler.
// #uses window_on_before_unload
// #param {Event} e
var set_on_before_unload = function(e) {
// Initialize the handler for window.onbeforeunload.
window.onbeforeunload = window_on_before_unload;
}
// Initialize the handler for window.onbeforeunload.
set_on_before_unload();
Create a global variable that is set to true inside the handler. Only show the alert/popup when this variable is false.
I use the following snippet to track the exitcount
When the page loads the following variable exitCount is initialized
if (typeof(MTG) == 'undefined') MTG = {};
MTG.exitCount=0;
and in the Window unload event
$(window).bind("beforeunload", function(){
if (MTG.exitCount<=0)
{
//do your thing, save etc
}
MTG.exitCount++;
});
I've found that instead of doing your own call to confirm(), just do even.preventDefault(); within the beforeunload event. Firefox throws up its own confirm dialog.
I'm not sure if this is the correct/standard thing to do, but that's how they're doing it.
I have a document opening another popup window with window.open. In the original window I have registered (with jquery) a listener for "unload" event like this:
var popup_window = window.open(...)
$(popup_window).on('unload', function(event) ...
I have came across this page because the event was effectively triggering twice. What I have found is that it is not a bug, it triggers twice because it fires once for "about:blank" page being replaced by your page and another for your page being unloaded.
All I have to do is to filter the event that I am interested in by querying the original event:
function (event) {
var original_url = e.originalEvent.originalTarget.URL;
if (original_url != 'about:blank')
{
... do cool things ...
}
}
I don't know if this applies to the original question, because it is a special case of a window opening another, but I hope it helps.