Span element not updating correctly - javascript

Update 3 - 10/09/2013: Just tested this with Version 29.0.1547.66 m and the problem still persists. If anyone else can test this out and let me know the results that would be great. You need an inline element such as a span with some text in, have it relatively positioned and moved by however many pixels you want from left and top. Then set up some jScript to change the current inner html of the element to something else and you should see it remain the same in the viewport but change correctly in the DOM.
Update 2: After a bit more testing the problem seems to occur on elements that are inline such as span, or have CSS that makes them inline, but that are also relatively positioned, it seems to be this combination that is causing the issue. After posting the bug on Chromium it has been flagged as a cr-Blink-Rendering issue which looks to be the engine that renders the DOM in the broswer viewport. I am using Version 29.0.1547.57 (the current version ends .66 but mine has not updated due to an error). So if you're on the latest version this issue may no longer be there.
Update: On further investigation I think the problem is with the latest Chrome build Version 29.0.1547.57 m As I tested the element in an inline fashion in IE9 and Firefox 21 and it worked fine. I have filed a bug report for this on chromium
I'm having a problem (that I have not been able to recreate with jsfiddle) where I perform an ajax request, obtain some values and place them within span elements that exist within my page.
I have a very odd problem where the ajax request is working and bringing the values back. The values are being inserted into the span elements via jQuerys .html' method and when I check the DOM using Chrome developer tools I can see the new value in the span.
However, what I see on the page doesn't reflect this, it still shows the old value. Yet if I attempt to highlight the value, it instantly changes to the correct value (the value that is showing in the DOM).
I have even tried to update the spans value before the ajax call (as the value I am using is being obtained from jQuery UI's slider widget) but this still yields the same results.
Has anyone else come across this?
EDIT: Here is some of the code
HTML
<div id="NewLoanSliderAmount" class="NewLoanSliderRules"></div>
<span id="NewLoanSliderAmountDisplay" class="NewLoanDisplay">£600</span>
The slider code. This is the version where I attempt to update it directly from the slider value
$("#NewLoanSliderAmount").slider({
value: amount,
min: 300,
max: amount,
step: 100,
change: function (event, ui) {
$("#NewLoanSliderAmountDisplay").html("£" + ui.value);
window.CkSpace.GetLoanValues();
}
});
Here is the ajax code:
(function (CkSpace, $, undefined) {
CkSpace.GetLoanValues = function () {
var url = "/Home/UpdateAPR";
$.get(url, { Amount: $("#NewLoanSliderAmount").slider("value"), Length: $("#NewLoanSliderLength").slider("value") }, function (data) {
$("#NewLoanAmount").html("£"+data.LoanAdvance);
$("#NewLoanLength").html(data.LoanTerm);
$("#NewLoanMonthlyCost").html("£"+data.LoanInstalment);
$("#NewLoanTotal").html(data.LoanGrossRepyable);
$("#NewLoanAPR").html(data.LoanAPR+"%");
$("#NewLoanSliderAmountDisplay").html("£" + data.LoanAdvance);
});
}
} (window.CkSpace = window.CkSpace || {}, jQuery));
EDIT 2:
Another thing to note is that if i set a break point on the span being populated and step through it, it updates perfectly every time in Chrome developer tools

I've figured out what was causing the problem although I don't know WHY it is causing the problem.
First off I tried changing the span to a div and adding display:inline to the css. It still didn't work.
I then removed the inline display and all of a sudden, as a block level element it works.
If anyone knows more about why this is and can elaborate then please do!
EDIT: On further investigation I think the problem is with the latest Chrome build Version 29.0.1547.57 m As I tested the element in an inline fashion in IE9 and Firefox 21 and it worked fine. I think it's time to file a bug report!

Related

find source of input value modification on page ready in javascript

I'm trying to find the cause of an unwanted value modification so I can remove the bug. When I turn off javascript for my page it includes this element after loading:
<input type="hidden" value="5123" name="report[sub_district_id]" id="report_sub_district_id">
but when I have javascript on, the same element looks like this after page load:
<input type="hidden" value="" name="report[sub_district_id]" id="report_sub_district_id">
I can't work out what code is unsetting the value property.
I've got one method that I know of that modifies the value. I've tried putting an alert in that method, but it's not triggered. I've also tried commenting out that method, but still the change happens. Perhaps some of my other JS accidentally hooks onto this element, but it seems unlikely. Perhaps the change is caused by some code in my framework (Rails with Materialize).
I've also tried adding DOM breakpoints "attribute modified" and "subtree modified" on this element, and "subtree modified" on the parent element, but none of these breakpoints are triggered.
The "attribute modified" breakpoint does trigger when my code modifies the value of the input at some point after the page is loaded, but I'm trying to find what is happening when "page:change" event is triggered, and this breakpoint is not triggering - perhaps because the DOM is not loaded yet.
I've tried the answers to this question but they don't help because they don't show how to make a breakpoint on an element change event that triggers before the DOM is loaded.
I'm using Chromium browser 48.0.2564.116 on Ubuntu 15.10 (64-bit)
How can I find what the cause of this bug is?
Debug after insert this code on top line of your page.
setInterval(function() {
var value = $("#report_sub_district_id").val();
if(value !== 5123) debugger;
},10);
and,
Maybe any Chrome extension program might cause the problem.
You should disable your all Chrome extensions.
TL;DR is there's no easy way.
So working backwards from the code that was actually changing, I don't think there is a way with browser's debugging tools to put a breakpoint here. However with an educated guess about the dom node's property that was getting changed, you could (assuming you run soon enough in the page) set a breakpoint that would help you out.
You found that the code in question was $('#parent-div-id input').val('').
Now .val() in jQuery just finds the actual node element and sets node.value = "blah"; The important distinction here is that it was changing a "property" on the node, and not an "attribute". You'll notice that all the DOMAttribute etc breakpoints talk about node attributes. If you take a node and edit the html's attribute, by say doing $('#parent-div-id input').attr('value', 'blah'), the breakpoint would get hit. The list of properties on a node is much larger than the list of HTML attributes, and the debugging tools only put breakpoints on HTML attribute modifications.
However in this case, you know the element in question (the input element), and the property that was getting messed with (the value property), so you could have done what was suggested in this answer, and redefined the property.
Example code here:
var node = $('#parent-div-id input')[0];
Object.defineProperty(node, 'value', {
get: function () {
return node._value;
},
set: function (value) {
debugger; // sets breakpoint
node._value = value;
}
});
All you'd need to do is get that code to run early enough in the page. To do that I'd probably set a breakpoint on the first line of the first javascript file loaded in the network tab.

selectedIndex undefined in IE

I saw a few posts similar to my problem and tried the solutions offered, but I'm still having issues with IE8 & IE9 and 'selectedIndex'. This code returns my variable answerSubmitted as 'undefined':
var answerSubmitted = document.getElementById("DropDown-Answers").selectedIndex;
The above works perfectly in all other browsers. Based on another post here, I also tried this:
var answerSubmitted = document.getElementById("DropDown-Answers").value;
Still the same results - works elsewhere, but not in IE8 or IE9. I've verified that IE is recognizing that particular element by its ID.
Any guidance here?
MORE INFO:
I'm creating the drop down menu dynamically by going thru a loop and adding variable text between the option and /option tags, like so (note that 'tempRandom' is a random number updated each time thru the loop):
tempMenuText = tempMenuText + "<option>" + Answers[tempRandom] + "</option>";
The results are surrounded by the form an select tags, then I update the innerHTML of my element. This works and generates a working drop down menu. But... perhaps this is a clue: when I put a test with the innerHTML of the menu element into another element to view it, it shows as empty. It's as though IE is not seeing that there is HTML in the element, thinks it is null, and therefore 'selectedIndex' fails as null.
This is solved. It turns out it was my error in how I was referring to the ID of the selected item. An associate explained that .selectedIndex only works (in IE, at least), when the ID within the 'select' tag is correct. If not, it returns null, which is what was originally happening. All is good now. Thanks for the suggestions.

Chrome/Webkit inline-block refresh problem

The problem I found is the following:
Situation: I have overall div that has a inline-block display. Inside it are two element that have an inline-block display as well.
Then I add (thanks to JavaScript) a <br/> between the two elements. The second goes to the next line, which is the normal behavior.
Buggy part: The <br/> is then removed (JavaScript again) and... the display doesn't change. It appears that the box of the overall div is not recalculated. In the end I have two similar markup that doesn't appear the same way (which is a bit problematic, isn't it).
It works fine on Firefox (it appears to be webkit based as the Android browser behave the same way). So my question is, is there a workaround that doesn't use methods that will alter the DOM? The library used is jQuery.
A test case here.
EDIT: As suggested by duri, I filled a bug report in webkit bugzilla, it's here. But I'm still looking for a workaround ;)
Way what I found: remove all childs from overall DIV, and then append all except BR's:
function removeBr(){
var ahah=document.getElementById("ahah");
var childs=[],child;
while(child=ahah.firstChild) {
if(!child.tagName||child.tagName.toLowerCase()!=='br')
childs.push(child);
ahah.removeChild(child);
}
for(var i=0;i<childs.length;i++)
ahah.appendChild(childs[i]);
}
http://jsfiddle.net/4yj7U/4/
Other variant:
function removeBr(){
var node=$("#ahah")[0];
node.style.display='inline';
$("#ahah").children("br").remove();
setTimeout(function(){node.style.display='';},0);
}
As a work around, you could set the style to display: block when you want them on individual lines and revert to inline-block when you want them to be friends.
I have created a JS Fiddle example
Which demonstrates this fix:
function addBr(){
$('span').css({ display: 'block'});
}
function removeBr(){
$('span').css({ display: 'inline-block'});
}
$("#add").click(addBr);
$("#remove").click(removeBr);
This bug still exists, so here's another workaround: http://jsfiddle.net/4yj7U/19/
$("span").css('display', 'none');
setTimeout(function(){
$('span').css('display', 'inline-block');
}, 0);
This makes Chrome re-render the spans and displays them properly.

Is it so bad to have heaps of elements in your DOM?

I am making a real estate non interactive display for their shop window.
I have kicked jCarousel into doing what I want:
Add panels per AJAX
Towards the end of the current set, go and AJAX some new panels and insert them
This works fine, but it appears calling jQuery's remove() on the prior elements cause an ugly bump. I'm not sure if calling hide() will free up any resources, as the element will still exist (and the element will be off screen anyway).
I've seen this, and tried carousel.reset() from within a callback. It just clears out all the elements.
This will be running on Google Chrome on Windows XP, and will solely be displaying on LCD televisions.
I am wondering, if I can't find a reasonable solution to remove the extra DOM elements, will it bring my application to a crawl, or will Chrome do some clever garbage collecting?
Or, how would you solve this problem?
Thanks
Could you reuse old elements instead of removing them and adding new ones ?
I worked out a fix that ended up being very simple!
Simply pass this to the config for jCarousel
itemFirstOutCallback: {
onAfterAnimation: function(carousel, li, index, state) {
if (state === 'init') return;
carousel.remove(index);
}
}
Basically, this just removes the list element as soon as it becomes invisible (scrolled into negative overflow: hidden territory, if you will :) )

