I have a textarea that can be draged around in which text should still be selectable by draging over it. In order to distinguish a "over text drag" from a "move drag" I have to know weather the point where the user started its drag (i.e. mousedown position) was white space or text.
The only thing I can come up with to figure this out is calculating using character width and line height, which I would like to avoid.
Not really sure what you're asking, but here's my attempt to translate the insanity into working code:
let doc, htm, bod, I; // for use on other loads
addEventListener('load', ()=>{
doc = document; htm = doc.documentElement; bod = doc.body; I = id=>doc.getElementById(id);
// magic under here
const test = I('test');
function whiteStart(string){
if(string.match(/^\s+/)){
return true;
}
return false;
}
test.oncopy = test.ondragstart = function(){
let s = getSelection().toString();
if(whiteStart(s)){
console.log('"'+s+'" starts with one or more white spaces');
}
else{
console.log('"'+s+'" starts without a white space');
}
}
}); // end load
<div id='test'>I'm just going to put some text in here so we can run a very basic test. I hope this helps!</div>
Related
When modifying a feature, there is the option to delete a single vertex. According to the docs it says:
removePoint(){boolean}:
Removes the vertex currently being pointed.
(https://openlayers.org/en/latest/apidoc/ol.interaction.Modify.html)
Since I work on mobile devices, I would like to present a popup with a delete button next to the a vertex if a user clicks or hovers over it. Therefore I need the coordinates of this vertex. I can see the vertex indicated on the map with a different style, but how can I get it or its coordinates?
It must be somewhere in some selection because the automatic "pointing to" style and removePoint method works per se fine.
Here is a solution that use a button to delete a vertex.
The button is shown or hidden if there is a vertex to delete (it could be a popup).
It uses:
condition option to show the button if there is a point near the click
insertVertexCondition option to hide the button (there is no vertex here)
modifystart and modifyend event to hide the button (we are moving and we don't want the button to be visible)
removePoint function when click on the button
The button is not show if you're moving or if there is no point to delete.
It doesn't rely on features that are not documented or private.
You can see it in action here.
var btElt = document.getElementById("delete");
// Modify interaction
var mod = new ol.interaction.Modify({
source: vector.getSource(),
// Show on select
condition: function(e){
// Check if there is a feature to select
var f = this.getMap().getFeaturesAtPixel(e.pixel,{
hitTolerance:5
});
if (f) {
var p0 = e.pixel;
var p1 = f[0].getGeometry().getClosestPoint(e.coordinate);
p1 = this.getMap().getPixelFromCoordinate(p1);
var dx = p0[0]-p1[0];
var dy = p0[1]-p1[1];
if (Math.sqrt(dx*dx+dy*dy) > 8) {
f = null;
}
}
if (f) btElt.style.display = "inline-block";
else btElt.style.display = "none";
return true;
},
// Hide on insert
insertVertexCondition: function(e) {
btElt.style.display = "none";
return true;
}
});
// Hide on modifying
mod.on(['modifystart','modifyend'], function(){
btElt.style.display = "none";
});
map.addInteraction (mod);
// Delete vertex when click the button
function deleteVertex() {
mod.removePoint();
btElt.style.display = "none";
}
Alright digging into the source code I came up with a kinda ugly but so far working solution. For the record, this is the code.
this.modify = new Modify({
features: new Collection([this.selectedFeature]),
pixelTolerance:30,
condition: (event)=>{
if(this.modify["lastPointerEvent_"] && this.modify["vertexFeature_"])
this.removePointPopup.setPosition(this.modify["lastPointerEvent_"].coordinate);
else
this.removePointPopup.setPosition(undefined);
return true;
}
});
this.modify.on("modifyend",ev=>{
this.removePointPopup.setPosition(ev.target["lastPointerEvent_"].coordinate);
})
[...]
removePoint(){
this.modify.removePoint()
this.removePointPopup.setPosition(undefined);
}
If someone knows about a nicer solution, feel free to post it.
I'm creating dynamic scroll page, where I decided to use wheel event to detect user's scrolling. As you may know this event has a deltaY parameter that updates dynamically(several times for one scroll). I want the script to return true once deltaY is bigger than 100. However it updates over and over again causing my function shoot several times. Is there a way to 'bake'(be able to change once) this true value?
window.addEventListener('wheel', func)
function func(event){
if(event.deltaY>100){
var p = document.createElement('p');
var text = document.createTextNode("You scrolled over 100");
p.appendChild(text);
document.body.insertBefore(p, document.getElementsByTagName('p')[0]);
}
}
<p>Scroll the page down \/ and keep scrolling</p>
You could remove the listener once the element has been added. this way the function will not continue to fire.
window.addEventListener('wheel', func)
function func(event){
if(event.deltaY>100){
var p = document.createElement('p');
var text = document.createTextNode("You scrolled over 100");
p.appendChild(text);
document.body.insertBefore(p, document.getElementsByTagName('p')[0]);
window.removeEventListener('wheel',func);
}
}
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
so I currently have a nav bar that consists of text, and an image above that text. When I hover on the text, the image is highlighted, and vice versa. Say, I hover on the 'Home' image, it should also highlight the image. Now, this works just fine, but my problem is that, if you move the mouse around too fast, either the text or the image will remain highlighted, which is slightly annoying. I'm just wondering if there's anything that I can do about this, if not, it's not like it's a huge deal.
My code, which is unfortunately, a bit hackey:
<script>
function handleEnter(elem) {
elem = elem.target;
var location = -1;
var image_elem = null;
if ($(elem).hasClass('menutext')) {
location = $(elem).parent().parent().index() + 1
image_elem = $('.menuimgwrap:nth-child('+ location +')')
$(elem).parent().parent().addClass('hovering');
$(image_elem).addClass('hovering');
} else if ($(elem).hasClass('menuimgwrap')) {
location = $(elem).index() + 1
image_elem = $('.menuitem:nth-child('+ location +')')
$(elem).addClass('hovering');
$(image_elem).addClass('hovering');
}
}
function handleLeave(elem) {
elem = elem.target;
var location = -1;
var image_elem = null;
if ($(elem).hasClass('menutext')) {
location = $(elem).parent().parent().index() + 1
image_elem = $('.menuimgwrap:nth-child('+ location +')')
$(elem).parent().parent().removeClass('hovering');
$(image_elem).removeClass('hovering');
} else if ($(elem).hasClass('menuimgwrap')) {
location = $(elem).index() + 1
image_elem = $('.menuitem:nth-child('+ location +')')
$(elem).removeClass('hovering');
$(image_elem).removeClass('hovering');
}
}
$('.menuitem, .menuimgwrap').hover(handleEnter, handleLeave);
</script>
When the text is highlighted, it's handled by the menutext selector, and when the image is highlighted, it's handled by the menuimgwrap selector. It then figures out which navbar element was highlighted, and then decides which image or text the said element matches up with, and highlights that one too.
How can I fix this, so that it doesn't stay highlighted if the mouse is moved too fast over the navbar?
Thanks
Change this to use CSS instead. The basic hover would be like the following:
<style>
.menuItem:hover {
background-color: red;
}
</style>
<a href='#' class='menuItem'>
<img src='image.png' />
Home
</a>
How do I flow a text stream from one div to the next? Each div has a fixed height and width and I need the data to be passed to the first, then if that is filled overflow to another etc. (The second etc. divs need to be dynamically created). Eventually the divs will be contenteditable, this is the page technique for a simple WYSIWYG style editor.
Please help...
JS Fiddle (note zoom in use on body)(I need to reflow on keyup/down, make pages and remove as necessary and be able to add in the middle)
function loadgo(){
run();
var h = document.getElementById('page'+(document.getElementById("pagecount").value-1)).offsetHeight;
document.getElementById("loadgo").value = h+1;
if (h > 1135){
var pagecount = document.getElementById("pagecount").value;
//$('body').append("<div class=page style='color:#F00' id='page"+pagecount+"' contenteditable>"+this.id+"</div>");
var objTo = document.body;
var divtest = document.createElement("div");
divtest.style.color = '#F00';
divtest.id = "page"+pagecount;
divtest.className = 'page';
divtest.contentEditable = "true";
divtest.innerHTML = "new div";
objTo.appendChild(divtest);
document.getElementById("page"+pagecount).focus();
document.getElementById("pagecount").value++;
zoomin();zoomout();
run();
}
}
function run(){
setTimeout(function() {
loadgo();
}, 500);
}
loadgo();
What you're looking for is called CSS Regions. This allows your text to flow through various containers placed on your site.
You can read about it on Adobe's site, and Apple has a nice WWDC video explaining how to implement it (starts at 8:40). Also check out the Editor's Draft.
yeah i have a problem.
So i have a script which puts all footnotes at the end of the document and makes crossreferences from the little number in text to the fitting endnote.
now i want to add a backlink, so when i have a long document(book) i dont have to scroll back by hand, but can just click on the endnote and get back.
by now i have managed to get the endnotes as crossref sources, but i struggle with the crossrefdestination
when i use footnote.storyOffset as destination, it screws up the numbering of the footnotes in text.
for example the first footnote just disappears from text, then there comes 1,3,3,4,5,7... and so on. why does this happen?? im just using this insertion point as destination and suddenly it screws up everything.
it would also be enough to put the footnote numbers manually into the text, but i dont know how to delete the scrambled numbers in the text.
i could also use the next or previous character as insertionPoint, but how do i get there?
Im pretty new to that indesign script stuff. hope somebody can help me.
here is the critical part of the source:
stories[j].insertionPoints[-1].contents = SpecialCharacters.PAGE_BREAK; // add new page for notes
stories[j].insertionPoints[-1].contents = 'Notes';// title
footn = stories[j].footnotes;
for (var i = 0; i < footn.length; i++)
{
stories[j].insertionPoints[-1].contents = '\r';
endnote = footn[i].texts[0].move (LocationOptions.after, stories[j].insertionPoints[-1]);
endnote.applyParagraphStyle (note_styles.first, false);
if (i === 0)
{
endnote.numberingContinue = false;
endnote.numberingStartAt = 1;
}
if (endnote.paragraphs.length > 1)
{
endnote.paragraphs.itemByRange (1,-1).applyParagraphStyle (note_styles.next, false);
}
//var stoff = footn[i].storyOffset;
//stoff.contents = ''+(i+1);
//stoff.applyCharacterStyle(note_styles.char_style_in_text);
//stoff.appliedCharacterStyle.position= Position.superscript;
backlink_destination = doc.paragraphDestinations.add (footn[i].storyOffset); // position of footnote in text
endnote_destination = doc.paragraphDestinations.add (endnote.insertionPoints[0]);
try
{
crb = app.activeDocument.crossReferenceFormats.add({name:'backlink'+i});
crb.appliedCharacterStyle = note_styles.char_style_endnote;
crb.buildingBlocks.add (BuildingBlockTypes.customStringBuildingBlock);
crb.buildingBlocks.anyItem().customText = endnote.contents;
}
catch(_)
{
crb = app.activeDocument.crossReferenceFormats.item ('backlink'+i);
};
backlink_source = doc.crossReferenceSources.add (endnote, crb); // position of note at end of story
endnote_source = doc.crossReferenceSources.add (footn[i].storyOffset, note_styles.cr_format);
doc.hyperlinks.add(backlink_source, backlink_destination, {visible: false}); //add link from notes to text
doc.hyperlinks.add(endnote_source, endnote_destination, {visible: false});
} // for
fixed it:
i just flipped the order of making the crossrefs.
i flipped the following lines
backlink_destination = doc.paragraphDestinations.add (footn[i].storyOffset);
endnote_destination = doc.paragraphDestinations.add (endnote.insertionPoints[0]);
to
endnote_destination = doc.paragraphDestinations.add (endnote.insertionPoints[0]);
backlink_destination = doc.paragraphDestinations.add (footn[i].storyOffset);
and
backlink_source = doc.crossReferenceSources.add (endnote, crb);
endnote_source = doc.crossReferenceSources.add (footn[i].storyOffset, note_styles.cr_format);
to
endnote_source = doc.crossReferenceSources.add (footn[i].storyOffset, note_styles.cr_format);
backlink_source = doc.crossReferenceSources.add (endnote, crb);
and
doc.hyperlinks.add(backlink_source, backlink_destination, {visible: false});
doc.hyperlinks.add(endnote_source, endnote_destination, {visible: false});
to
doc.hyperlinks.add(endnote_source, endnote_destination, {visible: false});
doc.hyperlinks.add(backlink_source, backlink_destination, {visible: false});
i dont know why, but it works when put in this order... this doesnt testify to good software...
how could i expect good software for that price?