How to Loop on an array in Javascript? - javascript

When I run this code it reads only index 0 what is wrong?
Javascript:
function openTabs()
{
var data = document.getElementById('excelData').value;
var rows = data.split("\n");
for(var i = 0; i < rows.length; i++)
{
window.open('http://www.google.com/search?q=' + rows[i]);
}
}
HTML:
<textarea id = "excelData" name="excel_data" style="width:300px;height:580px;"></textarea><br>
<input type="button" onclick="openTabs()" value="Open Tabs"/>

There is nothing wrong with neither the code before the loop nor the loop itself. I suspect the browser you are using is blocking you from opening som many windows.
You can verify this by changing the line to something else, for example console.log(rows[i]); and see if that outputs more than the first element in the index.

This depends on the browser. If you are using Chrome, it will block opening multiple windows at the same instant. To allow this, in the address bar, click Pop-ups blocked and select "Always show pop-ups from [site]"

You can try by setting a the name property of the window.open method. ALong with that you may need to allow pop up from the browser.
Here is snippet to add name property to window.open
function openTabs() {
var data = document.getElementById('excelData').value;
var rows = data.split("\n");
for (var i = 0; i < rows.length; i++) {
// second parameter is the name
window.open('http://www.google.com/search?q=' + rows[i],'newWindow'+i);
}
}
DEMO
Allow popup from the browser option

Related

Event target should be anchor but is image instead

I am working on a dialog script in Vanilla JS. I ran into a problem with the click event on the video image. Even tough the image is surrounded with an anchor tag it shows the image as the event.target on the "trigger-dialog-open" event.
Here is the HMTL:
<a class="trigger-dialog--open thumbnail" data-dialog-id="dialog-video" href="javascript:;">
<figure>
<img src="http://i.ytimg.com/vi/id/sddefault.jpg" alt="" />
</figure>
</a>
And this is the event in JS:
var openTriggers = document.getElementsByClassName('trigger-dialog--open');
for (var i = 0; i < openTriggers.length; i++) {
openTriggers[i].addEventListener("click", function (event) {
this.openDialog(event.target.getAttribute('data-dialog-id'));
}.bind(this), false);
}
The event handler wants to know the dialog-id from the anchors data attribute. It can't be found because it thinks the image is the event.target, not the actual anchor. How can I correct this? Thanks!
Use event.currentTarget. The event.target is supposed to be the img element since that is what the user has clicked on. The click then bubbles up through the image's containers. event.currentTarget gives you the element that the click handler was actually bound to.
(Or if you didn't bind this to some other object you could use this within the click handler and it should also be the current target.)
I have a few questions is the var openTriggers supposed to be a part of a module hash? Because if it's global then you don't use a this, you only add a this, if it's referencing a variable that the function is also contained in. For example:
var aThing = {
openTriggers: document.getElementsByClassName('trigger-dialog--open'),
openModal: null,
openDialog: function(clickedThingAttr){
if(this.openModal !== null){
this.openModal.style.display = 'none';
}else{
this.openModal = document.getElementById(clickedThingAttr);
}
this.openModal = document.getElementById(clickedThingAttr);
this.openModal.style.display = 'block';
},
setEventListenersNStuff: function(){
for (var i = 0, n = this.openTriggers.length;i < n; i++) {
this.openTriggers[i].addEventListener("click", function (event) {
this.openDialog(event.target.getAttribute('data-dialog-id'));
});
};
}
};//end of aThing hash object
aThing.setEventListenersNStuff();
There are a few issues here:
1. why are you using .bind I think that is a jQuery thing, you want to pass a string to another function when an object is clicked, there no need for binding at all.
2. Also make sure that if you want to do something like open a modal, there is no need to call another method unless it's kinda complex.
3. What about other potential dialogs, it seems that when a .trigger-dialog--open is clicked you're just showing that one one modal with the embedded id, but what about others? Make sure all modals are closed before you open a new one, unless you want to have like 10 modals are open.
A thing to note: I added the line var i = 0, n = openTriggers.length;i < n; i++, now in this case it's silly optimization, and I heard for modern browsers this doesn't apply, but to explain why I added it, is because i < openTriggers.length would count and integrate the array N times. (This may be an outdated optmiziation).
If you meant global
Below I added a different set of code, just in case you meant that var openTriggers is global, kinda like you wrote above. Also I used querySelectorAll for this which is like jQuery's $('.thing') selector.
anyhoo, I also added
var openTriggers = document.querySelectorAll('.trigger-dialog--open');
var n = openTriggers.length;
function openDialog(ddId){
for (var i = 0;i < n; i++) {
openTriggers[i].style.display = 'none';
};
document.getElementById(ddId).style.display = 'block';
};
for (var i = 0;i < n; i++) {
openTriggers[i].addEventListener("click", function (event) {
openDialog(event.target.getAttribute('data-dialog-id'));
});
}
}
So for the question of hiding already open modals I would suggest you could either cache the open Dialog within a module, or you could toggle a class, which would be less efficient since it would require an extra DOM search. Additionally you could add a if this.openModal.id === clickedThingAttr to hide if open, that way you got a toggle feature.
Anyways I suggest you read up on this stuff, if you want to use plain JS but would like the features of jQuery: http://blog.romanliutikov.com/post/63383858003/how-to-forget-about-jquery-and-start-using-native
Thank you for your time.
You can use a closure
var openTriggers = document.getElementsByClassName('trigger-dialog--open');
for (var i = 0; i < this.openTriggers.length; i++) {
(function(element) {
element.addEventListener("click", function (event) {
element.openDialog(event.target.getAttribute('data-dialog-id'));
}, false)
})(openTriggers[i]);
}

