I'm trying to implement a simple auto sized textarea component with VueJS but I'm facing an issue with IE.
On this browser only, we can feel the height calculation. The size of the textarea changes twice and we can easily see the following content moving.
Here's how I'm doing it :
Each time the value changes, I'm calling the following resizeTextarea method :
resizeTextarea: function() {
// Set the height to auto to have a correct scrollHeight
this.textareaStyle.height = 'auto';
// Wait for the next tick to be sure that the heigh is set to 'auto'
this.$nextTick(this.setHeight);
},
With the referenced setHeight method :
setHeight: function() {
//IE COMPATIBILITY this.textareaStyle.height = `${this.$refs.input.scrollHeight}px`;
this.textareaStyle.height = ''.concat(this.$refs.input.scrollHeight, 'px');
},
As you can see, the process is quite simple :
Setting the textarea's height to auto;
After the value is updated, setting the height to the component's scrollHeight.
However, I have to wait the next tick to set the height and I'm guessing that this causes the clip with IE.
In my HTML template, I'm binding the textareaStyle data to the textarea component and I'm referencing it via a ref :
<textarea
v-model="message"
ref="input"
:style="textareaStyle"
></textarea>
You can found a working example here, please run it on IE and another browser to see the difference.
Notes :
I'm not using ES' syntax to ensure IE compatibility;
I've already tried to use the autosize package but the results are the same.
This issue may be due (and most certainly is) to my implementation of the auto sized textarea, so I'll consider this issue closed if the current system get fixed or if another solution (working in every modern browsers + IE 11) is found.
Related
I'm using a bootstrap 3 fluid grid to display thumbnails, and I love how the images scale in size as the browser is resized. The downside however, is a "big bang" effect when each page is loaded. That is, the grid begins collapsed then grows as images are added. I imagine a simple fix is to hardcode image sizes, but this would lose the scaling benefit I believe.
One attempt to fix this was to load a transparent placeholder image right before each thumbnail, which would of course be cashed on the first page of results and thus expand the grid faster. On callback for thumbnail loaded event, I remove the placeholder. This seems to help, but other times I still see the shifting as badly as before. In addition, with a slow connection you can actually for a moment see the real thumb below the placeholder.
<script type="text/javascript">
$(function(){
// For each thumbnail, insert a placeholder image.
// Once the thumb is loaded, remove the placeholder.
$("[id^=thumb-]").each(function(i, thumb) {
var $thumb = $(thumb)
var imgTag = "<img id='ph-" + (i + 1) +
"' class='placeholder' src='{% static "img/placeholder.png" %}'/>";
$thumb.parent().prepend(imgTag);
var $holder = $thumb.prev();
function loaded() {
$holder.remove();
}
if (thumb.complete) {
loaded();
} else {
$thumb.on('load', loaded);
$thumb.on('error', function() {
console.log('Error with thumbnail placeholders.');
});
}
});
});
</script>
Regarding compatibility, I'd like to at least have a usable site with older browsers, but it doesn't have to be perfect.
I'm not as interested in fixing my Javascript solution above as I am the best solution overall.
Please look at the live beta site here to help diagnose. I attempted a jsfiddle, but couldn't quite reproduce it. I will paste more context into the question once we understand what was wrong.
In this case, I would recommend adding the <img> tag to the plain HTML. Then set the src in your javascript function.
You'll also need to set height and width attributes on the <img> tags so their space is preserved, to prevent redrawing the page after the images are loaded. You could do this with a simple javascript function that determines the window.width and then sets the height and width attributes.
Something like this.
I'm quite new to Selenium so that question may be silly, but i cannot resolve it...
I'm trying to make a click() with Selenium (in Java, with Eclipse and Firefox and Chrome drivers) on an element that is definitely displayed and visible on the screen, but that returns false when i apply the isDisplayed() method on it. So i get an exception telling me that the element must be visible in order to perform an action on it.
I checked all parents div (i'm not using any iframe in my page), and some of them returns true as other returns false. Here is a small example of code of what i try to do :
<div id=1><div id=2><div id=3><div id=4><img that i want to click on with selenium\></div></div></div></div>
I want to click on the img with selenium, but it sees it as not displayed.
the img is marked as not displayed
the div4 is marked as not displayed
the div3 is marked as displayed by selenium
the div2 is marked as not displayed
the div1 is marked as displayed, as all parents div
But i definitely can see the image and others elements in the same div on my screen.
Any help on that point ?
Thanks !
EDIT : I use JS to modify these properties, particularly div 3, which is not displayed and marked as not displayed at loading, but then after e few action, it became (it is and is marked as) displayed.
Edit 2 : I found out that the styles of the two divs marked as not displayed by selenium have both the style display:block; (seen in the chrome dev tools). Any ideas ?
Edit3 : based on the link given in the comments, i add the computed style of the div :
div4 : it has non zero height and width, display is set on block. It even has a min width and min height.
div3 : it has non zero height and width, display is also set on block
div2 : it has a 0 height a non zero width and a display:block; so it might be the problem.
div1 : it has a 0 height, a non sero width, no display parameters, and hidden overflow-x and y. Thought this one is marked as deisplayed by Selenium...
Any ideas ?
I managed to solve my problem with a simple trick : call the Js function that is supposed to be triggered by the click, using
JavascriptExecutor js;
if (driver instanceof JavascriptExecutor) {
js = (JavascriptExecutor) driver;
} else {
throw new Exception(" Webdriver do not manage JS");
}
js.executeScript("function()");
Another solution that could be suitable is to use a Robot to use the mouse to click on this img, if you have its coordinates of course (or if you can compute it) :
Robot robot = new Robot();
robot.mouseMove(300, 300);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Though i did not find a solution to the displayed/not displayed problem.
Enjoy :)
Can anyone explain why the click handler is not invoked consistently in this example?
http://jsfiddle.net/4QBnf/
For instance, if you click in the upper left half of the div, it does not reliably increment the counter.
If I remove the padding-top from this block it works just fine:
.click-check:active {
background-color:blue;
padding-top: 25px;
}
I have tested this in a number of different browsers and it behaves the same way.
I found two possible issues with your code. You can view the fixes here:
http://jsfiddle.net/4QBnf/6/
CSS Box Model vs jQuery Box Model
Whenever you click on the top half of your box, you aren't technically clicking on .click-check, you are actually clicking on .count. This image shows the location of .count relative to .click-check:
jQuery counts this as a click on .click-check, but CSS doesn't. The number increments, but the CSS "active" effect isn't applied.
You can resolve this by removing the .count div and placing everything inside of .click-check.
jQuery Counter
The second issue is with your jQuery code. The code currrently reads:
$('.click-check').click(function() { $('.count').html(count++); });
count isn't increased until after this line is done. This means that the first click appears to have no effect.
This line will increment count, then display it to the user:
$('.click-check').click(function() { $('.click-check').html(++count); });
I've applied both updates to your example here:
http://jsfiddle.net/4QBnf/6/
Update
An alternate way to resolve the issue is to do everything through jQuery. This synchronizes all of the appearance and logic into a single box-model interpretation.
var count=0;
$('.click-check').mousedown(function() {
$('.click-check').addClass("active");
$('.click-check').html(++count);
setTimeout(function(){
$('.click-check').removeClass("active");
}, 50);
});
http://jsfiddle.net/4QBnf/15/
I'm using CKEditor as a rich text editor for my website. On that site I also have a custom image manager that I use in CKEditor using the "filebrowserImageBrowseUrl" config parameter.
This puts a "Browse Server" button in the image properties that lets me select a file from my image manager. This works just fine.
However, when I insert an image from my image manager and resize it in CKEditor this only adds a style attribute to the img tags. When people browse me website they will see the image as the size I want, but they also have to download a large amount of data, even if the image size is only a thumbnail.
My image manager has automatic resizing when you put a width and height as a query string to the image url.
How can I override the img tag CKEditor creates so that the selected width and height is put as query variables into the src attribute in the img tag in addition to the style attribute (so that CKEditor still knows which size the image has)?
I did find another question posted here: CKEditor: Customized HTML on inserting an image
But the answers for that question doesn't seem to work since the width and height from that example contains the image's original size instead of the custom size. I've also debugged the various variables from those methods without finding the custom size.
So the question remains: How can I override CKEditor's output HTML to put an image's size as query variables as well as in the style attributes where CKEditor puts it by default?
UPDATE
To make all the comments below a bit more comprehensive, here's a condensed version:
CKEDITOR.on('instanceReady', function (ev) {
var editor = ev.editor,
dataProcessor = editor.dataProcessor,
htmlFilter = dataProcessor && dataProcessor.htmlFilter;
htmlFilter.addRules( {
elements : {
$ : function( element ) {
// Output dimensions of images as width and height attributes on src
if ( element.name == 'img' ) {
var style = element.attributes.style;
if (style) {
// Get the width from the style.
var match = /(?:^|\s)width\s*:\s*(\d+)px/i.exec( style ),
width = match && match[1];
// Get the height from the style.
match = /(?:^|\s)height\s*:\s*(\d+)px/i.exec( style );
var height = match && match[1];
var imgsrc = element.attributes.src + "?width=" + width + "&height=" + height;
element.attributes.src = imgsrc;
element.attributes['data-cke-saved-src'] = imgsrc;
}
}
}
}
});
});
This code is run whenever the CKEditor generates the actual HTML, which happens when you either view the source by clicking the "Source" button, or by performing an HTTP POST of that page.
A small warning, though. The code above will keep appending the width and height query strings for each click on the "Source" button, or for each postback, so you might want to add some extra logic to filter out the width and height query strings before appending them to the src attribute.
If you look at the Output HTML sample in your copy of CKEditor you can see how it uses the htmlFilter to change the images to put the dimensions in attributes. Based on that code you can write your own code so that it changes the url of the image.
And be careful: URLs are protected to avoid problems with the browsers, so modifying the "src" attribute might not be enough. Look at the properties of the object that you are modifying.
I have a page with a for layout where one half of the page is dynamic width an the other is fixed. This is achieved by floating the fixed width side to the right. It all displays fine but because the fixed width markup comes before the dynamic width markup the tab ordering gets thrown off.
See here: http://jsfiddle.net/BaMqG/
How can i overcome this without resorting to putting tabindex properties on the inputs?
You can use jQuery to dynamically set the tabindexes with a loop and counter variable. Check it out. http://jsfiddle.net/BaMqG/22/
$(document).ready(function() {
var i = 1;
$('.wrapper').each(function(){
$(this).children('.dynamic').children('input').each(function(){
$(this).attr("tabindex",i);
i++;
});
$(this).children('.fixed').children('input').each(function(){
$(this).attr("tabindex",i);
i++;
});
});
});
The initial value for i can be set to whatever tabindex number you want to start from.
I have managed to get the same looking form with no tab index to work by using tables.
See here: http://jsfiddle.net/ymSGM/
I would still be interested if it can be done any other way.