JQuery Terminal typing animation not displaying special HTML characters or class styles until after animation completes - jquery-terminal

I'm using code from the JQuery Terminal examples to emulate typed animation in a console window. I can get the animation to work as intended, but during the course of the animation special HTML characters do not display until after the animation completes. For example, while the animation is running, the console renders '\' instead of ''
This problem also applies to styles assigned to the class of any div that's being animated. The styles do not show up until after the animation is complete.
Below is the code used to animate (adapted from the JQuery Terminal examples page):
var anim = false;
function typed(finish_typing) {
return function(term, message, delay, finished, classname) {
anim = true;
var prompt = term.get_prompt();
var c = 0;
if (message.length > 0) {
term.set_prompt('');
var interval = setInterval(function() {
term.insert(message[c++]);
if (c == message.length) {
clearInterval(interval);
// execute in next interval
setTimeout(function() {
// swap command with prompt
finish_typing(term, message, prompt, classname);
anim = false
finish && finish();
}, delay);
}
}, delay);
}
};
}
var typed_message = typed(function(term, message, prompt, classname) {
if (typeof classname === "undefined") { classname = "default"; }
term.set_command('');
term.echo(message, {
finalize: function(div) { div.addClass(classname); }});
term.set_prompt(prompt);
});
And an example of how it's being called:
E.match(/^\s*ping\s*$/i)?
typed_message(N, "PONG", 10, function(){finished = true;}, "pong"):
In this case, styles applied to the "pong" class that's assigned to the div output by typed_message do not display until after the text is finished typing.
Is there a way to go about having the styles or special characters display while the animation is running?

