Update
I recently discovered you can programatically create selections with Chrome which aren't continuous, by either replacing elements / textnodes inbetween in the parts you want unselected or hiding and then showing them.
Example of non-continuous selections for Chrome: http://jsfiddle.net/niklasvh/YKJBW/
var t = $('div').contents().get(0);
$.each(t.nodeValue.split(" "),function(i,e){
t = t.splitText(e.length);
if (t.length>0){
t = t.splitText(1);
}
});
var c = $('div').contents();
$.each(c,function(i,e){
if (i>0){
if (i%3) { }else{
e.parentNode.replaceChild($('<unselect />').text(e.nodeValue).get(0),e);
}
}
});
$('unselect').hide();
window.setTimeout(function(){
$('unselect').show();
},0);
However when performing the copy event, the whole selection does get selected (even if it has gaps in-between), but of course the same method can be used to programatically alter the selection before the copy event is performed.
The tricky part now is that can you actually make this functionality usuable by holding Ctrl down like you can in Firefox to create non-continous selections. The current method I use in the example breaks the TextNodes into many pieces, which for visual purposes does no difference. It however, also uses additional tags to break the selection, which as far as I've discovered, cannot be removed. However, the same functionality can be reached by deleting TextNodes and adding new ones in place for them. The problem is that it will only take into account the last node added, so if you have multiple spaces in your selection, it will only take into account the last DOM change you applied.
Can anyone think of any non-document breaking ways to apply this non-continous selections which does not make any permanent changes to the selection and its elements?
The original question
Is it possible to make selections which are non continous in Google Chrome? For example if you have an element with text like this:
<div>this is some random text</div>
Is it possible to make a selection which contains for example this is and text making the text in-between unselected?
This seems to work fine in FF, where you can addRanges which aren't next to each other, and the selection is made accordingly.
For IE, there doesn't seem to be anything that would allow you to have multiple ranges, but IE's selection object has a lot of other methods that compensate for it.
With non-continous selections, you could always append or prepend a selection a certain section from a website for example when performing copy actions, or force the user to unselect certain portions of their selections, which you don't want them to copy.
Example of non-continous selection:
working example (working at least in FF4).
edit
To perform the same type of selection manually, you can with firefox hold ctrl down and start dragging text in different positions, but performing it on chrome doesn't work.
edit 2
I guess this and this sum it up quite well. Looks like there isn't anything to be expected as far as webkit browsers are concerned.
No. Firefox is the only mainstream browser to support multiple selected ranges. I think the main use case for it was to allow selection of individual columns within tables, which is not possible otherwise.
WebKit are not planning to support multiple selected ranges any time soon, from what I can gather. IE overhauled its Range and Selection APIs for IE 9 and didn't implement it. No idea about whether Opera has any plans to support it. See this thread from the WHATWG mailing list for some information:
No, there is no concept of multiple text span selection. The selection is associated with the caret. One caret - one selection.
Related
I'm writing a web application that displays a large number of rows of data (~2000 at present), each of which has a drop-down "select" element with ~100 options. Any of those options can be selected by default. I'm generating all the actual DOM elements client-side. My problem: rendering this beast takes ~4 seconds on my relatively recent machine, which is really suboptimal. I know the problem is specifically with all the select elements, because replacing them with a bit of static text or a single-option list causes render time to be nigh imperceptible.
The vanilla code, minus failed experiments (see below) is here.
Avoiding the suggestions of "paginate your data" and "don't have so many options in a select", what is the most efficient way I can write my append / render code, assuming I do have a legitimate reason to display that much data and have that many options? For my purposes, Firefox is the only platform I care about.
Things I have tried:
Using an async loop to append rows to the table (slower than a regular loop, and oddly didn't render the intermediate results)
Building up a string that represents the body of the table and inserting it into the DOM in a single call (almost identical performance)
Instead of inserting the entire options list, inserting a single-option "select" element, and then populating the entire list when the "select" element gains focus (presumably because someone is trying to change it). This was actually pretty high-performing for the initial render, but then populating the element with the full list caused some weird behavior, losing focus and never actually being able to "open" the select element.
Right now my default assumption is that the third option is the way to go, and I need to figure out how to do some bookkeeping about what has already been populated. But my suspicion is that there is a plainly better / faster / more idiomatic way to do this. Is there?
Yes, I would "lazily" generate and/or populate the dropdowns.
That is, only create and populate the dropdowns when the user clicks on them, as probably almost all of the dropdowns in the 2000 rows will never be used right?
Perhaps a select element might not be the best UI here too, but instead some kind of HTML menu like so: https://jqueryui.com/menu/ that is created, populated and displayed only when the user clicks on some kind of button to display it.
How would you get the currently selected text within a textarea (and modify it)?
I've seen the select event that can be listened for, but I was wondering if there was a way to just get the currently selected text.
Also, what technique do you need to use in order to be able to modify that specific section of text within the textarea? I assume there's some way of finding out what the position of the selection is within the contents of the textarea as a whole?
What I want to be able to do is take the selection and modify it, or wrap it in certain tags etc., like you are able to do in the stackexchange text editor.
If you only have to support the latest browsers, you can use the selectionStart and selectionEnd properties which expose the character positions of the text selected in the textarea. You can't modify just the selected text but having updated the value you can use setSelectionRange to reselect the text.
I've posted what I consider the definitive function to do this in all browsers (including IE < 9) on Stack Overflow many times. Here's one example:
IE's document.selection.createRange doesn't include leading or trailing blank lines
I'd also recommend my jQuery plug-in for this, which includes this function and others to insert, delete, surround or replace the selected text, which sounds like exactly what you want. It's also the only jQuery plug-in for textarea selections I'm aware of that works correctly with line breaks in IE < 9.
From this page
http://www.netadmintools.com/art466.html
function display(txtarea) {
var sl = (txtarea.value)
.substring(txtarea.selectionStart, txtarea.selectionEnd);
}
<body onload="thisForm=document.frmKey;">
jquery field selection plugin..
Download Here examples on site.
The ::selection selector might work as well.
http://www.w3schools.com/cssref/sel_selection.asp
I'm looking for a rich text editor that allows for locking regions so that they can't be edited by the user. These locked regions would contain markup, not just plain text. TinyMCE has a plugin to support this but it is quite buggy.
Rather than having the RTE contain the content you don't want edited, why not just put multiple editors around only the areas you want users to edit?
The problem I see with doing it the other way is that you could have individual nodes within the editable text with contenteditable off, but those nodes could still be part of a larger edit (e.g., they could be deleted). To truly prevent them being edited you'd have to check the current selection whenever it changed and disable all user actions until the selection didn't include the locked content. Even if you did that, it would be tricky to make sure that a user didn't add content in a place they weren't supposed to (before the first node, say, assuming the first node was locked).
How can I detect text selection from a text search using the browsers Ctrl+F.
For example, I want to make a FAQ, where are the items are closed (to remove clutter), and clicking them opens the text within them, but at the same time I don't want Ctrl+F to be broken.
So I'm thinking, is there a way for JavaScript to detect that I have searched for some text within a non visible (but selectable) block of text, and to automatically open it.
Is it even possible to detect text selection from a search with Ctrl+F? If so, how?
A more specific example: I have a div with the id of "one" and a div with the id of "two"
both have their own text:
<div id="one">Google is a search engine</div>
<div id="two">Stackoverflow users are very informative</div>
both have their text hidden from view but still selectable, but not by mouse (using margins or covering)
So a user searches for "Stackoverflow" on this page, I want to trigger a JavaScript function upon the search selection (how??), and I need the function that runs to know which div, with what ID has some text selected.
This is browser dependent. In Chrome (maybe Webkit in general?), it seems to use a selection that is separate from the one in the DOM API.
However, Firefox will use the DOM selection when highlighting text from a Ctrl+F.
For example, go to google.com, and type this in Firebug:
window.getSelection().toString()
This will return ""
Now do a Ctrl+F, type in Privacy, press enter.
Enter the above command again in Firebug, and you will get:
"Privacy"
As far as I know, there is no way. The content of the search field entirely under the control of the browser, and you can't access this from within the page.
What you might be able to do however, is detect a selection in the document and react to that. This will however probably produce many false positives (because you can't distinguish between an ordinary selection and a search), and it won't work with browsers that do not use an ordinary selection to highlight search results.
More info on detecting selections: Introduction to Range on Quirksmode
Why not make the FAQ search friendly and use a service for that. Google Custom Search Engine might be a good place to start.
I am currently working on a Javascript program for my company (Leader Technologies) that is used to register products for Logitech. The URL for that is :
http://wwwtest.onlineregister.com/logitechreg/
My program looks totally fine on everything single web browser (including IE 6) that I have tried except Safari 4. On Safari 4, after a location, language and product category have been selected, when the actual product menu is clicked (id=WHPR), the div responsible for displaying the product is shown, but the drop-down selections are still visible. On all other browsers, the drop-down and the possible selections inside it in hidden (which is the intended behavior.)
Directly, my question is can I hid this drop-down successfully in Safari 4 WITHOUT completely emptying out the drop down and then repopulating it with only the selected value? I would rather not do this if at all possible, but if it's the only way to accomplish my goal then I can change the site additionally.
I believe the problem is where I set the listeners on the <select>:
<select id="WHPR" class="ui-formulate-ignore" style="width: 280px; visibility: visible;" onchange="whprChanged(this);" onfocus="displaySelector(form, document.getElementById('WHPR')); document.getElementById('imageHolder').focus(); this.blur();" name="WHPR">
Thank you all very much for taking the time to help me. I really appreciate all the help available on this site.
-Brian J. Stinar-
Not to pick on your style, but attaching listeners inline like you're doing is not very clean. Why not take advantage of jQuery's ability to deal with any browser discrepancies? The page you refer to is already loading it.
See http://docs.jquery.com/Events/bind
I think it's some kind of a bug in Safari - for example if you do .focus() nof for the DIV but for another input element like a textfield, then after clicking the selectbox both would have the focus (or actually, the focus would stay in the selectbox and the textbox would only seem to have the focus by having thicker border than usual).
Anyhow quick and dirty methot to achieve the goal would be removing the selectbox from the page (display: none) and then bringing it back (display:inline).
replace the this.blur() with the following command
this.style.cssText='display:none';var select = this; window.setTimeout(function(){select.style.cssText='display:inline';},1);
If you don't use a delay then it doesn't work - the removal and retrieval of the element need to be in different scopes.