I'm trying to highlight text in realtime using JQuery or Javascript. Current code doesn't want to search from .filters-no-actions block.
How it should look like:
Note: I don't want to add new text to the .filters-no-actions block, but only find text in this block using input value and highlight them.
CSS
.highlight_y {
background-color: yellow;
}
p, div {
display: inline-block;
}
HTML
<input id="ue__searchInput" placeholder="Search">
<div class="filters-no-actions">
<p>Example text to search</p>
<p>Lorem ipsum and...</p>
</div>
Script
$(document).ready(function(){
var search_input = $('#ue__searchInput');
$(search_input).change(function(){
var search_box = $('.filters-no-actions').text();
var search_box_val = search_box.val();
if (search_box_val == this.val()) {
search_box.append('<div class="highlight_y">' + search_box_val + '</div>');
}
});
});
You need to use the keyup event instead of the change event. Here is how you can do it:
$(document).ready(function(){
var search_input = $('#ue__searchInput');
$(document).on('keyup', '#ue__searchInput',function(){
var search_box = $('.filters-no-actions').text();
var search_box_val = search_input.val();
if (search_input.val() != '') {
$('.highlight_y').html('<p class="highlight_text">' + search_input.val() + '</p>');
}
else
{
$('.highlight_y').html('');
}
});
});
.highlight_y {
background-color: yellow;
}
p, div {
display: inline-block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
</head>
<body>
<input id="ue__searchInput" placeholder="Search">
<div class="highlight_y"></div>
<div class="filters-no-actions">
<p>Example text to search</p>
<p>Lorem ipsum and...</p>
</div>
</body>
</html>
As Santu Roy said (+1 for him) you could try a jQuery highlight plugin like this: http://bartaz.github.io/sandbox.js/jquery.highlight.html.
In this exemple, I used it in a small delay function that is trigger after 100ms (you can change this time) your last keyup [thanks to Ata ul Mustafa for this solution: How to trigger an event in input text after I stop typing/writing? +1 also for him].
Try it:
/* This is the plugin. Put it in an external file
=> https://github.com/bartaz/sandbox.js/blob/master/jquery.highlight.js
Here you can find all the documentation: http://bartaz.github.io/sandbox.js/jquery.highlight.html
*/
jQuery.extend({
highlight: function (node, re, nodeName, className) {
if (node.nodeType === 3) {
var match = node.data.match(re);
if (match) {
var highlight = document.createElement(nodeName || 'span');
highlight.className = className || 'highlight';
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
}
}
return 0;
}
});
jQuery.fn.unhighlight = function (options) {
var settings = { className: 'highlight', element: 'span' };
jQuery.extend(settings, options);
return this.find(settings.element + "." + settings.className).each(function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};
jQuery.fn.highlight = function (words, options) {
var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
jQuery.extend(settings, options);
if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word, i){
return word != '';
});
words = jQuery.map(words, function(word, i) {
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
});
if (words.length == 0) { return this; };
var flag = settings.caseSensitive ? "" : "i";
var pattern = "(" + words.join("|") + ")";
if (settings.wordsOnly) {
pattern = "\\b" + pattern + "\\b";
}
var re = new RegExp(pattern, flag);
return this.each(function () {
jQuery.highlight(this, re, settings.element, settings.className);
});
};
$(document).ready(function(){
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
var search_input = $('#ue__searchInput');
$(search_input).on('keyup',function(){
delay(function(){
$(".filters-no-actions").unhighlight({ className: 'highlight_y'}); /*remove all highlight before create a new one */
$(".filters-no-actions").highlight($(search_input).val(), { className: 'highlight_y'});
}, 100 );
});
});
.highlight_y {
background-color: #FFFF88;
}
p, div {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="ue__searchInput" placeholder="Search">
<div class="highlight_y"></div>
<div class="filters-no-actions">
<p>Example text to search</p>
<p>Lorem ipsum and...</p>
</div>
Related
I am using the following jQuery script from enter link description here
<script>
var calendarObjects = [
{name:"Event Type 1", colour:"#735f9e"},
{name:"Event Type 2", colour:"#0000FF"},
{name:"Event Type 3", colour:"#0066cc"},
{name:"Event Type 4", colour:"#83b53f"},
{name:"Event Type 5", colour:"#ff99cc"} ,
]
</script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
LoadSodByKey("SP.UI.ApplicationPages.Calendar.js", function () {
WaitForCalendarToLoad();
});
var SEPARATOR = "|||";
function WaitForCalendarToLoad() {
var _renderGrids = SP.UI.ApplicationPages.SummaryCalendarView.prototype.renderGrids;
SP.UI.ApplicationPages.SummaryCalendarView.prototype.renderGrids = function($p0) {
_renderGrids.call(this, $p0);
ColourCalendar();
}
var _onItemsSucceed = SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed;
SP.UI.ApplicationPages.CalendarStateHandler.prototype.onItemsSucceed = function($p0, $p1) {
_onItemsSucceed.call(this, $p0, $p1);
ColourCalendar();
}
}
function ColourCalendar() {
// Find calendar links (i.e. links that contain the separator |||)
if ($('a:contains(' + SEPARATOR + ')') != null) {
// Loop through calendar links
$('a:contains(' + SEPARATOR + ')').each(function (i) {
// Get the div of the calendar entry
$box = $(this).parents('div[title]');
// Get the category, colour and actual text
var category = GetCategory(this.innerHTML);
if (category != "")
{
var colour = GetColourCodeFromName(category);
var actualText = GetActualText(this.innerHTML);
// Set html of calendar entry
this.innerHTML = actualText;
// Set the title of the div
$($box).attr("title", GetActualText($($box).attr("title")));
// Set class of div to category without spaces
$($box).attr("class", "calendarEvent " + category.replace(/ /g, ""));
// Set the background colour
$box.css('background-color', '#da7b2f');
}
else
{
// Set html of calendar entry
this.innerHTML = GetActualText(this.innerHTML);
// Set class of div to category without spaces
$($box).attr("class", "calendarEvent");
// Set the background colour
$box.css('background-color', '#da7b2f');
}
});
}
// Setup filter links
SetupFilterLinks();
// If filter already selected
var selectedFilter = document.getElementById('hfdSelectedFilter').value;
if (selectedFilter != "") {
FilterCategory(document.getElementById('hfdSelectedFilter').value);
}
}
function GetActualText(originalText) {
var parts = originalText.split(SEPARATOR);
return parts[0] + parts[2];
}
function GetCategory(originalText) {
var parts = originalText.split(SEPARATOR);
return parts[1];
}
function GetColourCodeFromName(name) {
// Iterate calendar objects
for (var i = 0, len = calendarObjects.length; i < len; i++) {
if (calendarObjects[i].name === name)
return calendarObjects[i].colour; // Return as soon as the object is found
}
return "#999999"; // Default to dark grey
}
function FilterCategory(category) {
// Get category with no spaces
var categoryNoSpaces = category.replace(/ /g, "");
// If divs with class "calendarEvent" exist
if ($('div.calendarEvent') != null) {
// Loop through divs
$('div.calendarEvent').each(function (i) {
// Hide divs
this.style.display = "none";
});
}
// If div(s) with category class exist
if ($('div.' + categoryNoSpaces) != null) {
// Loop through divs
$('div.' + categoryNoSpaces).each(function (i) {
// Set display to block
this.style.display = "block";
});
}
// Set hidden field value
document.getElementById('hfdSelectedFilter').value = categoryNoSpaces;
// Expand all days
expandCalCheck();
// Hide collapse links
hideCollapseLinks();
}
function expandCalCheck() {
var a = $("a.ms-cal-nav", $("div.ms-acal-rootdiv:last>div")).get(0);
if (a) {
for (var r = 0; r < 6; r++) {
var a = $("a.ms-cal-nav", $("div.ms-acal-rootdiv:last>div").get(r)).get(0);
if (a)
if (a.innerText.indexOf("more") >= 0) {
a.click();
}
}
}
}
function hideCollapseLinks() {
if ($('a:contains(collapse)') != null) {
// Loop through collapse links
$('a:contains(collapse)').each(function (i) {
this.style.display = "none";
});
}
}
function ShowAllEvents() {
// If divs with class "calendarEvent" exist
if ($('div.calendarEvent') != null) {
// Loop through divs
$('div.calendarEvent').each(function (i) {
// Hide divs
this.style.display = "block";
});
// Set hidden field value
document.getElementById('hfdSelectedFilter').value = "";
}
}
function SetupFilterLinks()
{
// Variables
var filters = [];
// Loop through calendar objects
$(calendarObjects).each(function (i) {
var name = this.name;
var colour = GetColourCodeFromName(name);
// Add filters variable
filters.push("<a href='javascript:void(0)' id='" + name.replace(/ /g, "") + "' class='filterLink' style='background-color:" + colour + "' onclick='FilterCategory(\"" + name + "\")'>" + name + "</a> ");
});
// Add filters to page
$('.calendarFilters').replaceWith(filters.join(''));
$('.filters a').click(function () {
$(this).addClass('selected');
$(this).siblings().removeClass('selected');
});
}
</script>
<style>
.filters
{
margin:10px 0 0 0;
}
.filters .title
{
font-size:15px;
margin:0 5px 0 0;
}
.filters .filterLink
{
color:#ffffff !important;
padding:3px 6px 4px 6px;
display: inline-block;
margin-bottom: 5px;
}
.filters .filterLinkShowAll
{
color:#ffffff !important;
background:#666666;
}
.filters .selected
{
border:2px solid #000000 !important;
padding:1px 4px 2px 4px;
}
</style>
<input type="hidden" id="hfdSelectedFilter" name="hfdSelectedFilter">
<div class="filters">
<span class="title">Filters:</span>
Show all
<div class="calendarFilters">
<!-- -->
</div>
</div>
There is a variable that controls color
$box.css('background-color', '#da7b2f');
The problem is when I try to remove the background-color variable, it does not use the following stylesheet and just inherits the color from the table it's from. How can I incorporate this stylesheet so it works with the jQuery script?
<style>
.ms-acal-time, .ms-acal-apanel-color {
DISPLAY: none;
}
.ms-acal-color6{
background-color:#0066cc!important;
}
.ms-acal-apanel-color6{
background-color:#0066cc!important;
}
.ms-acal-color8{
background-color:#787878!important;
}
.ms-acal-apanel-color8{
background-color:#787878!important;
}
</style>
I would like to know how can I define a bigger variable for a set of variables that I have in javascript: showFootnotesPanel();, showReferencesPanel();, showImagesPanel();, showInformationPanel();.
Would it be something like this?
function showPanel() {
var x = [showFootnotesPanel();showReferencesPanel();showImagesPanel();showInformationPanel();]
}
Update:
I have this function that used to open a side panel on the right side and color the content:
var els = document.getElementsByClassName('change-color'),
target = document.getElementsByClassName('resources'),
changeColor = function(a) {
elements = document.getElementsByClassName("note");
for (var i = 0; i < elements.length; i++) {
console.log(elements[i])
elements[i].style.backgroundColor = "";
}
target = a.getAttribute('href');
element = document.querySelector('[data-id="' + target.substring(1, target.length) + '"]');
element.style.backgroundColor = a.getAttribute('data-color');
};
for (var i = els.length - 1; i >= 0; --i) {
els[i].onclick = function() {
showFootnotesPanel();
changeColor(this);
}
Now I have 4 side panels that need to respond to the same script, and I thought that by defining something like showPanel() is showFootnotesPanel() or showReferencesPanel() or showImagesPanel() or showInformationPanel() I might simplify things, so the last line of the script would be this instead just:
els[i].onclick = function(){showPanel();changeColor(this);}
Update 2:
Or is it possible to do this with the logical operator OR?
els[i].onclick = function(){showFootnotesPanel(); || showReferencesPanel(); || showImagesPanel(); || showInformationPanel();changeColor(this);}
Update 3:
This is the new script that I am using to hide and show the panels:
function showPanel(myPanel) {
var elem = document.getElementById(myPanel);
if (elem.classList) {
console.log("classList supported");
elem.classList.toggle("show");
} else {
var classes = elem.className;
if (classes.indexOf("show") >= 0) {
elem.className = classes.replace("show", "");
} else {
elem.className = classes + " show";
}
console.log(elem.className);
}
}
function hideOthers(one, two, three, four) {
if (one > "") {
var elem1 = document.getElementById(one);
var classes = elem1.className;
elem1.className = classes.replace("show", "");
}
if (two > "") {
var elem2 = document.getElementById(two);
var classes = elem2.className;
elem2.className = classes.replace("show", "");
}
if (three > "") {
var elem3 = document.getElementById(three);
var classes = elem3.className;
elem3.className = classes.replace("show", "");
}
if (four > "") {
var elem4 = document.getElementById(four);
var classes = elem4.className;
elem4.className = classes.replace("show", "");
}
return;
}
And this is the script that calls the panels and highlights the text on them:
var els = document.getElementsByClassName('change-color'),
target = document.getElementsByClassName('resources'),
changeColor = function(a) {
elements = document.getElementsByClassName("note");
for (var i = 0; i < elements.length; i++) {
console.log(elements[i])
elements[i].style.backgroundColor = "";
}
target = a.getAttribute('href');
element = document.querySelector('[data-id="' + target.substring(1, target.length) + '"]');
element.style.backgroundColor = a.getAttribute('data-color');
};
for (var i = els.length - 1; i >= 0; --i) {
els[i].onclick = function() {
hideOthers('footnotes-section', 'references-section', 'images-section', 'information-section');
showPanel('references-section');
changeColor(this);
}
}
Thank you!
Updated with a final solution.
In javascript you can declare variables by this way:
var text = ""; // String variable.
var number = 0; //Numeric variable.
var boolValue = true; //Boolean variable.
var arrayValue = []; // Array variable. This array can contain objects {}.
var obj = {}; // Object variable.
Check this version of your code.
// var text = ""; => String variable.
// var number = 0; => Numeric variable.
// var boolValue = true; => Boolean variable.
// var arrayValue = []; => Array variable. This array can contain objects {}.
// var obj = {}; => Object variable.
// This section of code is only to explain the first question.
(function() {
function showFootnotesPanel() {
return 10; // Random value.
}
function showReferencesPanel() {
return 30; // Random value.
}
function showImagesPanel() {
return 50; // Random value.
}
function showInformationPanel() {
return 90; // Random value.
}
function showPanel() {
return [
showFootnotesPanel(), // Index = 0
showReferencesPanel(), // Index = 1
showImagesPanel(), // Index = 2
showInformationPanel() // Index = 3
];
}
var bigVariable = showPanel(); // bigVariable is array of numeric values.
// Using logical operator to check status of variable about this demo code.
if (bigVariable[0] === 10 || bigVariable[1] === 30) {
console.log("Hey, with these values can show the FootnotesPanel and ReferencesPanel.");
} else {
console.log("With the current values can't show anything...");
}
console.log(bigVariable);
})();
// https://jsfiddle.net/dannyjhonston/t5e8g22b/
// This section of code attempts to answer the question of this post.
(function() {
// This function can be executed when the page is loaded.
function showPanel(panels) {
var panel, panelVisible = "";
var selPanels = document.getElementById("selPanels");
// In panels array...
for (var i = 0; i < panels.length; i++) {
// panels[0] = "ReferencesPanel";
panel = document.getElementById(panels[i]); // Get in the DOM tag context of the panel to set in the variable "panel".
panelVisible = panel.getAttribute("data-visible"); // HTML5 data attribute.
if (panelVisible == "true") {
panel.setAttribute("class", "show");
} else {
panel.setAttribute("class", "hide");
}
}
}
// This function is for set panel visibilty.
function setPanel(panelId, status) {
panel = document.getElementById(panelId);
panel.setAttribute("data-visible", status);
// Calling the showPanel function to check in the DOM.
showPanel(["ReferencesPanel", "InformationPanel", "ImagesPanel", "FootnotesPanel"]);
}
// Binding the change event to the select tag.
selPanels.addEventListener("change", function() {
// Executes setPanel function with panelId and true to update the data-visible attribute in the DOM.
setPanel(this.options[this.selectedIndex].value, "true");
});
// Executes showPanel function with array argument with panels Id. You need to specify every panel that want to handle.
showPanel(["ReferencesPanel", "InformationPanel", "ImagesPanel", "FootnotesPanel"]);
})();
#global {
border: solid 1px #6291AD;
}
.tools {
background-image: linear-gradient(#FFFFFF, #8999CE);
}
#global div[data-visible] {
height: 80px;
padding: 5px 0;
}
#global div p {
padding: 10px;
}
#ReferencesPanel {
background-image: linear-gradient(#FFFFFF, #FD9A9A);
float: left;
width: 20%;
}
#InformationPanel {
background-image: linear-gradient(#FFFFFF, #A1C7F1);
float: left;
width: 80%;
}
#ImagesPanel {
background-image: linear-gradient(#C6E9FB, #FFF);
width: 100%;
}
#FootnotesPanel {
background-image: linear-gradient(#C6E999, #FFF);
width: 100%;
}
.clear {
clear: both;
}
.show {
display: block;
}
.hide {
display: none;
}
<div id="global">
<div class="tools">Show Panel:
<br />
<!-- Demo -->
<select id="selPanels">
<option value="">[SELECT]</option>
<option value="ReferencesPanel">ReferencesPanel</option>
<option value="InformationPanel">InformationPanel</option>
<option value="ImagesPanel">ImagesPanel</option>
<option value="FootnotesPanel">FootnotesPanel</option>
</select>
</div>
<!-- You need to set data-visible attribute with true or false to show or hide a panel. -->
<div id="ReferencesPanel" data-visible="false">
<p>References Panel</p>
</div>
<div id="InformationPanel" data-visible="false">
<p>Information Panel</p>
</div>
<div class="clear"></div>
<div id="ImagesPanel" data-visible="false">
<p>Images Panel</p>
</div>
<div id="FootnotesPanel" data-visible="false">
<p>Foot notes Panel</p>
</div>
</div>
I dont understand your question exactly, but if you want to define a variable that contains other variables then you can use an object.
e.g:
var footNotesPanel = true;
var referencesPanel = true;
var imagesPanel = true;
var showPanels = {
footNotesPanel: footNotesPanel,
referencesPanel: referencesPanel,
imagesPanel: imagesPanel
}
/*
Option 2 - for showing/hiding side panels
1 ) create all your panels as they would appear, with all the data, but hide them with display:none;
2 ) call show panel function to show a panel.
*/
var showPanel(panel_id) {
var panel_element = $("#" + panel_id); /*panel that you want to show ( is hidden atm but somewhere on the page */
if (!panel_element.length) {
return false; //no panel with this id currently on page
} else {
//check the panel id and do some custom editing if needed, eg.
if (panel_id == "main_side_panel") {
//add some additional classes to body element etc
}
panel_element.show();
//Or Another option that you probably are looking for is below
if (panel_id == "footnotes_panel") {
showFootnotesPanel();
} else if (panel_id == "images_panel") {
showImagesPanel();
}
}
}
// And use it like this:
<div id="footnotes_panel" onclick="showPanel('footnotes_panel')"></div>
// Or simply get the element id from `event.target` and use `showPanel()` without arguments.
I'm using a word count textarea jquery script and I'm trying to work out how to update the word count onload to e.g. 2 from the preset text area "this example" to start with.
(it currently shows 0)
I can set the focus on it and move the cursor but I don't know how to update it initially, any ideas?
HTML
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="js/jQuery.textareaCounter.c.js"></script>
<textarea id="txtarea" name="text" rows="7" cols="120">this example</textarea>
<script type="text/javascript">
$("textarea").textareaCounter();
document.getElementById('txtarea').focus();
var val = document.getElementById('txtarea').value; //store the value of the element
document.getElementById('txtarea').value = ''; //clear the value of the element
document.getElementById('txtarea').value = val; //set that value back. so cursor is at end.
</script>
jquery.min.js contains:-
(function(a){a.fn.textareaCounter=function(b){var c={limit:10};var b=a.extend(c,b);return this.each(function(){var c,d,e,f;c=a(this);c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">Max. '+b.limit+" words</span>");c.keyup(function(){d=c.val();if(d===""){e=0}else{e=a.trim(d).split(" ").length}if(e>b.limit){a("#counter-text").html('<span style="color: #DD0000;">0 words left</span>');f=a.trim(d).split(" ",b.limit);f=f.join(" ");a(this).val(f)}else{a("#counter-text").html(b.limit-e+" words left")}})})}})(jQuery)
jQuery.textareaCounter.c.js contains:-
(function(a) {
a.fn.textareaCounter = function(b) {
var c = {
limit: 10
};
var b = a.extend(c, b);
return this.each(function() {
var c, d, e, f;
c = a(this);
c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">' + "0 words</span>");
c.keyup(function() {
d = c.val();
if (d === "") {
e = 0
} else {
e = d.replace(/^[\s,.;]+/, "").replace(/[\s,.;]+$/, "").split(/[\s,.;]+/).length;
}
if (e > b.limit) {
// a("#counter-text").html('<span style="color: #DD0000;">0 words left</span>');
// f=a.trim(d).split(" ",b.limit);
// f=f.join(" ");
// a(this).val(f)
a("#counter-text").html(e + " words ")
document.myform.numwords.value = e;
} else {
a("#counter-text").html(e + " words ")
document.myform.numwords.value = e;
}
});
});
}
})
(jQuery)
This is what I changed in jQuery.textareaCounter.c.js:
var initCount = c.text().split(" ").length;
if(initCount < 2){initCount=0;}
c.after('<span style="font-size: 11px; clear: both; margin-top: 3px; display: block;" id="counter-text">' + initCount +" words</span>");
Here is the JSFiddle demo
You can fire a keyup event during initialization to trigger the update:
<script type="text/javascript">
$("textarea").textareaCounter();
document.getElementById('txtarea').focus();
var val = document.getElementById('txtarea').value; //store the value of the element
document.getElementById('txtarea').value = ''; //clear the value of the element
document.getElementById('txtarea').value = val; //set that value back. so cursor is at end.
// init word count
$("textarea")[0].dispatchEvent(new Event('keyup'));
</script>
//Function to show maxlength of Textarea
document.getElementById("textArea").addEventListener("keyup",function(){
var textAreaValue = document.getElementById("textArea").value;
var show = (250 - (textAreaValue.length));
document.getElementById('count').innerHTML = show + " characters remaining";
});
A little background of my problem:
I'm making a board-based game when the user is going to be able to make a path from a square to another one, the thing is that when a square is clicked it should stay highlighted no matter if pointer is over of it and then leaves it. It seems when the square is clicked and then the pointer leaves it the handlerIn of .hover() changes the state of the square's path-type attribute making possible to the square to be unhighlited when the pointer enter and leaves the square.
this is what I've got so far:
$(function() {
$('td.soccer-field').click(function(){
if ($('#dice1').text() != '' && $('#dice2').text() != '') {
if ($("[path-type='begin-path']").length == 0) {
$(this).attr('path-type','begin-path');
} else if ($("[path-type='begin-path']").length && $(this).attr('path-type') != 'end-path'){
$(this).attr('path-type','end-path');
$('[path-type="selecting-actual-path"]').attr('path-type','actual-path');
} else if ($(this).attr('path-type') == 'end-path'){
$(this).attr('path-type','');
};
}
});
$('td.soccer-field').hover(
function () {
if ($('#dice1').text() != '' && $('#dice2').text() != '') {
if ($("[path-type='begin-path']").length == 0) {
$(this).attr('path-type','select-begin-path');
} else if ($(this).attr('path-type') == ''){
var actualCell = $(this).attr('id') + $(this).parent().attr('id');
var cell, distance,dicesResult = parseInt($('#dice1').text())+ parseInt($('#dice2').text());
$("[path-type*='path']").each(function () {
cell = $(this).attr('id') + $(this).parent().attr('id');
distance = new Board().calculateDistanceSquares(actualCell,cell);
if (distance == 1 && $("[path-type='selecting-actual-path']").length < (dicesResult -2))
{
$(this).attr('path-type','selecting-actual-path');
return false;
}
});
}
};
},function () {
if ($(this).attr('path-type') == 'selecting-actual-path' || $(this).attr('path-type') == 'select-begin-path') {
$(this).attr('path-type','');
}
});
$('#diceRoller').click(function() {
$('#dice1').text(Math.floor(Math.random()*6)+1);
$('#dice2').text(Math.floor(Math.random()*6)+1);
$(this).attr('disabled',true);
});
});
//function Board(playerTurn, piecesPosition, gamePhase, gameBegginingType, container)
function Board(){
this.buildBoard = function (container) {
var board = $('<table></table>').attr('id','board');
var row, cell,containerHeight,containerWidth;
for (var i=0; i<10; i++){
row = $('<tr></tr>').attr('id',i+1);
for (var j=0; j<20; j++){
cell = $('<td></td>');
cell.attr('path-type','');
if ((j == 0 || j == 19) && (i >= 3) && (i <= 6)) {
cell.addClass('behind-goal');
}
else if ((j > 0) && (j < 19)){
cell.attr('id',String.fromCharCode(j+96));
cell.addClass("soccer-field");
};
row.append(cell);
}
board.append(row);
}
$('#'+container).append(board);
};
this.calculateHorizontalDistance = function (sq1,sq2) {
var column1 = sq1.substring(0,1).charCodeAt(0);
var column2 = sq2.substring(0,1).charCodeAt(0);
return ( Math.abs(column1-column2) );
};
this.calculateVerticalDistance = function (sq1, sq2) {
var row1 = parseInt(sq1.substring(1));
var row2 = parseInt(sq1.substring(1));
return ( Math.abs(row1-row2) );
};
this.calculateDistanceSquares = function(sq1, sq2){
return(this.calculateVerticalDistance(sq1,sq2)+this.calculateHorizontalDistance(sq1,sq2));
}
}
var board = new Board();
board.buildBoard('left');
#left table{
width: 60em;
height: 25em;
border:0.2em solid black;
border-collapse:collapse;
}
#left table tr{
height: 2.5em;
}
#left table tr td{
width: 3.33em;
}
td.soccer-field{
border: 0.1em solid black;
}
td.behind-goal{
background-color: #F8FAB4;
}
td[path-type*="path"]{
border: 0.15em solid #F8FAB4;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="boardContainer">
<div id="right">
<p id="dice1"></p><p id="dice2"></p>
<button id="diceRoller">Lanzar Dados</button>
</div>
<div id="left"></div>
</div>
A little help will be really appreciate
To prevent that you can add an attribute on the element whenever it is clicked and remove it later on second click. Now in the hover handler check for this attribute on the element, if it is present(or set) then don't do anything just return from the handler.
Something like this
$('td.soccer-field').click(function(){
$(this).data('clicked', !!$(this).data('clicked'));
...
...
});
$('td.soccer-field').hover(
function () {
if ($(this).data('clicked')) return;
...
...
},
function () {
if ($(this).data('clicked')) return;
...
...
});
I have a sentence where I fade in one word and replace it with another from an array. However, since the words all vary in length, the sentence width abruptly changes and it results in a choppy transition.
How can I animate the width change? I tried adding a transition to the container of the sentence in css but that didn't work. I applied the transition as 1.5s all linear, so it should be animating the width as well as everything else whenever there is change. Any ideas?
$(function() {
var hello = ['dynamic', 'a', 'aklsjdlfajklsdlkf', 'asdf'];
var used = ['dynamic'];
var greeting = $('#what');
var item;
function hey() {
item = hello[Math.floor(Math.random() * hello.length)];
if (hello.length != used.length) {
while (jQuery.inArray(item, used) != -1) {
item = hello[Math.floor(Math.random() * hello.length)];
}
used.push(item);
} else {
used.length = 0;
item = hello[Math.floor(Math.random() * hello.length)];
used.push(item);
}
greeting.html(item);
greeting.animate({
"opacity": "1"
}, 1500);
}
window.setInterval(function() {
greeting.animate({
"opacity": "0"
}, 1500);
setTimeout(hey, 1500)
}, 5000);
});
#sentence {
transition: 1.5s all linear;
}
#what {
font-style: italic;
text-decoration: underline;
color: red;
}
<p id="sentence">
This is a sentence that has <span id="what">dynamic</span> text that alters width.
</p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
EDIT: Sorry if I was unclear, I only want to fade out the word, not the entire sentence. I'm trying to animate the width to fit the new word. I don't want to change/add any elements, just solve with the current tags in place.
function dataWord () {
$("[data-words]").attr("data-words", function(i, d){
var $self = $(this),
$words = d.split("|"),
tot = $words.length,
c = 0;
// CREATE SPANS INSIDE SPAN
for(var i=0; i<tot; i++) $self.append($('<span/>',{text:$words[i]}));
// COLLECT WORDS AND HIDE
$words = $self.find("span").hide();
// ANIMATE AND LOOP
(function loop(){
$self.animate({ width: $words.eq( c ).width() });
$words.stop().fadeOut().eq(c).fadeIn().delay(1000).show(0, loop);
c = ++c % tot;
}());
});
}
// dataWord(); // If you don't use external fonts use this on DOM ready; otherwise use:
$(window).on("load", dataWord);
p{text-align: center;font-family: 'Open Sans Condensed', sans-serif;font-size: 2em;}
/* WORDS SWAP */
[data-words]{
vertical-align: top;
position: static;
}
[data-words] > span{
position: absolute;
color: chocolate;
}
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
We provide
<span data-words="code|solutions|design"></span>
for your business.
</p>
<p>
You ordered
<span data-words="1|3|28"></span>
<b>big</b>
<span data-words="salad|macs|chips"></span>
</p>
When you set new word for your sentence, you can save #what width and then make an animation with this width too. Like this:
// declare as global variable and update when you set new word
var width = greeting.css('width');
// animation
greeting.animate({
"opacity": "0", "width": width
}, 1500, function(){
});
I have had the same problem and went with a different approach, not fading but typing: jsfiddle demo
function type($el, text, position) {
if (text.length >= position) {
var rchars = 'qbvol'; // typo chars
if (position % 3 == 0 && Math.random() > .85) { // insert typo!
var typo;
var chr = text.substr(position, 1);
if (chr == chr.toUpperCase()) { typo = chr.toLowerCase(); }
else { typo = rchars.substr(Math.floor(Math.random() * rchars.length), 1); }
$el.text(text.substring(0, position - 1) + typo + '_');
setTimeout(function() { type($el, text, position - 1); }, 200)
}
else {
$el.text(text.substring(0, position) + '_');
setTimeout(function() { type($el, text, position + 1); }, 150)
}
}
else {
setTimeout(function() { $el.text(text); }, 400)
}
}
It basically inserts your new text on the page, with a nice caret and typo to make it look like someone is typing it.
Try this out:- http://jsfiddle.net/adiioo7/c8fFU/13/
You can update the sentence effect depending upon your requirement. Currently it is using fadein/fadeout.
JS:-
$(function () {
var hello = ['jupiter', 'a', 'aklsjdlfajklsdlkf', 'asdf'];
var used = ['jupiter'];
var greeting = $('#what');
var item;
var sentence = $('#sentence');
function hey() {
item = hello[Math.floor(Math.random() * hello.length)];
if (hello.length != used.length) {
while (jQuery.inArray(item, used) != -1) {
item = hello[Math.floor(Math.random() * hello.length)];
}
used.push(item);
} else {
used.length = 0;
item = hello[Math.floor(Math.random() * hello.length)];
used.push(item);
}
greeting.html(item);
greeting.animate({
"opacity": "1"
}, 1500);
sentence.fadeIn(1500);
}
window.setInterval(function () {
sentence.fadeOut(1500);
greeting.animate({
"opacity": "0"
}, 1500);
setTimeout(hey, 1500);
}, 5000);
});