Get text in CSS3 column? - javascript

I'm using CSS3's support for columns support in a project (so far I've found it much more robust and dependable than most JavaScript solutions out there).
Question: Is it possible to get the text that is in a specific column, in any way?

And...what, two months later? I finally found the answer to this question. It's reliant on document.caretRangeFromPoint (Webkit) or document.caretPositionFromPoint.
var getAllTextInColumn = function(rect){
/*
rect should be the size and x,y of the column
{ top, left, width, height }
*/
if(document.caretRangeFromPoint){
var caretRangeStart = document.caretRangeFromPoint(rect.left, rect.top);
var caretRangeEnd = document.caretRangeFromPoint(rect.left+rect.width-1, rect.top+rect.height-1);
} else {
return null;
}
if(caretRangeStart == null || caretRangeEnd == null) return null;
var range = document.createRange();
range.setStart(caretRangeStart.startContainer, caretRangeStart.startOffset);
range.setEnd(caretRangeEnd.endContainer, caretRangeEnd.endOffset);
return range.toString();
};

My only guess is to start replacing spaces with a SPAN, then detecting when the vertical position of that SPAN gets smaller, then you know you're in the next column. This last SPAN becomes a column marker.
You can then copy the text that is between the beginning/end and/or a column maker.

Related

retain CKEditor scroll bar at cursor position

I'm using the similar code to retain cursor position for ckeditor.
var range = null;
editor.on( 'blur', function() {
range = editor.getSelection().getRanges()[ 0 ];
});
someElement.on('click',function() {
var editor = CKEDITOR.instances.editor1;
if(editor){
editor.focus();
range.select();
}
});
I'm able to retain cursor position but the scrollbar scrolls to the top.
How can i keep/retain the scrollbar at same position as of cursor's?
range.select().scrollIntoView() helped me out!!
I have several editors on a long page, and scrollIntoView() never did exaclty what I wanted: either it scrolled laso the container page, or it doesn't, or it puts the elemnt to show just one line after the viewport... so, since my need was simply to return to the previous position after a small change in the HTML with setData(), I could do the following:
let window = editor.document.getWindow().$ ;
let scrollX = window.scrollX ;
let scrollY = window.scrollY ;
[...]
editor.setData(contents, {
callback: function() {
editor.document.getWindow().$.scrollTo(scrollX, scrollY) ;
}
}) ;
I don't think that CKEditor (at least, not the 4.x series) has the proper APIs for this, so I had to go to the underlying DOM.

Issue calculating table scrollbar location

So I have a script that adds a slight shadow to table edge where you can scroll, depending on the location of the scrollbar, but it sometimes doesn't work.
This is one part of it:
$('table').on('scrollstart scrollstop', function(){
if($(this).parent().hasClass('table-wrap')){
var elem = $(this),
elemBody = elem.find('tbody'),
elemParent = elem.parent('.table-wrap');
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() - elem.scrollLeft());
if(scrolled === 0){
elemParent.addClass('left_active');
elemParent.removeClass('right_active');
} else if(elem.scrollLeft() === 0) {
elemParent.removeClass('left_active');
elemParent.addClass('right_active');
} else {
elemParent.addClass('left_active');
elemParent.addClass('right_active');
}
}
});
This part sometimes I have to add "+1" to "elem.scrollLeft() --here---); to make it work.
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() -
elem.scrollLeft());
But then I noticed, some tables it helps and on others, it stops working. Meaning when I scroll to right the 'right_active' class will not disappear.
Any suggestions?
Have you tried including scrollbar width in your calculation for var scrolled?
var scrolled = (elemBody.outerWidth() - elemParent.outerWidth() - elem.scrollLeft());
I think you are on the right track but the width is probably not precise since .outerWidth() doesn't include scrollbar width. Hence, the maximum scroll width is always greater than the actual element width.

Resize table columns with mouse

I am writing a script to allow a client to mouse drag table cell borders and resize columns in a table. So far I have a working model in Firefox but there is a flaw in width measurement that leaves the mouse out of sync when the change gets large. Worse, the script fails in other browsers (opera,safari) or even if I change the browser zoom in Firefox.
function doDrag() {document.body.style.cursor='crosshair';}
function noDrag() {document.body.style.cursor='auto';}
var xpos=0;
var sz=0;
var dragObj = {};
function resizeOn(el)
{
dragObj = document.getElementById(el);
document.addEventListener("mousemove",resize, true);
document.addEventListener("mouseup",resizeOff, true);
}
function resize(ev)
{
if(xpos == 0) {xpos=ev.clientX;}
if(xpos != ev.clientX)
{
sz = dragObj.offsetWidth + (ev.clientX - xpos);
dragObj.style.width = sz - 10 + "px";
alert("size="+sz+" offsetwidth="+dragObj.offsetWidth);
if(dragObj.offsetWidth != sz)
{
resizeOff();
return false;
}
xpos=ev.clientX;
}
}
function resizeOff()
{
xpos = 0;
document.removeEventListener("mousemove",resize, true);
document.removeEventListener("mouseup",resizeOff, true);
}
The HTML looks like:
<th id="col0" class="edit">client</th>
<th class="drag" onmouseover="doDrag()" onmouseout="noDrag()" onmousedown="resizeOn('col0')"></th>
The second cell is made to appear as the right edge of the first.
I assume the problem is dragObj.style.width = sz - 10. The -10 was derived purely by trial and error. I suspect this is the difference between the actual width of the cell including borders, padding etc and offsetwidth. It should really be, per my css, 10 for padding + 1 for the left border = 11px. Either my fixed padding/borders aren't staying fixed or there is some other css property between the offsetWidth and the actual with of the element. Is there some way to get the actual width of the element regardless of the browsers scaling?
Have a look at the documentation in www.quirksmode.org and/or http://help.dottoro.com. Confirm whether the properties are supported by your target browser. They also have comments on how zoom affects offsetX and similar.
Also, you should note that ev.clientX has been broken in IE by a recent patch (KB2846071). If the patch is installed, clientX returns a meaningless result.
Hopefully MS will release a patch for their patch!

