I have written an javascript that generates the dynamic elements based on the jSON data supplied to it.
$(function () {
var list = JSON.parse(#ViewBag.NomineeList);
var counter = 1;
var tr;
$(list).each((function () {
if (counter % 2 != 0) {
tr = CreateElems('tr', null, null);
}
var td = CreateElems('td', null, null);
var div = CreateElems('div', 'dvBorder', null);
div.attr('empID', this.EmpId);
div.attr('nomineeID', this.Id);
RegisterEvents(div);
div.append('<img alt="user" src=' + this.UserImagePath + ' style="padding: 5px;" />');
div.append(CreateElems('span', 'EmpolyeeName', this.FirstName));
div.append(CreateElems('span', 'EmployeeEmail', this.Email));
td.append(div);
tr.append(td);
if (counter % 2 == 0) {
$('#tblEmployee').append(tr);
tr = "";
}
counter++;
}));
});
function CreateElems(type,cssClass,value)
{
var elem = $(document.createElement(type));
if(value != null)
elem.text(value);
if(cssClass!= null)
elem.addClass(cssClass);
return elem;
}
There are three different events that i have registered for the dynamic elements that are created.
function RegisterEvents(crntDiv) {
var url;
$(crntDiv).click(function () {
url = "/home/SaveVote?nomineeId=" + $(crntDiv).attr('nomineeID');
AjaxCall(url, false, crntDiv);
});
$(crntDiv).mouseover(function () {
RemoveToolTip();
url = "/home/GetDescription?nomineeId=" + $(crntDiv).attr('nomineeID');
AjaxCall(url, true, crntDiv);
});
$(crntDiv).mouseout(function () {
$(crntDiv).children('div.RollOverTip').remove();
});
}
when you mouse over the tool tip comes up . On that event I am checking if any previous tool tip is present in dom it should be removed.
function RemoveToolTip() {
$('#tblEmployee').find('div.RollOverTip').remove();
}
But still there are times when there are more than two three tool tips are present on the browser. Also can this be optimized a bit.
Html
<table border="0" cellpadding="5" cellspacing="0" id="tblEmployee">
</table>
css Classes.
.dvBorder
{
background-image: url(/Images/screen2-button.png);
background-repeat: no-repeat;
height: 125px;
width: 400px;
cursor:pointer;
position: relative;
}
.RollOverTip
{
background-image: url("/Images/screen2-rollover-tooltip.png");
background-repeat: no-repeat;
color: #000000;
font-family: Calibri Regular;
font-size: 18pt;
height: 199px;
line-height: 20pt;
margin-left: 385px;
position: absolute;
width: 474px;
z-index: 90000;
padding:34px;
}
What are the optimization possible in the script,also any suggestions to remove the flickering?
Try using mouseenter and mouseleave to stop the flickering
$(crntDiv).mouseenter(function () {
RemoveToolTip();
url = "/home/GetDescription?nomineeId=" + $(crntDiv).attr('nomineeID');
AjaxCall(url, true, crntDiv);
});
$(crntDiv).mouseleave(function () {
$(crntDiv).children('div.RollOverTip').remove();
});
Try to use mouseenter and mouseleave it might fix the problem instead of mouseover and mouseout
EDIT
Try this :
change
$(crntDiv).mouseover(function () {...}
to
$(document).on('mouseenter',$(crntDiv,'#tblEmployee div.RollOverTip'), function () {...}
Related
I am trying to dynmaically create round checkboxes with tickMark which get appended to id="demo" onclick of two buttons which call get(data) method.
The issue is when two buttons called simulataneously, checkbox is not getting tick mark and causing call of getdata(idD + '_chckBox') method twice or more as seen in console.log.
However, I am using e.preventDefault(); e.stopPropagation();.
What is the issue here, the getdata(idD + '_chckBox') is called twice or more and roundcheckbox is not getting checked?
I am trying to toggle checkbox and show tick mark. If any better way of doing this possible, is also welcomed.
what is the best and easiest way to bind onclick and onscroll method in dynamic htmls which are in for loop, so that a object can be passed as a parameter in called method onclick.
index.html
var data0 = [{
"title": "a"
},
{
"title": "b"
},
{
"title": "c"
},
{
"title": "d"
},
];
var data1 = [{
"title": "ads"
},
{
"title": "bd"
},
{
"title": "fc"
},
{
"title": "dg"
},
];
var html = "<div id='parent' ' + 'onscroll="loadMoreContent(event)" ></div>";
$(html ).appendTo('body');
$(document).on('click', '#btn11', () => {
get(data0, 'parent');
})
$(document).on('click', '#btn00', () => {
get(data1,'parent');
})
function loadMoreContent(event){
// gettting server data (data01 ) on ajax call
var data01 = [{
"title": "aaa"
},
{
"title": "sdw3b"
},
{
"title": "c433"
},
{
"title": "34d"
},
];
get(data01 , idToAppend)
}
function get(data, idToAppend) {
var html = '';
html += '<div class="col-12 parentdiv">';
$.each(data, function(key, msgItem) {
var idD = msgItem.title + key;
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget" id="' + idD + '_roundCheckboxWidget">';
html += '<input id="' + idD + '_chckBox" class="" type="checkbox" tid="" title="discard">';
html += '<label id="' + idD + '_chckBox_label" for="' + msgItem.title + '" ></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
});
html += '</div>';
$('#'+ idToAppend).append(html);
$.each(data, function(index, element) {
var idD = element.title + index;
const self = this;
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
});
}
function getdata(id) {
console.log(id);
$("#" + id).prop("checked", !$("#" + id).prop("checked"));
return true;
}
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11" onclick="get()">Try It</button>
<button id="btn00" onclick="get()">Try It2</button>
<div id="demo"></div>
There is several mistakes here.
You use some id that aren't unique. There is an attempt to make them unique, but you used the array key, which is static. So on every button click, duplicate ids are produced. You need a counter.
You use an .each() loop to define a delegated event handler... Which is a misunderstanding of delegation.
You use a function to toggle the checkbox state when the for= attribute on the label can do it without a single line of code.
The loadMoreContent() function is unclear... I assumed you want an "infinite scroll"... So you have to check if the bottom of the page is reached to call the Ajax request... Else, you will fire tons of request on each scroll... up and down!
So here is how to do it:
(See comment within code)
// checkbox title arrays
var data0 = [{ "title": "a" }, { "title": "b" }, { "title": "c" }, { "title": "d" }];
var data1 = [{ "title": "ads" }, { "title": "bd" }, { "title": "fc" }, { "title": "dg" }];
// Appends th "parent" div on load.
var html = "<div id='parent'></div>";
$(html).appendTo('body');
// Button handlers
$(document).on('click', '#btn11', () => {
get(data0,'parent');
})
$(document).on('click', '#btn00', () => {
get(data1,'parent');
})
// Simulated Ajax request... I assume.
function loadMoreContent(idToAppend){
// gettting server data (data01 ) on ajax call
var data01 = [{ "title": "aaa" }, { "title": "sdw3b" }, { "title": "c433" }, { "title": "34d" } ];
get(data01 , idToAppend)
}
// Main function. It needs a counter to create UNIQUE ids.
var checkbox_counter = 0;
function get(data, idToAppend) {
var html = '';
html += '<div class="col-12 parentdiv">';
$.each(data, function(key, msgItem) {
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget">';
html += '<input id="checkbox_'+checkbox_counter+'" type="checkbox" tid="" title="discard">';
html += '<label for="checkbox_'+checkbox_counter+'"></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
// Increment the checkbox counter
checkbox_counter++;
});
html += '</div>';
$('#'+ idToAppend).append(html);
}
// Just to console log the id of the checkbox...
$(document).on('click', 'label', function(){
var checkbox_id = $(this).prev("[type='checkbox']").attr("id");
console.log(checkbox_id);
});
// On scroll handler, check if the bottom of the page is reached to load some more...
$(document).on('scroll', function(){
var scrolled = Math.ceil($(window).scrollTop());
var viewport_height = $(window).outerHeight();
var window_full_height = $(document).outerHeight();
//console.log(scrolled +" "+ viewport_height +" "+ window_full_height);
if(scrolled + viewport_height == window_full_height){
console.log("reached the bottom... Loading some more!");
// Call the Ajax request
loadMoreContent("parent");
}
});
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11" onclick="get()">Try It</button>
<button id="btn00" onclick="get()">Try It2</button>
<div id="demo"></div>
CodePen
There are two problems with code:
You are setting onclick="get()" and also adding click event using jQuery so it will trigger twice. remove onclick ="get()"
Second problem is that on every get() call it will add new click listeners to checkboxes. To prevent that use a boolean in your array only apply click event once
var data0 = [{
"title": "a"
},
{
"title": "b"
},
{
"title": "c"
},
{
"title": "d"
},
false
];
var data1 = [{
"title": "ads"
},
{
"title": "bd"
},
{
"title": "fc"
},
{
"title": "dg"
},
false
];
$(document).on('click', '#btn11', () => {
get(data0);
})
$(document).on('click', '#btn00', () => {
get(data1);
})
function get(data) {
var html = '';
html += '<div class="col-12 parentdiv"';
$.each(data, function(key, msgItem) {
var idD = msgItem.title + key;
html += '<div class="flLeftBlock" style="width: 30px;margin-top: 36px;">';
html += '<div class="roundCheckboxWidget" id="' + idD + '_roundCheckboxWidget">';
html += '<input id="' + idD + '_chckBox" class="" type="checkbox" tid="" title="discard">';
html += '<label id="' + idD + '_chckBox_label" for="' + msgItem.title + '" ></label> ';
html += " " + msgItem.title;
html += '</div>';
html += '</div>';
html += '';
});
html += '</div>';
$('#demo').html(html);
if(data[data.length - 1]) return false;
$.each(data, function(index, element) {
var idD = element.title + index;
const self = this;
if(index === data.length - 1) return false;
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
//console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
});
data[data.length -1] = true;
}
function getdata(id) {
//console.log(id);
$("#" + id).prop("checked", !$("#" + id).prop("checked"));
return true;
}
.roundCheckboxWidget {
position: relative;
}
.roundCheckboxWidget label {
background-color: #ffffff;
border: 1px solid rgb(196, 196, 209);
border-radius: 50%;
cursor: pointer;
height: 22px;
left: 0;
position: absolute;
top: 0;
width: 22px;
}
.roundCheckboxWidget label:after {
border: 2px solid #fff;
border-top: none;
border-right: none;
content: "";
height: 6px;
left: 4px;
opacity: 0;
position: absolute;
top: 6px;
transform: rotate(-45deg);
width: 12px;
}
.roundCheckboxWidget input[type="checkbox"] {
visibility: hidden;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
/* background-color: #6168e7 !important;
border-color: 1px solid #6168e7 !important; */
}
.roundCheckboxWidget input[type="checkbox"]:checked+label:after {
opacity: 1;
}
.roundCheckboxWidget input[type="checkbox"]:checked+label {
background-color: #ff5b6a;
border-color: #ff5b6a !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Alternate click on two buttons without refreshing causing getdata() method call twice. </p>
<button id="btn11">Try It</button>
<button id="btn00">Try It2</button>
<div id="demo"></div>
TL;DR
Unbind the event handlers before binding a new one. Use this code:
$(document).off('click', '#' + idD + '_chckBox_label').on('click', '#' + idD + '_chckBox_label', (e) => {
Long Answer
You cannot use e.preventDefault(); e.stopPropagation(); to stop different function calls. Here is the thing,
let's say you have an element in your dom and you added event handlers twice, in this case, those two event handlers will be executed no matter what.
What you need here is,
"remove the existing click handler before adding a new one".
This line:
$(document).on('click', '#' + idD + '_chckBox_label', (e) => { adds event handler to a label. But when you click on a button again, this runs again and adds another event handler.
So the number of times you click on your button, that's the same number of event handlers you are adding to your element.
But when you refresh, it's fixed. Reason: refreshing the page loads an entirely new page, and all previous handlers are gone. You need to do this programmatically, and here is how you can do it.
$(document).off('click', '#' + idD + '_chckBox_label').on('click', '#' + idD + '_chckBox_label', (e) => {
This code tells that, switch off any previous click handler and add a new one.
Bonus:
If you have named functions, you can remove the specific event handlers, for example:
$(document).off(<event_type>, <el_selector>, <event_handler>).on(<event_type>, <el_selector>, <event_handler>);
Hope this helps. Let me know if you have any counter question.
PS: There were a couple of typos in the code when I copy pasted, but I think running the code is not the agenda here :)
You have 2 click event listeners here:
$(document).on('click', '#btn11', () => {
get(data0);
})
$(document).on('click', '#btn00', () => {
get(data1);
})
Your get() function conatins two $.each() loops, the second of which is adding another event listener here:
$(document).on('click', '#' + idD + '_chckBox_label', (e) => {
if (e.target.tagName === "LABEL") {
e.preventDefault();
e.stopPropagation();
console.log('#' + idD + '_chckBox_label');
getdata(idD + '_chckBox');
}
});
From what I can tell, by the time you click the second button there are potentially 3 event listeners responding to that event.
I'm building a page that first gets the HTML data from an external page (Not cross domain), then after the first function completes, it runs a function which is a sideshow. It works... More or less...
The problem that I'm having is that after 5 or 6 slides, the whole thing gets messy and then everything disappears. When checking the console, I found the following message:
Uncaught DOMException: Failed to execute 'insertBefore' on 'Node': The new child element contains the parent.
at HTMLDivElement.<anonymous> (xxxxxxxxxxxxxxxxx.com/jquery/jquery-1.12.4.js:6297:21)
at domManip (xxxxxxxxxxxxxxxxx.com/jquery/jquery-1.12.4.js:6066:14)
at jQuery.fn.init.after (xxxxxxxxxxxxxxxxx/jquery/jquery-1.12.4.js:6295:10)
at HTMLDivElement.<anonymous> (xxxxxxxxxxxxxxxxx.com/go/scripts/jqueryautoscroll/autoscroll.js:41:47)
at HTMLDivElement.opt.complete (xxxxxxxxxxxxxxxxx/jquery/jquery-1.12.4.js:7900:12)
at fire (xxxxxxxxxxxxxxxxx.com/jquery/jquery-1.12.4.js:3232:31)
at Object.fireWith [as resolveWith] (xxxxxxxxxxxxxxxxx/jquery/jquery-1.12.4.js:3362:7)
at tick (xxxxxxxxxxxxxxxxx.com/jquery/jquery-1.12.4.js:7755:14)
at jQuery.fx.tick (xxxxxxxxxxxxxxxxx.com/jquery/jquery-1.12.4.js:8069:9)
I presume it has something to do with the container.find(elm + ':first').before(container.find(elm + ':last'));
So I tried commenting all the lines, the error was gone, but then the sliders wouldn't change.
My code is as follows:
jQuery(document).ready(function ($) {
$("#jobshome").load("jobs/newest-jobs .js-toprow", function(){
//rotation speed and timer
var speed = 3000;
var run = setInterval(rotate, speed);
var slides = $('.js-toprow');
var container = $('#jobshome');
var elm = container.find(':first-child').prop("tagName");
var item_height = container.height();
var previous = 'prevabc'; //id of previous button
var next = 'nextabc'; //id of next button
slides.height(item_height); //set the slides to the correct pixel height
container.parent().height(item_height);
container.height(slides.length * item_height); //set the slides container to the correct total height
container.find(elm + ':first').before(container.find(elm + ':last'));
resetSlides();
//if user clicked on prev button
$('#buttonsabc a').click(function (e) {
//slide the item
if (container.is(':animated')) {
return false;
}
if (e.target.id == previous) {
container.stop().animate({
'top': 0
}, 1500, function () {
container.find(elm + ':first').before(container.find(elm + ':last'));
resetSlides();
});
}
if (e.target.id == next) {
container.stop().animate({
'top': item_height * -2
}, 1500, function () {
container.find(elm + ':last').after(container.find(elm + ':first'));
resetSlides();
}
);
}
//cancel the link behavior
return false;
});
//if mouse hover, pause the auto rotation, otherwise rotate it
container.parent().mouseenter(function () {
clearInterval(run);
}).mouseleave(function () {
run = setInterval(rotate, speed);
});
function resetSlides() {
//and adjust the container so current is in the frame
container.css({
'top': -1 * item_height
});
}
});
//a simple function to click next link
//a timer will call this function, and the rotation will begin
function rotate() {
jQuery('#nextabc').click();
}
});
#carouselabc {
position: relative;
width: 60%;
margin: 0 auto;
}
#slidesabc {
overflow: hidden;
position: relative;
width: 100%;
height: 250px;
}
#areadoslideabc {
list-style: none;
width: 100%;
height: 250px;
margin: 0;
padding: 0;
position: relative;
}
#slidesabcdef {
width: 100%;
height: 250px;
float: left;
text-align: center;
position: relative;
font-family: lato, sans-serif;
}
/* Styling for prev and next buttons */
.btn-barabc {
max-width: 346px;
margin: 0 auto;
display: block;
position: relative;
top: 40px;
width: 100%;
}
#buttonsabc {
padding: 0 0 5px 0;
float: right;
}
#buttonsabc a {
text-align: center;
display: block;
font-size: 50px;
float: left;
outline: 0;
margin: 0 60px;
color: #b14943;
text-decoration: none;
display: block;
padding: 9px;
width: 35px;
}
a#prevabc:hover,
a#next:hover {
color: #FFF;
text-shadow: .5px 0px #b14943;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="carouselabc">
<div class="btn-barabc">
<div id="buttonsabc">
<a id="prevabc" href="#">Previous</a>
<a id="nextabc" href="#">Next</a>
</div>
</div>
<div id="slidesabc">
<div id="jobshome"></div>
</div>
</div>
Screenshot 1
Screenshot 2
This is how it starts
Your problem seems to happen because of the nested selectors (.js-toprow) that are later moved.
Try replacing all the .find() (matches children any level deep) with .children() (matches only immediate children).
jQuery(document).ready(function ($) {
$("#jobshome").load("jobs/newest-jobs .js-toprow", function(){
//rotation speed and timer
var speed = 3000;
var run = setInterval(rotate, speed);
var slides = $('.js-toprow');
var container = $('#jobshome');
var elm = container.children(':first-child').prop("tagName");
var item_height = container.height();
var previous = 'prevabc'; //id of previous button
var next = 'nextabc'; //id of next button
slides.height(item_height); //set the slides to the correct pixel height
container.parent().height(item_height);
container.height(slides.length * item_height); //set the slides container to the correct total height
container.children(elm + ':first').before(container.children(elm + ':last'));
resetSlides();
//if user clicked on prev button
$('#buttonsabc a').click(function (e) {
//slide the item
if (container.is(':animated')) {
return false;
}
if (e.target.id == previous) {
container.stop().animate({
'top': 0
}, 1500, function () {
container.children(elm + ':first').before(container.children(elm + ':last'));
resetSlides();
});
}
if (e.target.id == next) {
container.stop().animate({
'top': item_height * -2
}, 1500, function () {
container.children(elm + ':last').after(container.children(elm + ':first'));
resetSlides();
}
);
}
//cancel the link behavior
return false;
});
//if mouse hover, pause the auto rotation, otherwise rotate it
container.parent().mouseenter(function () {
clearInterval(run);
}).mouseleave(function () {
run = setInterval(rotate, speed);
});
function resetSlides() {
//and adjust the container so current is in the frame
container.css({
'top': -1 * item_height
});
}
});
//a simple function to click next link
//a timer will call this function, and the rotation will begin
function rotate() {
jQuery('#nextabc').click();
}
});
I am writing a simple jQuery plugin for my purpose, which:
creates a background div (for blocking purposes, like a modal dialog). (referenced with backDiv)
shows that background.
shows $(this).
removes background and hides $(this) when background clicked.
I am able to do all of these except 4th one: As I can't save a reference to the background div, I cannot get it back and remove it.
I tried $(this).data('backDiv',backDiv); and $(this)[0].backDiv = backDiv;
I know that there are various plugins that does this including the jQuery's own dialog function, but I want to create my own version.
I cannot keep this variable globally, so, how can I keep a reference to backDiv in a jQuery object, (or DOM object?) if that's even possible at all?
update: I allow multiple of these elements show on top of each other: Nested modal dialogs.
update-2:
(function($) {
$.fn.showModal = function() {
var backDiv = $('<div style="width: 100%; height: 100%; background-color: rgba(55, 55, 55, 0.5); position:absolute;top:0px;left:0px;">This is backDiv</div>');
$(this).data('backDiv', backDiv);
$('body').append(backDiv);
//TODO: bringToFront(backDiv);
$(this).show();
//TODO: bringToFront($(this);
var thisRef = $(this);
backDiv.click(function() {
thisRef.closeModal();
});
return $(this);
};
$.fn.closeModal = function() {
//PROBLEM (null): var backDiv = $(this).data('backDiv');
//backDiv.remove();
$(this).data('backDiv', '');
$(this).hide();
}
}(jQuery));
$(document).ready(function() {
$('#a').showModal();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="a" style="display:none;z-Index:2;background:red; width: 100px; height:50px;position:absolute"></div>
I suggest you to work in terms of complex dom objects, something similar angular directives, basically, you have to work with components that are represented in the dom as Group of Objects.
So, following what I'm saying, your modal component should be something like that:
var Modal = (function($) {
var tpl = '<div style="display:none;" class="modal"><div class="modal-backdrop"></div><div class="modal-content"></div></div>';
function Modal(container) {
var self = this;
this.container = $(container || 'body');
this.tpl = $(tpl).appendTo(this.container);
this.content = $('.modal-content', this.tpl);
this.backdrop = $('.modal-backdrop', this.tpl);
this.isOpened = false;
this.ANIMATION_DURATION = 500;
this.backdrop.click(function(e) { self.toggle(e) });
}
Modal.prototype.show = function(cb) {
var self = this;
cb = $.isFunction(cb) ? cb : $.noop;
this.tpl.fadeIn(this.ANIMATION_DURATION, function() {
self.isOpened = true;
cb();
});
return this;
};
Modal.prototype.hide = function(cb) {
var self = this;
cb = $.isFunction(cb) ? cb : $.noop;
this.tpl.fadeOut(this.ANIMATION_DURATION, function() {
self.isOpened = false;
cb();
});
return this;
};
Modal.prototype.toggle = function() {
if(this.isOpened) {
return this.hide();
}
return this.show();
};
Modal.prototype.setContent = function(content) {
this.content.html($('<div />').append(content).html());
return this;
};
return Modal;
})(window.jQuery);
function ExampleCtrl($) {
var modal = new Modal();
modal.setContent('<h1>Hello World</h1>');
$('#test').click(function() {
modal.show();
});
}
window.jQuery(document).ready(ExampleCtrl);
.modal {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.modal .modal-backdrop {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, .8);
}
.modal .modal-content {
width: 300px;
height: 150px;
background: #fff;
border: 1px solid yellow;
position: absolute;
left: 50%;
top: 50%;
margin-left: -150px;
margin-top: -75px;
line-height: 150px;
text-align: center;
}
h1 {
line-height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="test">Test Modal</button>
Add data-backDiv="" into you dynamic modal div
Change below
var backDiv = $('<div data-backDiv="" style="width: 100%; height: 100%; background-color: rgba(55, 55, 55, 0.5); position:absolute;top:0px;left:0px;">This is backDiv</div>');
In order to retrive data attribute value using JQuery use following code
Syntax
$('selector').data('data-KeyName');
Example
1. $(this).data('backDiv'); // use to retrive value or
2. var temp=$(this).data('backDiv'); // use to retrive value and assign into variable
I would like to create a little slider to change background-image of my div every seconds.
My code doesn't work for the moment, image is not changed. And ideally, i would like that the script run in infinite mode..
HTML
<div id="slidesPartenairesHome"></div>
CSS
#slidesPartenairesHome {
background-size: contain;
background-position: center center;
width: 300px;
height: 170px;
margin-left: 120px;
}
JS
$( document ).ready(function() {
var arrayOfPartenaires = [
"images/partenaires/a.png",
"images/partenaires/b.jpg",
"images/partenaires/c.jpg",
"images/partenaires/d.png",
"images/partenaires/e.png",
"images/partenaires/f.jpg",
"images/partenaires/g.jpg",
"images/partenaires/h.jpg",
"images/partenaires/i.png",
"images/partenaires/j.jpg",
"images/partenaires/k.jpg",
"images/partenaires/l.jpg"
];
for (var i=0; i<arrayOfPartenaires.length; i++) {
var currentPartenaireImg = arrayOfPartenaires[i];
$('#slidesPartenairesHome').animate({opacity: 0}, 'slow', function() {
$(this).css({'background-image': 'url("'+currentPartenaireImg+')'}).animate({opacity: 1});
});
}
});
You could use window.setinterval, you could also use setTimeout but setinterval is a litle bit more precise.
Example with setinteval:
window.setInterval(function(){
var url = getCurrent();
//start animation
$('#slidesPartenairesHome').delay( 500 ).fadeTo(500, 0.3, function()
{
$(this).css('background-image', 'url(' + url + ')');
}).fadeTo('slow', 1);
}, 1000);
// We start with index of 1 because we want to skip the first image,
// Else we would be replacing it with the same image.
var index = 1;
var arrayOfPartenaires = [
"http://yourdomain.com/images/partenaires/a.png",
"http://yourdomain.com/images/partenaires/b.png",
"http://yourdomain.com/images/partenaires/c.png"
];
function getCurrent(){
// We check if the index is higher than the ammount in the array.
// If thats true set 0 (beginning of array)
if (index > arrayOfPartenaires.length -1){
index = 0;
}
var returnValue = index;
index ++;
return arrayOfPartenaires[returnValue];
}
Note if you really want to change the image every 1 second the background will be changing very fast.
Fiddle
I hope this may help you
html
<div id="slidesPartenairesHome">
<div id="imags">
</div>
</div>
Css
#slidesPartenairesHome
{
margin-left: 120px;
}
#slidesPartenairesHome, #imags
{
background-size: contain;
background-position: center center;
width: 300px;
height: 170px;
}
Js
$(function () {
var arrayOfPartenaires = [
"http://fotos2013.cloud.noticias24.com/animales1.jpg",
"http://www.schnauzi.com/wp-content/uploads/2013/03/animales-en-primavera.jpg",
"https://johannagrandac.files.wordpress.com/2015/01/conejos.jpg",
"http://png-4.findicons.com/files/icons/1035/human_o2/128/face_smile.png",
"http://icons.iconarchive.com/icons/rokey/the-blacy/128/big-smile-icon.png",
"http://simpleicon.com/wp-content/uploads/smile-256x256.png"
];
var loaders = 0;
function cycleImages() {
var element = arrayOfPartenaires[loaders];
$("#imags").css({ 'background-image': 'url(' + element + ')' }).animate({ opacity: 1 }).hide().fadeIn("slow");
if (loaders < arrayOfPartenaires.length) {
loaders = loaders + 1;
if (loaders >= arrayOfPartenaires.length) {
loaders = 0;
}
}
else {
loaders = 0;
}
console.log(loaders, arrayOfPartenaires[loaders]);
}
cycleImages();
setInterval(function () { cycleImages() }, 3000);
});
jsFiddel Demo
I am trying to create a button on an <a href="#" ...> tag using HTML+CSS+Javascript+jQuery. The button displays properly. However, when I click on it nothing happens except for the default behavior (i.e., navigating to "#") . Any suggestions of what I am doing wrong? Here is my code:
//container is a div created with
//borderDiv = document.createElement('div') and
//document.body.appendChild(borderDiv);
function addMenuNavigation(container) {
var temp_innerHTML = '' +
'<div id="titleBar" class="titleBar">' +
'<div id="menuTitle" class="menuTitle"><img id="titleImage" style="height: 70px; position: absolute; top: 2px; left:120px"></img></div>' +
'<a href="#" class="leftButton" id="leftButton">' +
' <div style="position: relative; top: 6px;"><img src="' + getURL('img/menu/iPhoneStyle/chevronLeft.png') + '"></img></div>' +
'</a>' +
'</div>' + //titleBar
'';
container.innerHTML = temp_innerHTML;
var $leftButton = $('#leftButton');
console.dir($leftButton); //Indeed it does display the #leftButton element
//FIXME BUG 'MenuNavigation' below functions do not get registered ...
$('#leftButton').mousedown(function(e) {
$('#leftButton').addClass("pressed");
console.log('leftButton down ' + this.id);
});
$('#leftButton').mouseup(function(e) {
console.log('leftButton up ' + this.id);
$(this).removeClass("pressed");
});
$('#leftButton').click(function(e){
console.log('leftButton clicked ' + this.id);
click_e.preventDefault();
});
}
.css is as follows
.titleBar {
...
display: block;
height: 63px;
opacity: 0.8;
padding: 6px 0;
...
background-image: -webkit-gradient(linear, left top, left bottom,
from(#bbb), to(#444));
z-index: 35;
}
.leftButton:not(ac_hidden), .leftButton:not(pressed) {
left: 6px;
...
-webkit-border-image: url(../img/menu/iPhoneStyle/back_button.png) 0 8 0 8;
}
.leftButton.pressed{
-webkit-border-image: url(../img/menu/iPhoneStyle/back_button_clicked.png) 0 8 0 8;
}
I am working with Chrome.
Any suggestions? Thank you.
$('#leftButton').click(function(e){
console.log('leftButton clicked ' + this.id);
click_e.preventDefault();
});
should be e.preventDefault();
I personally prefer to add my event handlers this way:
function addMenuNavigation(container) {
var container = $(container).empty();
var titleBar = $('<div id="titleBar/>');
var leftButton = $('Image here').mousedown(leftButtonMousedown).mouseup(leftButtonMouseup).click(leftButtonClick).appendTo(titleBar);
titleBar.appendTo(container);
}
function leftButtonMouseDown(e) { //mouse down handler
}
function leftButtonMouseUp(e) { //mouse up handler
}
function leftButtonClick(e) {
e.preventDefault();
// handle the click here
}
Could it be that the browser hasn't finished adding your HTML to the DOM yet before you try to attach an event to it?
i.e, between these two lines?
container.innerHTML = temp_innerHTML;
var $leftButton = $('#leftButton');
In which case, perhaps you want to attach the events with .live(), http://api.jquery.com/live/