Javascript - Get Meta Keywords and If Non Don't Break Bookmarklet - javascript

I have a bookmarklet that gets the meta keywords on a page. However if the there are no meta keywords the bookmarklet breaks.
Here is my current javascript
function docoument_keywords(){
var keywords;
var metas = document.getElementsByTagName('meta');
for (var x=0,y=metas.length; x<y; x++) {
if (metas[x].name.toLowerCase() == "keywords") {
keywords = metas[x];
}
}
return keywords.content;
}
k = document_keywords();
$('body').append("<p>" + k + "</p><p>Content</p>");
The bookmarklet works fine when there are actually keywords in the meta keywords. However its break when there are none. You guys have any solutions?
Much appreciated!

function document_keywords(){
var keywords = '';
var metas = document.getElementsByTagName('meta');
if (metas) {
for (var x=0,y=metas.length; x<y; x++) {
if (metas[x].name.toLowerCase() == "keywords") {
keywords += metas[x].content;
}
}
}
return keywords != '' ? keywords : false;
}
k = document_keywords();
if (k) {
$('body').append("<p>"+k+"</p>");
}
Working example: JS Fiddle

Though Michael answered your question, I just wanted to point out that since you appear to already be using jQuery, this can be accomplished much, much more simply. Your script can be summarized thusly in its entirety:
$('body').append(
"<p>" +
$.map($('meta[name="keywords"]'), function(metaEl) { return metaEl.content; }) +
"</p>"
);
// Or, on one line:
$('body').append("<p>" + $.map($('meta[name="keywords"]'), function(metaEl) { return metaEl.content; }) + "</p>");
Hope it's helpful!

Related

Animate array from user input like typewriter (javascript)

I suppose my question is a bit similar to this one, but I can't really work out how to do my specific need from it. I'm building a very basic text adventure, and I'd like the returned text - after the user has entered a command - to be returned in a typewriter style. Here's a snippet of my commands so far (there'll be a lot more, I don't mind that this will be built in a bit of a tedious way)
<script>
textIn = document.getElementById("input-textbox");
textOut = document.getElementById("output-textbox");
function process(input) {
if (input == "hi") { textOut.innerHTML += "Hello to you too!<br><br>"; }
else if (input == "exit") { textOut.innerHTML += "No."; }
}
function go() {
var input = textIn.value;
textIn.value = "";
var output = process(input);
textOut.value += output + "\n";
}
</script>
and the HTML
<div id="output-textbox">
Returned text goes here.
</div>
<form onSubmit="go();return false;">
<input id="input-textbox" name="command" value="" autofocus="autofocus"/>
</form>
Thank you so much for your help in advance! This solution doesn't need to be beautiful, code wise, nor very nifty. It just has to work, I have no standards at all with this!
Based on William B's answer, here is a more condensed version:
https://jsfiddle.net/sators/4wra3y1p/1/
HTML
<div id="output-typewriter"></div>
Javascript
function typewriterText(text) {
var outEl = document.querySelector('#output-typewriter');
var interval = 50; // ms between characters appearing
outEl.innerHTML = '';
text.split('').forEach(function(char, i){
setTimeout(function () {
outEl.innerHTML += char;
}, i * interval);
});
}
typewriterText('this is an example');
Create a timeout for each character inside a loop, with each timeout being a bit later than the last. See: https://jsfiddle.net/fswam77j/1/
var outputEl = document.querySelector('#output-textbox');
var charInterval = 50; // ms between characters appearing
function showOutput(text) {
outputEl.innerHTML = '';
for(var i = 0; i < text.length; i++) {
showChar(text, i);
}
}
function showChar(text, i) {
setTimeout(function () {
outputEl.innerHTML += text[i];
}, i * charInterval);
}
showOutput('this is an example');
process the input:
function process(input) {
if (input == "hi") {
showOutput("Hello to you too!");
}
else if (input == "exit") {
showOutput("No.");
}
}

