Is there a faster way to empty a HTML Select box? - javascript

I have an HTML Select box with about 1800+ options. In my javascript I have the following line to empty the select box so I can repopulate it.
box.options.length = 0;
In Firefox this runs fairly quickly, but IE takes a couple of seconds. Is there a faster way to do this in IE?

At some point I have worked around IE's dismal performance in this area by enclosing list object in a div and then when I needed to reset it I would just set innerHTML of that div to a brand new empty list html tag. I'm sketchy on the details but I think that's what I did and it worked.
Please don't tell anybody I suggested this to you.

One way that should be faster is to create a new select box with the same properties (but no options, of course), and replace the existing box with it.

You could use box.innerHTML="". In my test, it is 68% faster:
http://jsperf.com/emptying-a-select-box/4.
Update: in 2015 box.innerHTML = "" is by multiple orders of magnitude the slowest option. :-) Use box.options.length = 0 instead.

Related

Listen to specific changes on contenteditable?

Warning: not duplicate with existing questions, read through
I know I can have an event listen on changes on an contenteditable element.
What I would like is to be able to know what the changes are.
For example:
inserted "This is a sentence." at position X.
deleted from position X to Y.
formatted from X to Y with <strong>
Is that possible? (other than by doing a diff I mean)
The reason for this is to make a WYSIWYG editor of other languages than HTML, for example Markdown.
So I'd like to apply the changes to the Markdown source (instead of having to go from HTML to Markdown).
You may be able to do something with MutationObservers (falling back to DOM Mutation events in older browsers, although IE <= 8 supports neither) but I suspect it will still be hard work to achieve what you want.
Here's a simple example using MutationObservers:
http://jsfiddle.net/timdown/4n2Gz/
Sorry, but there is no way to find out what the changes are without doing a diff between the original content and the modified one when changes occur.
Are you looking for this
var strong=document.createElement("strong");
var range=window.getSelection().toString().getRangeAt(0);
range.surroundContents(strong);
this was for third part
You just need to select what you want to surround using real User interaction.
If you wanna do it dynamically
var range=document.createRange();
range.setStart(parentNode[textNode],index to start[X])
range.setEnd(parentNode[textNode],index to end[Y])
range.surroundContents(strong);
For 2nd Part
range.deleteContents()
1st part can be done by using simple iteration
var textnode=// node of the Element you are working with
textnode.splitText(offset)
offset- position about which text node splitting takes place[here==X]
Two child Nodes have been created of the parent editable Element
Now use simple insertBefore() on parent editable Element Node.
hope you will find it useful
The API you're looking for does not exist, as DOM nodes do not store their previous states.
The data / events you're wishing to get back are not native implementations in any browser Ive come across, and I struggle to think of a datatype that would be able to generically handle all those cases. perhaps something like this:
function getChanges() {
/* do stuff here to analyse changes */
var change = {
changeType : 'contentAdded',
changeStart : 50, /* beginning character */
changeContent : 'This is a sentence'
}
return change;
}
Since you're trying to get custom events / data, you're probably going to need a custom module or micro-library. Either way, to look at the changes of something, you need somehow be aware of what has changed, which can only be done by comparing what it was to what it is now.

How to prevent child from one element to be on top of another element

(Okay, I know the questions probably sounds rancid bad, so someone edit if they they know how to reformulate it).
So, basically I have this: jsFiddle
And as you can probably see, I'm trying to re-create a basic windows 7 aero effect (curiosity, fun, learning, etc nothing big), but I stumbled into a few problems.
(I will explain only vaguely, since you can see it on the fiddle and otherwise it would be a textathon)
The text is stuck on top of the parent's(div) parent(div) element.
The text somehow leaks out of the duplicate element(div), even thought it doesn't from the original.
I know this all sounds odd, but you'll probably best see it on the fiddle.
Thank you.
I think the problem you're having is stemming from this:
$(container).find('*').each(function() {
var e_clone = $(this).clone(false).appendTo(processor);
// etc etc
});
By using the * selector then running .each you are cloning more markup into #processor than I think you might have intended to. You get two copies of span.lol in there because first it clones #box (including all its children) and then on the next iteration through the each it copies over span.lol on it own.
As for the "leaking" of text out of the parent, it does happen in the original... at least that's what I see in Chrome if I comment out the call to glass('#container', '#processor').

Is there a way to lengthen a <textarea> by one row every time the user types in the next row with javascript?