Reload a content almost invisibly and no blinking effect using JAVASCRIPT

I'm writing a small progam wherein I'm getting data using $.get then display the data so far so good and then there's this part then when I click a certain link it refresh the page but it has this blinking effect. Is there a way on how to reload the content get the new updated content then replace the previously loaded data.
NOTE: I didn't use setInterval or setTimeout function because it slows down the process of my website. any answer that does not include those functions are really appreciated.
Here's the code
function EmployeeIssues(){
$('#initial_left').css({'display' : 'none'});
var table = $('#table_er');
$.get('admin/emp_with_issues', function(result){
var record = $.parseJSON(result);
var data = record.data,
employees = data.employees,
pages = data.pages;
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
for (var i = 0; i < employees.length; i++) {
$('#table_er').fadeIn('slow');
table.append(write_link(employees[i])); // function that displays the data
}
if(pages){
$('#pagination').html(pages);
}
}else{
$('#er_tab_label').html('<b>No employees with issues yet.</b>');
}
});
table.html('');
}
then this part calls the function and display another updated content
$('#refresh_btn').on('click', function(e){
e.preventDefault();
var tab = $('#tab').val();
if(tab == 'er'){
EmployeeIssues();
}
});
What should I do to display the content without any blinking effect?
thanks :-)
This section might be the issue :
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
for (var i = 0; i < employees.length; i++) {
$('#table_er').fadeIn('slow');
table.append(write_link(employees[i])); // function that displays the data
}
if(pages){
$('#pagination').html(pages);
}
} else ...
It seems you're asking table_er to fade in once per run of the loop whereas s there can only be one such table, you only need to do it once ?
first try re-arringing it like this:
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
$('#table_er').hide(); // hide it while we add the html
for (var i = 0; i < employees.length; i++) {
table.append(write_link(employees[i])); // function that displays the data
}
$('#table_er').fadeIn('slow'); // only do this after the table has all its html
if(pages){
$('#pagination').html(pages);
}
} else ....
Another possibility is that you're running through a loop and asking jquery to do stuff while the loop is running. It might be better to work out the whole HTML for the new page data in a string and then get the screen to render it in one line. I cna't do this for you as I don't know what's in write_link etc but something like this ..
if(employees){
$('#er_tab_label').html('<b>Employees with Issues</b>');
var sHTML ="";
$('#table_er').hide(); // hide it while we add the html
for (var i = 0; i < employees.length; i++) {
sHTML+=write_link(employees[i]); // maybe this is right ? if write_link returns an HTML string ?
}
table.append(sHTML); // add the HTML from the string in one go - stops the page rendering while the code is running
$('#table_er').fadeIn('slow'); // now show the table.
if(pages){
$('#pagination').html(pages);
}
} else ...

JQuery .load () in a loop does not work