Checking a div for duplicates before appending to the list using jQuery

This should be trivial but I'm having issues...
Basically what I am trying to do is append a new "div" to "selected-courses" when a user clicks on a "course". This should happen if and only if the current course is not already in the "selected-courses" box.
The problem I'm running into is that nothing is appended to the "selected-courses" section when this is executed. I have used alert statements to make sure the code is in fact being run. Is there something wrong with my understanding of the way .on and .each work ? can I use them this way.
Here is a fiddle http://jsfiddle.net/jq9dth4j/
$(document).on("click", "div.course", function() {
var title = $( this ).find("span").text();
var match_found = 0;
//if length 0 nothing in list, no need to check for a match
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (matched == 0) {
var out = '<div class="selected-course">' + '' + title + ''+'</div>';
$("#selected-box").append(out);
}
});
//checks to see if clicked course is already in list before adding.
function match(str) {
$(".selected-course").each(function() {
var retval = 0;
if(str == this.text()) {
//course already in selected-course section
retval = 1;
return false;
}
});
return retval;
}
There was a couple of little issues in your fiddle.
See fixed fiddle: http://jsfiddle.net/jq9dth4j/1/
function match(str) {
var retval = 0;
$(".selected-course").each(function() {
if(str == $(this).text()) {
retval = 1;
return false;
}
});
return retval;
}
You hadn't wrapped your this in a jquery object. So it threw an exception saying this had no method text().
Second your retval was declared inside the each so it wasn't available to return outside the each, wrong scope.
Lastly the if in the block:
if (matched== 0) {
var out = '';
out += '<div class="selected-course">' + '' + title + ''+'</div>';
$("#selected-box").append(out);
}
was looking at the wrong variable it was looking at matched which didn't exist causing an exception.
Relying on checking what text elements contain is not the best approach to solve this kind of question. It is prone to errors (as you have found out), it can be slow, it gives you long code and it is sensitive to small changes in the HTML. I would recommend using custom data-* attributes instead.
So you would get HTML like this:
<div class="course" data-course="Kite Flying 101">
<a href="#">
<span>Kite Flying 101</span>
</a>
</div>
Then the JS would be simple like this:
$(document).on('click', 'div.course', function() {
// Get the name of the course that was clicked from the attribute.
var title = $(this).attr('data-course');
// Create a selector that selects everything with class selected-course and the right data-course attribute.
var selector = '.selected-course[data-course="' + title + '"]';
if($(selector).length == 0) {
// If the selector didn't return anything, append the div.
// Do note that we need to add the data-course attribute here.
var out = '<div class="selected-course" data-course="' + title + '">' + title + '</div>';
$('#selected-box').append(out);
}
});
Beware of case sensitivity in course names, though!
Here is a working fiddle.
Try this code, read comment for where the changes are :
$(document).on("click", "div.course", function () {
var title = $(this).find("span").text().trim(); // use trim to remove first and end whitespace
var match_found = 0;
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (match_found == 0) { // should change into match_found
var out = '';
out += '<div class="selected-course">' + '' + title + '' + '</div>';
$("#selected-box").append(out);
}
});
function match(str) {
var retval = 0; // this variable should place in here
$(".selected-course").each(function () {
if (str == $(this).find('a').text().trim()) { // find a tag to catch values, and use $(this) instead of this
retval = 1;
return false;
}
});
return retval; // now can return variable, before will return undefined
}
Updated DEMO
Your Issues are :
1.this.text() is not valid. you have to use $(this).text().
2.you defined var retval = 0; inside each statement and trying to return it outside each statement. so move this line out of the each statement.
3.matched is not defined . it should be match_found in line if (matched == 0) {.
4. use trim() to get and set text, because text may contain leading and trailing spaces.
Your updated JS is
$(document).on("click", "div.course", function () {
var title = $(this).find("span").text();
var match_found = 0;
if ($(".selected-course").length > 0) {
match_found = match(title);
}
if (match_found == 0) {
var out = '<div class="selected-course">' + '' + title + '' + '</div>';
$("#selected-box").append(out);
}
});
function match(str) {
var retval = 0;
$(".selected-course").each(function () {
if (str.trim() == $(this).text().trim()) {
retval = 1;
return false;
}
});
return retval;
}
Updated you Fiddle

Capitalize select option using Javascript

I have a dropdown menu.
I've been trying to capitalize the text inside my select option, but I couldn't make it work.
JS
$.each(responseData.assignments, function(i, v) {
var chapterNum = v.contentLabel;
var assessmentType = v.assessmentType.toLowerCase().replace(/_/g, " ");
var sameAssignmentType = $('#assignment-type-dd option').filter(function(){
return $(this).text() == assessmentType;
})
if(!sameAssignmentType.length){
$('#assignment-type-dd').append('<option value="' + assessmentType + '">' +
assessmentType + '</option>');
}
});
I've tried chaining this code to my assessmentType :
.charAt(0).toUpperCase() + this.slice(1)
But as soon as I do that it give error :
Uncaught TypeError: this.slice is not a function
Can someone please give me a little hint here ? Thanks.
This should work (CSS approach)
#assignment-type-dd option {
text-transform: capitalize;
}
If you need the entire options text to be uppercase use this.
#assignment-type-dd option {
text-transform: uppercase;
}
And if you really hate CSS or you need the Capitalized text to be passed to server or do some other manipulation, use the below JavaScript code
var capitalizeMe = "";
$("#assignment-type-dd option").each(function() {
capitalizeMe = $(this).text();
$(this).text(capitalizeMe.charAt(0).toUpperCase() + capitalizeMe.substring(1));
});
Play it here
Instead of using this.slice(1), try using assessmentType.slice(1).
you need to format it as
string.charAt(0).toUpperCase() + string.slice(1)
One solution could be to use a CSS rule:
select option {
text-transform:capitalize;
}
We can manipulate font setting by CSS alternation also. Try this
<style>
select option {
text-transform:capitalize;
}
</style>
This seems like a problem CSS is best-suited for.
.select {
text-transform: uppercase;
}
You don't need jQuery for this, unless you are trying to capitalize the first letter of each word. In which case a pure JavaScript solution (assuming you are targeting h2 elements) would be:
var a = document.getElementsByTagName('h2');
for (i = 0; i < a.length; i++) {
var words = a[i].innerHTML.split(" ");
for (j = 0; j < words.length; j++) {
if (words[j][0] != "&") {
words[j] = "<span class='first-letter'>" + words[j][0] + "</span>" + words[j].substring(1);
}
}
a[i].innerHTML = words.join(" ");
}
http://jsfiddle.net/ryanpcmcquen/2uLLqy8r/
Otherwise pure css will work: text-transform: capitalize;
https://developer.mozilla.org/en-US/docs/Web/CSS/text-transform
If it is about just showing it then the css text-transform should work.
If you want to do it programatically in Javascript, I suggest creating a function and calling it as needed:
function stringCapitalize(str){
if (str){
str = str.charAt(0).toUpperCase() + str.slice(1);
return str;
}
}
stringCapitalize("moemen"); // returns "Moemen"
If you think that you will use it regularly during this application, then add it to the built-in String.prototype:
String.prototype.stringCapitalize = function () {
if (this){
str = this;
str = str.charAt(0).toUpperCase() + str.slice(1);
return str;
}
}
"moemen".stringCapitalize() // returns "Moemen"
var name = prompt("what is your name");
var firstchar = name.slice(0, 1);
var firstcharuppercase = firstchar.toUpperCase();
var restofName = name.slice(1,name.length);
var capitlisedName = firstcharuppercase + restofName;
alert(" Hello " + capitlisedName);

