Page stops loading when loop stop case increased by 1 - javascript

I am using the Instagram API onto my website and need to grab only the first few words of the description of the first 8 pictures.
My problem is that if I try to take more than 11 words per picture, the page stops loading.
Here's my code:
success: function (data) {
console.log(data);
data.data.forEach(function (pic) {
var height = pic.images.standard_resolution.height;
var width = pic.images.standard_resolution.width;
if (width == height && pic.type != "video") {
$("#img" + i).append("<img class='img-fluid' alt='placeholder' src=\"" + pic.images.standard_resolution.url + "\" > ");
var text = pic.caption.text;
var s = ""
var words = 0;
var j = 0;
while (words < 11 || j < text.length) {
if (text[j] == ' ') {
words++;
}
s += text[j];
j++;
}
$("#img" + i).append("<div class='mask flex-center waves-effect waves-light rgba-black-light'><p id='txt" + i + "' class='white-text'>" + s + "</p></div>");
i++;
}
});
}
I don't really know what I am doing wrong and what could be so terrible about 8 more words (I only fetch 8 pictures).
Thank you in advance for looking at my problem.

Your while condition should be with an && instead of || like this while (words < 11 && j < text.length) otherwise you may reach the end of the sentence and still have not reached the max word count. Also you are missing a semicolon on var s = "";
To simplify your code, you can use the split method to get the number of words of a phrase. Ex:
var str = 'This is a random string';
var wordCount = str.split(' ').length;

Related

Javascript Regex optimization

I have two JQuery/Javascript functions that highlights all string occurences in a web page, and then narrows these occurences one by one when clicking on the next/prev buttons.
Here is the current JS code for the next and previous buttons:
var outputHtmlContent;
var posScroll = 0;
// Trigger on search next occurence's button
$('#nextSearchOutputButton').on("click", function (e) {
e.preventDefault();
var searchString = "Command Name";
$("body").highlight(searchString);
$(".highlight").css({ backgroundColor: "#E0FFFF" });
var regex = /Command Name/g, result, indices = [];
var i = 0;
outputHtmlContent = $("#output").html();
if (posScroll == outputHtmlContent.match(/Command Name/g).length - 1) posScroll = 0;
else
posScroll++;
while ((result = regex.exec(outputHtmlContent))) {
if (posScroll == i) {
var index = result.index;
outputHtmlContent = outputHtmlContent.substring(0, index) + "<span class='highlight'>" + outputHtmlContent.substring(index, index + searchString.length) + "</span>" + outputHtmlContent.substring(index + searchString.length);
$("#output").html(outputHtmlContent);
document.getElementById("commandNumber" + posScroll).scrollIntoView();
return;
}
i++;
}
})
// Trigger on search previous occurence's button
$('#prevSearchOutputButton').on("click", function (e) {
e.preventDefault();
var searchString = "Command Name";
$("body").highlight(searchString);
$(".highlight").css({ backgroundColor: "#E0FFFF" });
var regex = /Command Name/g, result, indices = [];
var i = 0;
outputHtmlContent = $("#output").html();
if (posScroll == 0) posScroll = outputHtmlContent.match(/Command Name/g).length - 1;
else
posScroll--;
while ((result = regex.exec(outputHtmlContent)) && i <= posScroll) {
if (posScroll == i) {
var index = result.index;
outputHtmlContent = outputHtmlContent.substring(0, index) + "<span class='highlight'>" + outputHtmlContent.substring(index, index + searchString.length) + "</span>" + outputHtmlContent.substring(index + searchString.length);
$("#output").html(outputHtmlContent);
document.getElementById("commandNumber" + posScroll).scrollIntoView();
return;
}
i++;
}
})
The two functions work well, but I have a very critical issue concerning the time spent when executing the two functions, this time estimated to 10 seconds for IE when moving from one occurence to an other and is estimated to 4 seconds for FF and chrome.
I googled and found that the Regex performance issue is a classic topic. I found this nice atricle http://infrequently.org/2007/02/regexs-are-slow/.
I would rather remove completely this feature than offering it with such a low quality issue. Yet, I want to stick on it because it is very helpful for my user. Can anyone help improve the Regex performance for my functions ?