Detect if element has a background specified?

I'm trying to determine if an element has a background explicitly set. I figured I could just check to see if .css('background')* was set, however, it's inconsistent between browsers. For example, chrome shows an element without a background set as
background: rgba(0, 0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box
background-color: rgba(0, 0, 0, 0)
background-image: none
whereas IE8 shows
background: undefined
background-color: transparent
background-image: none
(test case here)
*(shorthand properties of CSS aren't supported for getting rendered styles in jQuery)
Short of handling each separate case is there a better way to detect this?
temporary element approach
It's not ideal, but you could create a temporary element when your js initiates, insert it somewhere hidden in the document (because if you don't you get empty styles for webkit browsers) and then read the default background style set for that element. This would give you your baseline values. Then when you compare against your real element, if they differ you know that the background has been set. Obviously the downside to this method is it can not detect if you specifically set the background to the baseline state.
var baseline = $('<div />').hide().appendTo('body').css('background');
var isBackgroundSet = ( element.css('background') != baseline );
If you wanted to avoid possible global styles on elements, that would break the system i.e:
div { background: red; }
... you could use the following instead, but I doubt if it would work so well with older browsers:
var baseline = $('<fake />').hide().appendTo('body').css('background');
background
I spent some time with a similar issue - attempting to get the original width value from an element when set to a percentage. Which was much trickier than I had assumed, in the end I used a similar temporary element solution. I also expected, as Rene Koch does above, that the getComputedStyle method would work... really annoyingly it doesn't. Trying to detect the difference between the source CSS world and the runtime CSS world is a difficult thing.
This should work:
function isBGDefined(ele){
var img = $(ele).css('backgroundImage'),
col = $(ele).css('backgroundColor');
return img != 'none' || (col != 'rgba(0, 0, 0, 0)' && col != 'transparent');
};
DEMO
I didn't bother to test against the background property because in the end, it will change the computed styles of either backgroundImage and/or backgroundColor.
Here's the code run against your test case (with another added): http://jsfiddle.net/WG9MC/4/
this article explains how:
http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/
function getStyle(oElm, strCssRule){
var strValue = "";
if(document.defaultView && document.defaultView.getComputedStyle){
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
}
else if(oElm.currentStyle){
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
return p1.toUpperCase();
});
strValue = oElm.currentStyle[strCssRule];
}
return strValue;
}
Using the approach suggested by #pebbl I wrote a small jQuery function, hasBack(), to determine if an element has its background set.
$.fn.hasBack = function()
{
var me = $.fn.hasBack;
if(!me.cache)
{
// get the background color and image transparent/none values
// create a temporary element
var $tmpElem = $('<div />').hide().appendTo('body');
$.fn.hasBack.cache = {
color: $tmpElem.css('background-color'),
image: $tmpElem.css('background-image')
};
$tmpElem.remove();
}
var elem = this.eq(0);
return !(elem.css('background-color') === me.cache.color && elem.css('background-image') === me.cache.image);
}
This was tested in Chrome v22, Firefox v15, Opera 12.1, IE9, IE9 set to browser modes 9 compat, 9, 8, 7 and quirks mode.
Test case here.

Range issue with ui-slider

I’m trying to set up a range with a slider. I would prefer if both cursors did not overlap in the same value. In other words, how do I get the sliders to freeze and stay put when the minimum value slider and the maximum value slider come next to each other. Any ideas? Thank you in advance.
Returning false from the slide function when they're about to collide seems to work: http://jsbin.com/eyoge3/3
Code from the jsbin:
slide: function(event, ui) {
var oldMin = $("#slider").slider("values", 0);
var oldMax = $("#slider").slider("values", 1);
var newMin = ui.values[0];
var newMax = ui.values[1];
if( oldMin != newMin && newMin == oldMax )
return false;
else if( oldMax != newMax && newMax == oldMin )
return false;
}
jQuery UI slider range extension
I needed something similar so I've written an extension over existing jQuery UI slider plugin/widget. These are additional options that this extension supports:
minimum and maximum range size - minimum range size is exactly what you're after
limiting lower and upper range boundary values - this sets the maximum value for the lower range boundary handle and minimum value for the upper range boundary handle
automatic range sliding - this allows to drag (any) handle over the limit of maximum range size which in turn drags the other handle along.
You can get the code on my blog (it gets updated so I'm not publishing it here directly).
I was searching for a solution to this when doing custom-styled slider yesterday.
Nothing worked from what I found, then I came up with an easy one myself:
1.Put the slider into container div with left and right padding
<div class="slider-container">
<div class="slider-main ..."></div>
</div>
2.Set the styles of
-container (left and right padding to half slider-handle width) slider
-handle (left-margin to minus half of its width)
Something like this (im writing from memory)
<style>
.slider-container {
padding-left: 8px;
padding-right: 8px;
}
.slider-handle {
width: 16px;
margin-left: -8px;
}
</style>
You should also remove styling from slider-main and move it from there to slider-container

Categories

Resources