setInterval not working in Opera - javascript

I am trying to make an element blink (by toggeling visibility of the element) but its not working in Opera for whatever reason. Works fine in Firefox and Chrome.
Here's a fiddle with a working sample: http://jsfiddle.net/UDWkK/2/
I don't think I have made any obvious errors.
Tested in Opera 12
Code:
var blinker;
function blink(elem) {
clearInterval(blinker);
blinker = setInterval(function() {
if ($(elem).css('visibility') === 'hidden'){
$(elem).css('visibility', 'visible');
} else {
$(elem).css('visibility', 'hidden');
}
}, 500);
}

As #nevermind noted in the comments above the problem is not with Opera. The problem is with the jsFiddle iframes. Note that jsFiddle is still in alpha stage. Hence there are bound to be some quirks. Hopefully the developers will fix it soon.
Nevertheless the code you provided doesn't really need jQuery, and setInterval works perfectly fine in Opera 12. For example this is what I did, and it blinks away nicely: http://jsfiddle.net/XwEhj/

I think you are in a corner buggy case.
When it's comes to user interface, it's not a good practice to rely on the state of the graphic objects to find out the state of the view. In other terms, you don't want to "read" the state of the view in the HTML elements, but rather in a variable or a set of variables called a view model.
I suggest that you rewrite your code this way, and I think there's a good chance to work around the bug:
var blinker;
function blink(elem) {
clearInterval(blinker);
var visible = false;
blinker = setInterval(function() {
visible = !visible;
$(elem).css('visibility', visible ? 'visible' : 'hidden');
}, 500);
}

Related

Scroll event won't fire what so ever

I have a (fairly simple) issue and I'm breaking my head over it.
The issue is pretty simple - scroll event won't fire (ever).
I'm writing this angular project, so I've tried the following:
angular.element($window).bind('scroll', ()=> {
console.log('scroll!');
if (!scope.scrollPosition) {
scope.scrollPosition = 0;
}
// Alerting for test cause wtf is going on
scope.boolChangeClass = this.pageYOffset > 600 ? alert(true) : alert(false);
scope.scrollPosition = this.pageYOffset;
scope.$apply();
}
);
but nothing happened. (assume $window is intact and that i'm using webpack etc.)
This example works great if I change the scroll to click. weird.
So I've tried vanilla~~!
window.addEventListener('scroll',function(){
console.log('test')
})
This attempt works on every other website except mine (gotta admit it's classic).
So - has anyone ever dealt with this and knows what's going on?
I assume that some other element is consuming this event at early stage thus not letting it bubble up. Yet this is just an assumption.'
Would love to understand this :)
=== EDIT ===
I've tried to see all the fired events using monitorEvents(window) (using Chrome) and I see every event that's being fire except the scroll..
Looks like it's the body element that is scrolling. Try adding the following code in the console.
document.body.addEventListener('scroll', function() {
console.log('test');
});

Javascript hide/show toggle works both ways in Opera, but only one way in other browsers

I have a customized show/hide toggle script that I'm using along with CSS3 transitions for the effects.
The script shows the content when clicked, and hides it when the 'HideLink' link is clicked, complete with CSS3 transistions - but only in Opera.
In other browsers the script only works for showing the content, clicking the hide link doesn't work.
See this JSfiddle: http://jsfiddle.net/xte63/
These days with show / hide javascript, I prefer to use HTML5's data-* attributes.
This can already be used in non-HTML5 browsers via the getAttribute and setAttribute function.
I've quickly tried it against IE7, Chrome and Opera and it seems to work.
http://jsfiddle.net/ThJcb/
function showHide(shID) {
var exDiv = document.getElementById(shID);
if(exDiv.getAttribute("data-visible") != 'false'){
document.getElementById(shID+'-show').style.cssText = ';height:auto;opacity:1;visibility:visible;';
document.getElementById(shID).style.cssText = ';height:0;opacity:0;visibility:hidden;';
exDiv.setAttribute("data-visible" , 'false');
} else {
document.getElementById(shID+'-show').style.cssText = ';height:;opacity:0;visibility:hidden;';
document.getElementById(shID).style.cssText = ';height:auto;opacity:1;visibility: visible ;';
exDiv.setAttribute("data-visible" , 'true');
}
}
This allows you to determine the state of the div without having to check for CSS values.
EDIT: As pointed out in the comments, a typo was on the hide link (onlick instead of onclick) which made it appear the above jsfiddle worked whereas it didn't. At least not exactly as I made an error in the logic, setting the "data-visible" to false instead of true.
Here's an updated jsfiddle: http://jsfiddle.net/ThJcb/4/
(javascript snippet above updated also)

Overriding yellow autofill background

After a long struggle, I've finally found the only way to clear autofill styling in every browser:
$('input').each(function() {
var $this = $(this);
$this.after($this.clone()).remove();
});
However, I can’t just run this in the window load event; autofill applies sometime after that. Right now I’m using a 100ms delay as a workaround:
// Kill autofill styles
$(window).on({
load: function() {
setTimeout(function() {
$('.text').each(function() {
var $this = $(this);
$this.after($this.clone()).remove();
});
}, 100);
}
});
and that seems safe on even the slowest of systems, but it’s really not elegant. Is there some kind of reliable event or check I can make to see if the autofill is complete, or a cross-browser way to fully override its styles?
If you're using Chrome or Safari, you can use the input:-webkit-autofill CSS selector to get the autofilled fields.
Example detection code:
setInterval(function() {
var autofilled = document.querySelectorAll('input:-webkit-autofill');
// do something with the elements...
}, 500);
There's a bug open over at http://code.google.com/p/chromium/issues/detail?id=46543#c22 relating to this, it looks like it might (should) eventually be possible to just write over the default styling with an !important selector, which would be the most elegant solution. The code would be something like:
input {
background-color: #FFF !important;
}
For now though the bug is still open and it seems like your hackish solution is the only solution for Chrome, however a) the solution for Chrome doesn't need setTimeout and b) it seems like Firefox might respect the !important flag or some sort of CSS selector with high priority as described in Override browser form-filling and input highlighting with HTML/CSS. Does this help?
I propose you avoiding the autofill in first place, instead of trying to trick the browser
<form autocomplete="off">
More information: http://www.whatwg.org/specs/web-forms/current-work/#the-autocomplete
If you want to keep the autofill behaviour but change the styling, maybe you can do something like this (jQuery):
$(document).ready(function() {
$("input[type='text']").css('background-color', 'white');
});
$(window).load(function()
{
if ($('input:-webkit-autofill'))
{
$('input:-webkit-autofill').each(function()
{
$(this).replaceWith($(this).clone(true,true));
});
// RE-INITIALIZE VARIABLES HERE IF YOU SET JQUERY OBJECT'S TO VAR FOR FASTER PROCESSING
}
});
I noticed that the jQuery solution you posted does not copy attached events. The method I have posted works for jQuery 1.5+ and should be the preferred solution as it retains the attached events for each object. If you have a solution to loop through all initialized variables and re-initialize them then a full 100% working jQuery solution would be available, otherwise you have to re-initialize set variables as needed.
for example you do: var foo = $('#foo');
then you would have to call: foo=$('#foo');
because the original element was removed and a clone now exists in its place.