detect natural line breaks javascript

When I type in a non-resizeable text area something like hello world, this is a demo and the text area is small enough, it will look like this:
hello world,
this is a demo
This is not caused by a \n or something.
How can I detect this natural line break in a text area?
A fiddle can be found here: http://jsfiddle.net/yx6B7/
As you can see, there is a line break, but javascript just says that it's one big line without any line-breaks in it.
Finally I found this script on the internet:
function ApplyLineBreaks(strTextAreaId) {
var oTextarea = document.getElementById(strTextAreaId);
if (oTextarea.wrap) {
oTextarea.setAttribute("wrap", "off");
}
else {
oTextarea.setAttribute("wrap", "off");
var newArea = oTextarea.cloneNode(true);
newArea.value = oTextarea.value;
oTextarea.parentNode.replaceChild(newArea, oTextarea);
oTextarea = newArea;
}
var strRawValue = oTextarea.value;
oTextarea.value = "";
var nEmptyWidth = oTextarea.scrollWidth;
var nLastWrappingIndex = -1;
for (var i = 0; i < strRawValue.length; i++) {
var curChar = strRawValue.charAt(i);
if (curChar == ' ' || curChar == '-' || curChar == '+')
nLastWrappingIndex = i;
oTextarea.value += curChar;
if (oTextarea.scrollWidth > nEmptyWidth) {
var buffer = "";
if (nLastWrappingIndex >= 0) {
for (var j = nLastWrappingIndex + 1; j < i; j++)
buffer += strRawValue.charAt(j);
nLastWrappingIndex = -1;
}
buffer += curChar;
oTextarea.value = oTextarea.value.substr(0, oTextarea.value.length - buffer.length);
oTextarea.value += "\n" + buffer;
}
}
oTextarea.setAttribute("wrap", "");
document.getElementById("pnlPreview").innerHTML = oTextarea.value.replace(new RegExp("\\n", "g"), "<br />");
}
Which is working fine.
This isn't a javascript problem.
Look at the word-wrap, white-space and overflow css properties.

Set CSS of words enclosed in double quotes