IE7 display oddity (example attached)

I'm working on a Javascript-based replacement for a Flash applet. The site is having rendering problems only in IE, where it exhibits a behavior that has me at wit's end.
http://janetalasher.com/new/content/portfolio/artcloth/ (This is the page)
What does IE do that's so strange (in this case only)? If you look in Firefox, you'll see a table of images on the right which has the thumbnails. IE6 and IE7 don't show this... unless you are in print preview. It's not a CSS glitch - I've disabled all stylesheets and the error still occurs. I'd provide more relevant source code, but I don't even know where the problem is. The .js files that I suspect (if it's any help) are:
/common/gallery/display.js
/common/gallery/loader.js
Okay - update: It is definitely rendering properly in print preview mode only. Can someone please explain to me in what world this happens? The div is present in the normal mode, but the table won't render. Using the IE developer toolbar confirms it and all the cells are present.
Try adding semi-colons here:
function loadGallery(xml)
{
thumbpath = $(xml).find("thumbpath").attr('dir') // add here
imagepath = $(xml).find("imagepath").attr('dir') // here
detailpath = $(xml).find("detailpath").attr('dir') // and here
cSheet = contactSheet(xml);
$('.contactSheet')[0].appendChild(cSheet);
display($(cSheet).find('img')[0]);
}
Also, on this line:
jQuery.get('/new/content/portfolio/artcloth/gallery.xml' , 'xml' , function(data) { loadGallery(data); } ) // missing one here too
Actually, your Javascript files are missing semi-colons on the end too. Make sure you go through each file and add one to the end of each line.
Javascript does not actually require them, but for the sake of sanity and knowing exactly what your code is going it is a good idea to put them in. For example:
return
1
Can become:
return;
1;
Which returns nothing at all, not exactly the desired effect.
According to Microsoft Script Editor, there's an error inside jQuery caused by this line:
$('#lower').css('padding-left' , paddingLeft - (lowerRightProtrusion < 0 ? 0 : lowerRightProtrusion) + "px");
Since lowerRightProtrusion is NaN, and NaN < 0 calculates to false, you're actually setting padding-left to "NaNpx". Does not compute ;)
See my previous answer for info about MS Script Editor:
Using the IE8 'Developer Tools' to debug earlier IE versions
It would seem that IE is not picking up the styles. If I open the page in chrome, the "float:left" style appears on the description div. however, in IE this is not the case.
You currently have your includes in a div in the body of the document. If it is possible try moving these into the head. I'm talking about the link and script tags directly descendant of div id="pageHead".
(I am using IE6 and the developer toolbar to get this information)
In /common/css/generic.css:
div#information
{
margin-left:188px;
m\argin-left:94px; <------ not sure if that would cause this, but thought i would point it out
}

Categories