Trying to run the following code, but it works either way I need to:
if(my_condition){
$('body').append("<div id='loaddiv'><div>");
for(var i=1; i<=100; i++){
var dl = 0;
$('#loaddiv').load('/script/?p='+i);
dl = $('#loaddiv .standart-view tr').length;
alert(dl);
}
}
Thus, I have to get the number of tr-elements, which is the parent element with class standart-view, and his parents - div block c id = load214235, for each page, but constantly displays zeros in the Alert :( I tried to upgrade the code, adding all the code in the load-callback function, but still does not work ...
if(my_condition){
$('body').append("<div id='loaddiv'><div>");
for(var i=1; i<=100; i++){
var dl = 0;
$('#loaddiv').load('/folder/?p='+i, function(){
dl = $('#loaddiv .standart-view tr').length;
alert(dl);
});
}
}
+I have yet to load after going condition with break; firebug it just swears that break does not know that close ... How do I get out of the situation? I feel that something with a visibility of variables and data do not have time to load another page, and the script is running on. Jquery is connected, the rest of the code is working, including the functions of jquery, the hierarchy of elements on another page observed (number of tr should be).
First load is an Asynchronous call, you are treating it as synchronous. You are reading the content before the Ajax call is returned. Hence why it is always zero.
Second, when you do hook it up write, the content will end up writing on top of each other. You can not use load() and expect it to work in a loop.
Here is the basic idea:
(function () {
var pageCounter = 1;
var tableRowsTotal = 0;
max pageMax=10;
function loadPage() {
$.get('/folder/?p='+pageCounter, function(data){
var table = $(data).filter(".standart-view");
//or
//var table = $(data).find(".standart-view");
var rows = table.find("tbody tr");
var rowCount = rows.length;
console.log(pageCounter, rowCount);
tableRowsTotal += rowCount;
pageCounter++;
if(pageCounter<pageMax) {
loadPage();
} else {
console.log("done");
}
});
}
loadPage();
}());

Set an HTML5 Video to PAUSE when video player is out of view

I'd like to do this with javascript. I'm building a presentation using Hakim El Hattab's Reveal.js as a foundation.
The way Reveal.js works is the current slide you are viewing has a class of .present, any previous slides have a class of .past, and any slides yet to come into view have a class of .future.
I would like it to automatically pause any video that is inside a slide set to .past or .future.
How should I go about this?
Thanks in advance!
************UPDATE**************
so thanks to some direction i got over on the css-tricks forums i was able to get it working on a single video using getElementById.
below is the javascript i'm using to add the .past and .future classes and simultaneously pause a video.
if( i < index ) {
// Any element previous to index is given the 'past' class
slide.setAttribute('class', 'past');
document.getElementById('vid').pause();
}
else if( i > index ) {
// Any element subsequent to index is given the 'future' class
slide.setAttribute('class', 'future');
document.getElementById('vid').pause();
}
the issue that i'm having now is how would i apply it to a tag name (ie: video) or possibly a class.
Now that you posted your code, it makes it easier to fix:
if( i < index ) {
// Any element previous to index is given the 'past' class
slide.setAttribute('class', 'past');
var vids = document.getElementsByClassName("past");
for (var i = 0; i < vids.length; i++) {
vids[i].pause();
}
}
else if( i > index ) {
// Any element subsequent to index is given the 'future' class
slide.setAttribute('class', 'future');
var vids = document.getElementsByClassName("future");
for (var i = 0; i < vids.length; i++) {
vids[i].pause();
}
}
See if that helps. If it doesn't, are you using a modern and standards-compliant browser? getElementsByClassName() is a relatively new feature. It works in the latest version of Chrome for me.
I don't know if setTimeout would work here but you could try the following:
function PauseVids() {
var vids = document.getElementsByClassName("past");
var vids2 = document.getElementsByClassName("future");
for (var i = 0; i < vids.length; i++) {
vids[i].pause();
}
for (var i = 0; i < vids2.length; i++) {
vids2[i].pause();
}
}
// Within onLoad or $(document).ready()
setTimeout("PauseVids()", 1000);
Tell me if that works.
#petschekr :guess this won't work, because classname past future is not only set to videoelements?!
i have no idea how reveals work and what kind of player you are using! but my way would be sth like:
there is only one file with the present class, right (current Slide)
a) define sth like a onChange function (for example on every button which changes pages + keypresses)
b) trigger that function before you switch pages
function onChange(){
var currentSlice = document.getElementByClassName('present') //get current html elemen
var videoObjects = currentSlice.getElementsByTag('video') //get videoelements here html5 video
for each videoObj
videoObj.pause()
edit: pseudocode to get you an idea!

Make all hyperlinks in the site do nothing

I want to make a script that disables hyperlinks and instead fires a function when one is clicked.
should work as
<a onclick="talk('http://google.com)'></a>
Is there a way to know when the wants to redirect and instead run "talk()" or display an alert window?
var anchors = document.getElementsByTagName('a');
for (var a = 0; a < anchors.length; a++){
anchors[a].href = "javascript:talk('" + anchors[a].href + "');";
}
Use some discretion though...
This solution uses (DOM Level 0) event handling instead of touching the href directly.
(function () {
var anchors = document.getElementsByTagName('a'),
i = anchors.length;
while (i--) {
anchors[i].onclick = function () {
talk(this.href);
return false;
};
}
}());
Edit: The benefit of this approach is it's much simpler to put the href back when you want to. Given an anchor tAnchor, you merely need to unset the onclick attribute:
tAnchor.onclick = null

Categories

Resources