This is a follow up question to my question about Setting the CSS of code if it contains a reserved word.
What I am trying to do: If some code has quotes or double quotes, I want to set the color of the font to red and bold. Ex. System.out.println( "Hello world" ); should set "Hello world" to red.
What's wrong: Despite my best efforts, I can't seem to get my control statements to work properly (at least I think that's the issue). It sets the first double quote and beyond to red, but when I tell it to stop when a word equals anyword" or anyword' it sets the rest of the code in the block to red.
HTML
<html>
<body>
<code id="java">
public static void main(String[] args)<br>
{
<pre> int i = 120; </pre><br>
<pre> // Displays a message in the console </pre>
<pre> // This is a test </pre>
<pre> System.out.println( "Hello Big World!" );</pre>
}
</code>
</body>
</html>
CSS
.quotes
{
font-weight: bold;
color: #E01B1B;
}
jQuery
$(document).ready(function() {
var code = $("#java").html(); // Get the code
var split = code.split(' '); // Split up each element
var chkQ = 0; // Check for quotes
var chkC = 0; // Check until end of comment line
// Set the CSS of reserved words, digits, strings, and comments
for (var j = 0; j < split.length; j++) {
// Check to see if chkQ is set to true
if (chkQ == 1) {
// If the element matches (anyword") or (anyword'), then set
// flag to false and continue checking the rest of the code.
// Else, continue setting the CSS to .quotes
if (split[j].match(/."/) || split[j].match(/.'/)) {
split[j] = '<span class="quotes">' + split[j] + '</span>';
chkQ = 0;
} else {
split[j] = '<span class="quotes">' + split[j] + '</span>';
}
}
...
} else if (chkQ == 0 && chkC == 0) {
...
// If the element matches a ("anyword) or ('anyword)...
} else if (split[j].match(/"./) || split[j].match(/'./)) {
split[j] = '<span class="quotes">' + split[j] + '</span>';
chkQ = 1;
} ...
}
}
// Join all the split up elements back together!
$("#java").html(split.join(' '));
});
Question: Is this just simply an issue with my regex, control blocks or something completely different?
Why split the string up when you can perform a simple global regex find and replace:
<script type="text/javascript">
$(document).ready(function(){
//cache the element
el = $('#java');
//get the HTML contained within the cached element
code = el.html();
//return the code having executed the replace method, regex explained:
/*
([^\w]{1}) -> look for a single character that is not an alpha character
(["']) -> then look for either a single quote or double quote
(.*?) -> then look any character, but don't be greedy
(\2) -> then look for what was found in the second group - " or '
([^\w]{1}) -> and finally look for a single character that is not an alpha character
*/
code = code.replace(/([^\w]{1})(["'])(.*?)(\2)([^\w]{1})/gm,
//execute an anonymous callback, passing in the result for every match found
function(match, $1, $2, $3, $4, $5, offset, original) {
//construct the replacement
str = $1 + '<span class="quotes">' + $2 + $3 + $4 + '</span>' + $5;
//return the replacement
return str;
});
//replace the existing HTML within the cached element
el.html(code);
});
</script>
Edit: Just updated it to accommodate nested quotes.
I don't know all your requirements, but it seems that your single quote could get a bit complicated.
I've set up a demonstration that works (updated link to include nested quotes).
I do not guarantee it is bug free. It does the replacement in two stages, first for double quotes, then for single, trying to weed out potential apostrophes (note in the code below the filters for apostrophes are based off common following letters--not sure how many you might practically need, if any).
Javascript
$(document).ready(function() {
var code = $("#java").html(); // Get the code
var split = code.split('\"'); // Split up each element at the "
// Set the CSS of reserved words, digits, strings, and comments
for (var j = 0; j < split.length - 1; j++) {
if (j%2 == 0) { //if first, add beginning
split[j] = split[j] + '<span class="quotes">"';
} else {//if second, add ending
split[j] = split[j] + '"</span>';
}
}
// Join all the split up elements back together!
$("#java").html(split.join(""));
code = $("#java").html(); // Get the code
split = code.split('\''); // Split up each element at the '
var openQ = 1;
var sub1;
var sub2;
for (var j = 0; j < split.length - 1; j++) {
sub1 = split[j+1].substr(0,2); //checking for a contraction of 's
sub2 = split[j+1].substr(0,3); //checking for a contraction of 'll
if(sub1 != "s " && sub2 != "ll ") {
if (openQ) { //if first, add beginning
split[j] = split[j] + '<span class="quotes">\'';
openQ = 0;
} else {//if second, add ending
split[j] = split[j] + '\'</span>';
openQ = 1;
}
}
else {//add apostrophe back
split[j] = split[j] + '\'';
}
}
$("#java").html(split.join(""));
});
Here's a pure JavaScript version:
id= id of element with quotes
classid= class to add to the quotes
function quotes(id,classid) {
var code = document.getElementById(id).innerHTML;
var split = code.split('\"');
for (var j = 0; j < split.length - 1; j++) {
if (j%2 == 0) {
split[j] = split[j] + '<span class='+classid+'>"';
} else {
split[j] = split[j] + '"</span>';
}
}
document.getElementById(id).innerHTML = split.join("");
code = document.getElementById(id).innerHTML;
split = code.split('\'');
var openQ = 1;
var sub1;
var sub2;
for (var j = 0; j < split.length - 1; j++) {
sub1 = split[j+1].substr(0,2);
sub2 = split[j+1].substr(0,3);
if(sub1 != "s " && sub2 != "ll ") {
if (openQ) {
split[j] = split[j] + '<span class='+classid+'>\'';
openQ = 0;
} else {
split[j] = split[j] + '\'</span>';
openQ = 1;
}
}
else {
split[j] = split[j] + '\'';
}
}
document.getElementById(id).innerHTML = split.join("");
}
String.prototype.Text2Html = function (){
var div = document.createElement('div');
div.appendChild(document.createTextNode(this))
encoded=div.innerHTML;
div.remove();
return encoded
}
String.prototype.colorTheQuotes = function(){
var re = /(?:<span style=|)(?:(?:"[^"]*")|(?:'[^']*'))/gm,
text = this.Text2Html(),
output = text,
tour = 0,
slen = 27;
while ((match = re.exec(text)) != null) {
if(match[0].startsWith("<span")) continue
output=output.slice(0,match.index+tour*slen)+'<span class="quote">'+output.slice(match.index+tour*slen,match.index+match[0].length+tour*slen)+"</span>"+output.slice(match.index+match[0].length+tour*slen);tour++
}
return output
}
element=document.getElementById("color")
document.addEventListener("readystatechange",(e)=>{
element.innerHTML=element.innerText.colorTheQuotes();
})
.quote{
color: red;
}
<span>System.out.println( "Hello world" );</span><br>
<span id="color">System.out.println( "Hello world" );</span>

Long string pagination done right

I want to split a long text into smaller chunks, that will act as pages.
var longText = document.getElementById('content').innerHTML;
for (i=0; i<10; i++) {
var page = longText.substring(i*100,(i+1)*100);
document.write(page + "<br /><hr />");
}
See it here on jsfiddle.
This code splits the text, but in a stupid way, cutting also words in half.
It would be far better, for example, creating substrings ending at the last space in a certain number of characters (count 100 characters, then go back to the last space).
How would you achieve it?
Second shot
Third shot
I would use:
function paginate(longText, pageSize) {
var parts = longText.split(/[ \n\t]/g);
if (parts.length == 0)
return [];
var pages = [parts.unshift()];
for (var i = 0; i < parts.length; i += 1) {
var part = parts[i];
if (part.length + pages[pages.length - 1].length < pageSize) {
pages[pages.length - 1] += " " + part;
} else {
pages.push(part);
}
}
return parts;
}
For those looking for a working answer:
<div id="long-text">Lorem ipsum [...]</div>
<script>
var splitter = function(id) {
var longText = document.getElementById(id).innerHTML;
var pageLenght = 200;
var charsDone = 0;
var htmlBefore = "<p>";
var htmlAfter = "</p>";
while (charsDone <= longText.length && (pageLenght+charsDone)<longText.length) {
var pageBox = longText.substr(lastSpace,pageLenght);
var lastSpace = charsDone + pageBox.lastIndexOf(" ");
var page = longText.substring(charsDone,lastSpace);
document.write(htmlBefore + page + htmlAfter);
charsDone = lastSpace;
}
document.write(longText.substr(lastSpace,pageLenght));
}
splitter("#long-text");
You can easily use arrays instead of writing to document.
You will also want to set your html to your needs, do it in htmlBefore and htmlAfter.
See it in action here.

how can i break the line in JOptionpane message box

<script language="javascript">
<![CDATA[
importPackage(javax.swing);
importPackage(java.lang);
System.out.println("Hello from JavaScript!");
var optionPane = JOptionPane.showMessageDialog(null,'Deployment instruction = ' + Deployment_Instrution);
]]>
</script>
here Deployment_Instruction is variable in which i am storing the output of sql select query. the output of sql select query length is too much big so the size of JOptionpane message box is also going bigger. for this i want to break the big line in message box.
how can i do this.pls help[ me out asap.
thanks in advance....
I guess you'll have to break the line by inserting newlines where appropriate. For a simple application like this it might do to just have a basic function that breaks on spaces once a line reaches the maximum length that you want.
Something like:
var boxText = wrapLines( 30, Deployment_Instruction );
JOptionPane.showMessageDialog( null, boxText );
Here the maximum length would be 30 characters. With the wrapLines function being:
function wrapLines(max, text)
{
max--;
text = "" + text;
var newText = "";
var lineLength = 0;
for (var i = 0; i < text.length; i++)
{
var c = text.substring(i, i+1);
if (c == '\n')
{
newText += c;
lineLength = 1;
}
else if (c == ' ' && lineLength >= max)
{
newText += '\n';
lineLength = 1;
}
else
{
newText += c;
lineLength++;
}
}
return (newText);
}
Note that this will give a 'ragged' right edge, so if there is a very long word at the end of a line it may not be satisfactory.
By the way your variable name is missing a letter 'c' - Instru?tion.

Categories

Resources