Can't get counter to work inside function in Javascript

I am trying to create the proverbial quiz in Javascript as my first 'from scratch' exercise. This is my fiddle, which has all the other code.
This is my question:
var allQuestions = [{
"question": "Who was Luke's gunner in the battle at Hoth?",
"choices": ["Dak", "Biggs", "Wedge", "fx-7"],
"correctAnswer": 0
}];
Here in this function, I included the loop which should go over the radio buttons vs. the users selection. See below.
function answerFwd() {
var answerOutput = " ";
var itemAnswers = allQuestions;
var answer = 0;
var playerTally = 0;
var playerFeedback = "";
var playerMessage = document.getElementById("playerMessage");
Right now I am stuck with this;
Matching the correct answer in the array, with what a user would select in the radio buttons and then dynamically displaying a score.
Right now, I can get the 0 to display, but no increment.
var radioValue = $("input[type='radio'].radioButtons:checked").val();
if (currentAnswer <= itemAnswers.length) {
currentAnswer++;
}
createRadioButtonFromArray(itemAnswers[currentQuestion].choices);
for(i = 0; i < radioValue.length; i++) {
if(radioValue[i].checked) {
if(radioValue[i].value == itemAnswers.correctAnswer) {
playerTally++;
break;
}
}
}
playerFeedback += "<h4>" + playerTally + "</h4> <br/>";
playerMessage.innerHTML = playerFeedback;
}
I am not opposed to a solution with jQuery, but would prefer a vanilla JS alternative, just so I can really see what is going on!
Thank you all in advance!
Before you progress to the next question, you can figure out if an answer is correct with
if (document.querySelectorAll("#responses input")[allQuestions[currentQuestion].correctAnswer].checked)
The complete solution is
fiddle
var radios = document.querySelectorAll("#responses input");
var correct = allQuestions[currentAnswer].correctAnswer;
if (radios[correct].checked) {
playerTally++;
playerFeedback += "<h5>" + playerTally + "</h5> <br/>";
playerMessage.innerHTML = playerFeedback;
}
if (currentAnswer <= itemAnswers.length) {
currentAnswer++;
}
And now I look closely it is the same as Mr. Me's