I have a <textarea> that I want to grow by one row every time the user enters into the last row shown in the <textarea>. Is this possible?
I have seen it done before, but can't figure out how to do it.
Okay, I just created this off the top of my head, so there may be browser compatibility issues. The concept is pretty simple however. Basically, on every keyup event, append a newline to the current text in the textarea element, then check if scrollHeight is greater than offsetHeight. If this is the case, set the elements height to be equal to scrollHeight. After all this, remove the appended newline. Assuming your textarea element has the id ta:
EDIT -- Okay, my original idea caused the cursor position to jump to the end of the text even if the user moved the cursor back, not good. The fix I came up with involves creating an invisible clone of the text area, and inserting the extra newline in that one, as to not disturb the cursor position in the visible one. Not sure I'm enterily comfortable with this method, but it works for now. If there is a better method I'd be happy to hear it. Here's the updated code:
var shadow = document.createElement('textarea');
shadow.className = 'autosize';
shadow.style.visibility = 'hidden';
document.getElementById('ta').onkeyup = function() {
this.parentNode.appendChild(shadow);
shadow.value = this.value + '\n';
if (shadow.scrollHeight > shadow.offsetHeight) {
this.style.height = shadow.scrollHeight + 'px';
}
this.parentNode.removeChild(shadow);
};
And the updated test http://jsfiddle.net/7wezW/1/
Now back to your regular programming...
Works well in Chrome, if someone points out issues in other browsers, I will try work them out.
PS, I should point out that if the user pastes text using just the mouse, the size of the textarea element will not adjust. Should be a trivial issue, but I'll leave it out as not to over-complicate things.
There are code and a demo at http://webdesign.torn.be/tutorials/javascript/prototype/auto-expand-contract-textarea/.
There's also a non-IE6 version that doesn't use frameworks:
http://scrivna.com/blog/2008/04/12/javascript-expanding-textareas/
Yes, there are many plugins for JQuery, such as this one, which comes with a demo: http://james.padolsey.com/javascript/jquery-plugin-autoresize/
Very customizable in terms of maximum height, buffer space, etc.

JavaScript: Quickly insert text into long textarea

I am playing around with creating an HTML-textarea based plain text editor to edit my scripts (using e.g. Mozilla Prism + a localhost install/ webserver). It works fine so far, but when I want to insert something at the cursor position, it gets slow in Firefox when there is a lot of text in the textarea (Chrome works fine). E.g. with 133k filled in the textarea it takes around 1 sec to perform inserting 4 spaces.
I already have and use elm.selectionStart and elm.selectionEnd. Based on these I then copy the text, manipulate it, and set the value back into the textarea -- perhaps that is what's causing the bottleneck (I'm using the similar approach as answered on this site before). Ideally, I would probably like to have something like elm.selectedText = 'foobar' but can't find this...
It doesn't necessarily need to be crossbrowser...
Can someone help?
According to this article on codemirror, using designMode is faster than using a textarea, because you can edit parts of the content instead of editing the whole text in one go.
There's an API that replaces the selected text: textarea.setRangeText('text').
Here's a demo:
const textarea = document.querySelector('textarea');
textarea.addEventListener('click', () => {
textarea.setRangeText('WOW');
});
<textarea rows="10" cols="40">Click anywhere or select any text in here. It will be replaced by WOW</textarea>
There's also document.execCommand('insertText') with undo support but it's not cross-browser. Try insert-text-textarea for a cross-browser solution.

prefilling dynamically created textbox with javascript in IE

I'm trying to dynamically add some textboxes (input type=text) to a page in javascript and prefill them. The textboxes are coming up, but they are coming up empty. What is the proper way to pre-fill a textbox. Ideally I'd love to use the trick of creating a child div, setting the innerhtml property, and then adding that div to the parent main div but that didn't work. Then I thought I'd use the dom but setting textboxname.value before or after insertion won't work and doing txttextbox.setattribute('value','somevalue') won't work either. Works fine in firefox. What gives? This has to be possible? Here is my code. I know I'm only using string literals, but these will be replaced with the results of a web service call eventually. Below is some code. Oh and how do you format code to show up as you type it? I thought it said to indent four spaces, and I did that but the code is still on one line. Sorry about that.
var table=document.createElement('table');
var tbody=document.createElement('tbody');
var row=document.createElement('tr');
row.appendChild(document.createElement('td').appendChild(document.createTextNode('E-mail')));
var txtEmail=document.createElement('input');
row.appendChild(document.createElement('td').appendChild(txtEmail));
tbody.appendChild(row);
table.appendChild(tbody);
//document.getElementById('additionalEmails').innerHTML="";
document.getElementById('additionalEmails').appendChild(table);
txtEmail.value = 'my text'
Does not work?
You can also use Prototype to do this easily:
document.body.insert(new Element("input", { type: "text", size:20, value:'hello world' }))
I've encountered problems similar to this in the past, and while my memory is a bit fuzzy on why it was happening exactly, I think you may need to make sure the element is actually added to the DOM before modifying its value. e.g:
var txtEmail=document.createElement('input');
document.getElementById('someElementThatAlreadyExists').appendChild(txtEmail);
txtEmail.value = 'sample text';
I ended up solving this problem by injecting the html directly into a page via a child div. That did work, it's just that I am blind and the software I use to read the screen for some stupid reason failed to see the text in the textbox. Go figure. Thanks for the tip on prototype though, if I ever decide not to cheat and add the eleements to the dom directly, I'll do it that way.

Categories

Resources