Slightly modified typed animation using set_prompt instead of insert, also $.terminal.substring and length (that last one need to go to $.terminal.length).
var anim = false;
function typed(finish_typing) {
return function(term, message, delay, finish) {
anim = true;
var prompt = term.get_prompt();
var c = 0;
if (message.length > 0) {
term.set_prompt('');
var new_prompt = '';
var interval = setInterval(function() {
// handle html entities like &
var chr = $.terminal.substring(message, c, c+1);
new_prompt += chr;
term.set_prompt(new_prompt);
c++;
if (c == length(message)) {
clearInterval(interval);
// execute in next interval
setTimeout(function() {
// swap command with prompt
finish_typing(term, message, prompt);
anim = false
finish && finish();
}, delay);
}
}, delay);
}
};
}
function length(string) {
return $('<span>' + $.terminal.strip(string) + '</span>').text().length;
}
var typed_message = typed(function(term, message, prompt) {
term.set_command('');
term.echo(message);
term.set_prompt(prompt);
});
$('body').terminal(function(command, term) {
typed_message(term, '[[;#fff;;class_name]hello]', 400);
});
body {
min-height: 100vh;
margin: 0;
}
.class_name {
text-decoration: underline;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.8.0/js/jquery.terminal.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/1.8.0/css/jquery.terminal.min.css" rel="stylesheet"/>
The example on the site was updated accordingly.

Related

kendo editor: prevent keydown not working

I would like to prevent the pressing of ENTER if the kendo editor body has a certain height (to limit the max height of the editor field). But none of my tries worked.
<textarea data-role="editor"
data-bind="events: { keydown: onEditorKeyDown }">
</textarea>
viewModel.onEditorKeyDown = function (e) {
var key = e.keyCode;
if (key == 13) {
var editor = e.sender;
var body = editor.body;
var height = body.scrollHeight;
if (height > 195) {
?? //tried e.preventDefault(), return false etc.
}
}
};
I've managed to find two solutions. One is dirty hack and other doesn't match your requirements 100%. But both perform what is needed more or less.
New paragraph is added via embedded editor insertParagraph command which overrides default keydown logic. So the first solution is to temporary override this command using keydown and keyup events like this:
<textarea data-role="editor"
data-bind="events: { keydown: onEditorKeyDown, keyup: onEditorKeyUp }">
</textarea>
// this should probably be moved to viewModel, it's here for demo puproses only
var savedCommand;
var viewModel = kendo.observable({
html: null,
isVisible: true,
onChange: function() {
kendoConsole.log("event :: change (" + kendo.htmlEncode(this.get("html")) + ")");
}
});
viewModel.onEditorKeyDown = function (e) {
var key = e.keyCode;
if (key == 13) {
var editor = e.sender;
var body = editor.body;
var height = body.scrollHeight;
if (height > 195) {
savedCommand = editor.toolbar.tools.insertParagraph.command;
editor.toolbar.tools.insertParagraph.command = function() {};
}
}
};
viewModel.onEditorKeyUp = function (e) {
var key = e.keyCode;
if (key == 13) {
if (savedCommand) {
var editor = e.sender;
editor.toolbar.tools.insertParagraph.command = savedCommand;
savedCommand = undefined;
}
}
};
kendo.bind($("#example"), viewModel);
This works fine, but looks a bit ugly.
Other solution is to execute editor undo command if needed. It works too, but empty line always flickers for a moment:
<textarea data-role="editor"
data-bind="events: { keyup: onEditorKeyUp }"></textarea>
var viewModel = kendo.observable({
html: null,
isVisible: true,
onChange: function() {
kendoConsole.log("event :: change (" + kendo.htmlEncode(this.get("html")) + ")");
}
});
viewModel.onEditorKeyUp = function (e) {
var key = e.keyCode;
if (key == 13) {
var editor = e.sender;
var body = editor.body;
while (body.scrollHeight > 195) {
editor.exec('undo');
}
}
};
kendo.bind($("#example"), viewModel);
UPD: I've found event better solution. You can use execute event, see http://docs.telerik.com/kendo-ui/api/javascript/ui/editor#events-execute
Then check conditions and filter by command name to cancel insert of new paragraph:
execute: function(e) {
alert(e.name);
e.preventDefault();
}

Distinguishing click and double-click in D3 Version 4

I have seen http://bl.ocks.org/couchand/6394506 which applies to d3 Version 3, but I have discovered that d3.rebind is no longer supported in Version 4. Can someone please help as I need this functionality?
As the CHANGELOG states, rebind can be replaced by implementing a simple wrapper function.
cc.on = function() {
var value = event.on.apply(event, arguments);
return value === event ? cc : value;
};
return cc;
function clickcancel() {
var event = d3.dispatch('click', 'dblclick');
function cc(selection) {
var down,
tolerance = 5,
last,
wait = null;
// euclidean distance
function dist(a, b) {
return Math.sqrt(Math.pow(a[0] - b[0], 2), Math.pow(a[1] - b[1], 2));
}
selection.on('mousedown', function() {
down = d3.mouse(document.body);
last = +new Date();
});
selection.on('mouseup', function() {
if (dist(down, d3.mouse(document.body)) > tolerance) {
return;
} else {
if (wait) {
window.clearTimeout(wait);
wait = null;
event.call('dblclick', d3.event);
} else {
wait = window.setTimeout((function(e) {
return function() {
event.call('click', e);
wait = null;
};
})(d3.event), 300);
}
}
});
};
cc.on = function() {
var value = event.on.apply(event, arguments);
return value === event ? cc : value;
};
return cc;
}
var cc = clickcancel();
d3.select('#map').call(cc);
cc.on('click', function() {
d3.select('#map').text(d3.select('#map').text() + 'click, ');
});
cc.on('dblclick', function() {
d3.select('#map').text(d3.select('#map').text() + 'dblclick, ');
});
#map {
width: 960px;
height: 500px;
background: cyan;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id='map'></div>
This is simply the source from the original rebind method.

lazy load doesnt work with hidden elements

this is my simple test code for lazy load
http://codepen.io/kevkev/pen/bVVGdE
it works so far .. but the thing is that hidden images in an onclick function for buttons etc. doesnt work!
(watch through my code and scroll to end and push the button)
you can see in the network feedback that it already had load the images.
i could figure out that the problem is "display:none"
.pop {
display:none;
z-index:99;
position:absolute;
width:100%;
height:auto;
background:inherit;
}
Because display: none; elements are unknown in position. And the lazyloader doesn't know, when and if you change this. Therefore it decides to eager load it. If you want a lazyloader that automatically detects this use https://github.com/aFarkas/lazysizes/.
As alternative I would recommend justlazy, because it's more lightweight and don't uses jQuery.
1. Define placeholder (similar to that what you have done):
<span data-src="path/to/image" data-alt="alt" data-title="title"
class="placeholder">
</span>
2. Initialize lazy loading after your button click:
$(document).ready(function () {
$("#art").click(function () {
$("#art_pop").fadeIn(300);
Justlazy.registerLazyLoadByClass("placeholder", {
// image will be loaded if it is 300 pixels
// below the lower display border
threshold: 300
});
});
// other code ..
});
thanks guys! but I also got a working solution on this:
http://codepen.io/kevkev/full/meebpQ/
$(document).ready(function () {
$("#art").click(function () {
$("#art_pop").fadeIn(300);
});
$(".pop > span, .pop").click(function () {
$(".pop").fadeOut(600);
});
});
;(function($) {
$.fn.unveil = function(threshold, callback) {
var $w = $(window),
th = threshold || 0,
retina = window.devicePixelRatio > 1,
attrib = retina? "data-src-retina" : "data-src",
images = this,
loaded;
this.one("unveil", function() {
var source = this.getAttribute(attrib);
source = source || this.getAttribute("data-src");
if (source) {
this.setAttribute("src", source);
if (typeof callback === "function") callback.call(this);
}
});
function unveil() {
var inview = images.filter(function() {
var $e = $(this);
if ($e.is(":hidden")) return;
var wt = $w.scrollTop(),
wb = wt + $w.height(),
et = $e.offset().top,
eb = et + $e.height();
return eb >= wt - th && et <= wb + th;
});
loaded = inview.trigger("unveil");
images = images.not(loaded);
}
$w.on("scroll.unveil resize.unveil lookup.unveil", unveil);
unveil();
return this;
};
})(window.jQuery || window.Zepto);
/* OWN JAVASCRIPT */
$(document).ready(function() {
$("img").unveil(200, function() {
$(this).load(function() {
this.style.opacity = 1;
});
});
});

Free Jqgrid 500 rows 20 plus columns not Swift scrolling down

Would it be possible to tweak the following sample to experience swift movement of scroll bar?
[link]https://drive.google.com/file/d/0B-CWzNFJRSuIQXZBMzM4R0ZQdHc/view?usp=sharing
I noticed setting hdiv.scrollLeft in scrollGrid is actually taking a time, am not understanding we this is required in verticall scroll?
scrollGrid: function (e) { // this must be bDiv
var bDiv = this, $bTable = getGridComponent(COMPONENT_NAMES.BODY_TABLE, $(bDiv));
if (e) { e.stopPropagation(); }
if ($bTable.length === 0) { return true; }
var gridSelf = $bTable[0].grid;
if (p.scroll) {
var scrollTop = bDiv.scrollTop;
// save last scrollTop of bDiv as property of grid object
if (gridSelf.scrollTop === undefined) { gridSelf.scrollTop = 0; }
if (scrollTop !== gridSelf.scrollTop) {
gridSelf.scrollTop = scrollTop;
if (gridSelf.timer) { clearTimeout(gridSelf.timer); }
gridSelf.timer = setTimeout(function () { gridSelf.populateVisible.call($bTable[0]); }, p.scrollTimeout);
}
}
gridSelf.hDiv.scrollLeft = bDiv.scrollLeft;
if (p.footerrow) {
gridSelf.sDiv.scrollLeft = bDiv.scrollLeft;
}
},
Developer tool profiler snapshot with IE9 browser
Function:scrollLeft
Inclusive time (ms):2,141.21
Inclusive time %:79.8
Exclusive time (ms):2,141.21

How to make the smooth scroll script not scroll till the top but a few pixels below

I have the below jquery scrip on my website which works fine. I wanted to make the menu fixed on top, due to which now a part of the text gets hidden behind the fixed menu. how can i make the smooth scroll script to stop at 160px; from the .top of the browser
Thanks for any help in advance.
Cheers.
<script type="text/javascript">
$(document).ready(function() {
function filterPath(string) {
return string
.replace(/^\//,'')
.replace(/(index|default).[a-zA-Z]{3,4}$/,'')
.replace(/\/$/,'');
}
var locationPath = filterPath(location.pathname);
var scrollElem = scrollableElement('html', 'body');
$('a[href*=#]').each(function() {
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath
&& (location.hostname == this.hostname || !this.hostname)
&& this.hash.replace(/#/,'') ) {
var $target = $(this.hash), target = this.hash;
if (target) {
var targetOffset = $target.offset().top;
$(this).click(function(event) {
event.preventDefault();
$(scrollElem).animate({scrollTop: targetOffset}, 1000, function() {
location.hash = target;
});
});
}
}
});
// use the first element that is "scrollable"
function scrollableElement(els) {
for (var i = 0, argLength = arguments.length; i <argLength; i++) {
var el = arguments[i],
$scrollElement = $(el);
if ($scrollElement.scrollTop()> 0) {
return el;
} else {
$scrollElement.scrollTop(1);
var isScrollable = $scrollElement.scrollTop()> 0;
$scrollElement.scrollTop(0);
if (isScrollable) {
return el;
}
}
}
return [];
}
});
</script>
EDIT 2: I tried to play around with the script and i added a scrolloffset and a preventdefault() condition. It works when i click a link the first time a page is loaded. If i click on any other link again, it doesnt scroll at all.
var scrollOffset = 160;
$('a[href*=#]').each(function() {
var thisPath = filterPath(this.pathname) || locationPath;
if ( locationPath == thisPath
&& (location.hostname == this.hostname || !this.hostname)
&& this.hash.replace(/#/,'') ) {
var $target = $(this.hash), target = this.hash;
if (target) {
var targetOffset = $target.offset().top - scrollOffset;
$(this).click(function(event) {
if(event != 'undefined') {
event.preventDefault();}
$(scrollElem).animate({scrollTop: targetOffset}, 1000, function(e) {
e.preventDefault();
location.hash = target;
I'm not sure if it works but try to just add "+ 160" to the scroll-target.
Remove location.hash since it scrolls back to the target element.

Resources