Changing allowed string value in obfuscated code

I have this obfuscated code. I just want to change one thing. Since this is a summary code for Blogger, it allows 40 words to be shown in the summary. I want it to be 0 words. All my tries were unsuccessful. I don't know how to deal with obfuscated code. Can anyone help me setting the string value to 0?
<script type='text/javascript'>//<![CDATA[
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('C X(s,n){14 s["\\9\\2\\i\\5\\8\\d\\2"](/<.*?>/15,"")["\\b\\i\\5\\c\\3"](/\\s+/)["\\b\\5\\c\\d\\2"](0,n-1)["\\N\\g\\c\\h"]("\\j")};C 16(a){13 p=S["\\6\\2\\3\\E\\5\\2\\7\\2\\h\\3\\y\\w\\M\\v"](a),z="",G=p["\\6\\2\\3\\E\\5\\2\\7\\2\\h\\3\\b\\y\\w\\D\\8\\6\\Q\\8\\7\\2"]("\\c\\7\\6");U(G["\\5\\2\\h\\6\\3\\e"]>=1){z="\\t\\c\\7\\6\\j\\d\\5\\8\\b\\b\\u\\f\\o\\8\\5\\b\\8\\7\\f\\j\\b\\9\\d\\u\\f"+G[0]["\\b\\9\\d"]+"\\f\\j\\4\\r"}Y{z="\\t\\c\\7\\6\\j\\d\\5\\8\\b\\b\\u\\f\\o\\8\\5\\b\\8\\7\\f\\j\\b\\9\\d\\u\\f\\e\\3\\3\\i\\B\\4\\4\\I\\k\\o\\i\\k\\o\\5\\g\\6\\b\\i\\g\\3\\k\\d\\g\\7\\4\\Z\\10\\2\\O\\q\\q\\v\\18\\q\\3\\i\\L\\4\\K\\2\\L\\17\\W\\1d\\E\\1f\\1g\\1h\\M\\4\\l\\l\\l\\l\\l\\l\\l\\l\\y\\m\\K\\4\\H\\w\\1b\\A\\Q\\9\\P\\O\\P\\A\\H\\4\\b\\I\\19\\J\\J\\4\\h\\g\\12\\c\\7\\8\\6\\2\\k\\N\\i\\6\\f\\j\\4\\r"};p["\\c\\h\\h\\2\\9\\V\\D\\A\\R"]="\\t\\8\\j\\e\\9\\2\\F\\u\\f"+x+"\\f\\r"+z+"\\t\\4\\8\\r"+X(p["\\c\\h\\h\\2\\9\\V\\D\\A\\R"],1a)};$(S)["\\9\\2\\8\\v\\w"](C(){$("\\T\\d\\9\\2\\v\\c\\3")["\\e\\3\\7\\5"]("\\t\\8\\j\\e\\9\\2\\F\\u\\f\\e\\3\\3\\i\\B\\4\\4\\m\\m\\m\\k\\o\\5\\g\\6\\6\\2\\9\\3\\e\\2\\7\\2\\q\\k\\d\\g\\7\\4\\f\\r\\y\\5\\g\\6\\6\\2\\9\\3\\e\\2\\7\\2\\q\\t\\4\\8\\r");1c(C(){U(!$("\\T\\d\\9\\2\\v\\c\\3\\B\\W\\c\\b\\c\\o\\5\\2")["\\5\\2\\h\\6\\3\\e"]){1e["\\5\\g\\d\\8\\3\\c\\g\\h"]["\\e\\9\\2\\F"]="\\e\\3\\3\\i\\B\\4\\4\\m\\m\\m\\k\\o\\5\\g\\6\\6\\2\\9\\3\\e\\2\\7\\2\\q\\k\\d\\g\\7\\4"}},11)});',62,80,'||x65|x74|x2F|x6C|x67|x6D|x61|x72||x73|x69|x63|x68|x22|x6F|x6E|x70|x20|x2E|x41|x77||x62||x39|x3E||x3C|x3D|x64|x79||x42|imgtag|x4D|x3A|function|x54|x45|x66|img|x6B|x31|x30|x55|x38|x49|x6A|x32|x53|x4E|x4C|document|x23|if|x48|x76|stripTags|else|x2D|x51|3000|x2B|var|return|ig|readmore|x4A|x58|x36|42|x47|setInterval|x43|window|x34|x57|x35'.split('|'),0,{}))
//]]></script>
Thanks to commenters, I see that a first step is to pass the code through jsbeautifier.org using the option "Unescape printable chars encoded as \xNN or \uNNNN".
function stripTags(s, n) {
return s["replace"](/<.*?>/ig, "")["split"](/\s+/)["slice"](0, n - 1)["join"](" ")
};
function readmore(a) {
var p = document["getElementById"](a),
imgtag = "",
img = p["getElementsByTagName"]("img");
if (img["length"] >= 1) {
imgtag = "<img class=\"balsam\" src=\"" + img[0]["src"] + "\" />"
} else {
imgtag = "<img class=\"balsam\" src=\"http://1.bp.blogspot.com/-Qe299dX9tp8/Ue8JvCE4W5I/AAAAAAAABwU/kyGMNrS2SMk/s1600/no+image.jpg\" />"
};
p["innerHTML"] = "" + imgtag + "" + stripTags(p["innerHTML"], 42)
};
$(document)["ready"](function () {
$("#credit")["html"]("Bloggertheme9");
setInterval(function () {
if (!$("#credit:visible")["length"]) {
window["location"]["href"] = "http://www.bloggertheme9.com/"
}
}, 3000)
});
Now where do I change the allowed number of words?

Categories