JavaScript changes to style being delayed

I'm running into a little problem that's driving me crazy, and I'd welcome any thoughts as to the cause. At this point I feel like I'm just going 'round in circles.
I have the following code:
function JSsortTable(phase) {
dynaLoadingDivShow();
createSortArray();
dataArr = do2DArraySort(dataArr, orderList, orderDir);
sortArrayToRs();
dynaListTable.tableControl.refreshTableViaObjects(rsDynaList, colObjs);
dynaLoadingDivHide();
}
function dynaLoadingDivShow() {
document.getElementById('dynaReportGuiWorking').style.display = 'block';
document.getElementById('dynaReportGuiWorking').style.visibility = 'visible';
}
function dynaLoadingDivHide() {
document.getElementById('dynaReportGuiWorking').style.display = 'none';
document.getElementById('dynaReportGuiWorking').style.visibility = 'hidden';
}
<div style="visibility:hidden; display:none; z-index:25;" class="tableControlHeader" id="dynaReportGuiWorking">
Working...
</div>
I call JSsortTable as an onclick event. When I run the above code as is, I never see the div in question. The JSsortTable function takes some 800-2500 ms to run so it's highly unlikely I just missed it the 10+ times I tried. If I change the style of the div to start out visible, then it will remain visible until after JSsortTable has finished running and then disappear; exactly as expected. So I figured the problem was in dynaLoadingDivShow.
Now, I tried removing dynaLoadingDivHide to see what would happen and found something completely unexpected. The div will not appear when you the JSsortTable function fires. Instead, after all the other code has been run, when JSsortTable finishes, the div becomes visible. It's alomst as though IE (version 8) is saving up all the changes to the DOM and then waiting until the end to paint them. This is, obviously, not the desired behavior.
Anyone have any thoughts on this? I'm only allowed to have IE at work so I haven't tried this on other browsers. I have enough CSS/JS knowledge to be dangerous, but am by no means an expert yet. ;)
Thanks!
You'll need to use a timeout:
function JSsortTable() {
dynaLoadingDivShow();
setTimeout(JSortTableWork);
}
function JSortTableWork()
createSortArray();
dataArr = do2DArraySort(dataArr, orderList, orderDir);
sortArrayToRs();
dynaListTable.tableControl.refreshTableViaObjects(rsDynaList, colObjs);
dynaLoadingDivHide();
}
Note that I took out the parameter phase because it's not used in the function. If you do need the parameter then you'll need to modify the timeout as
setTimeout(function(){JSortTableWork(phase);});
and also add the parameter to JSortTableWork

jquery click function doesn't work in internet explorer 7

I use this code to create a simple jquery carousel animation:
$(document).ready(function() {
var slide = 1;
$('#arrow-left').click(function() {
if (slide == 1) {
$("#slideshow-train").animate({left: '-840'}, 2000);
slide = 2;
} else if (slide == 2) {
$("#slideshow-train").animate({left: '-1680'}, 2000);
slide = 3;
} else if (slide == 3) {
$("#slideshow-train").animate({left: '0'}, 1000);
slide = 1;
}
});
});
This code works fine in all major browser except Internet Explorer 7! It even works fine in IE6! The problem is that click function doesn't work in IE7 at all. Can anyone please point out what is the problem and how can I solve it?
Here is the demo of page. Just click the left arrow (the right hand button doesn't work :)). It should work in all browsers excerpt IE7.
http://goo.gl/LVnhW
Check out 'http://www.electrictoolbox.com/jquery-animation-issues-ie7-position-relative/' - it states that 'Internet Explorer 7 can have issues with rendering jQuery animations if some of the properties that are to be animated have not already been set with CSS, and the containing block has the position property set to "relative".'
Also like Tom sugested, you should post your HTML/css as well.
$("selector").live("click", function() {
});
This solved my problem!
well this works for me in IE 7, maybe you should try this jquery plugin http://sorgalla.com/projects/jcarousel/

Categories

Resources