UPDATE [table_name] AS T1, (SELECT [имя_столбца] FROM [имя_таблицы] WHERE [имя_столбца] = [значение]) AS T2 SET T1. [column_name] = T2. [column_name] + 1 WHERE T1. [column_name] = [значение];
Пара решений для загрузки async:
//this function will work cross-browser for loading scripts asynchronously
function loadScript(src, callback)
{
var s,
r,
t;
r = false;
s = document.createElement('script');
s.type = 'text/javascript';
s.src = src;
s.onload = s.onreadystatechange = function() {
//console.log( this.readyState ); //uncomment this line to see which ready states are called.
if ( !r && (!this.readyState || this.readyState == 'complete') )
{
r = true;
callback();
}
};
t = document.getElementsByTagName('script')[0];
t.parentNode.insertBefore(s, t);
}
Если у вас уже есть jQuery на странице, просто используйте:
$.getScript(url, successCallback)
*
Кроме того, возможно, что ваши сценарии загружаются / выполняются до того, как документ будет загружен, что означает, что вам нужно будет ждать document.ready
до того, как события будут привязаны к элементам.
Невозможно точно рассказать, какова ваша проблема, не видя кода.
Самое простое решение - сохранить все ваши скрипты в нижней части страницы, Не блокируйте загрузку содержимого HTML во время их выполнения. Это также позволяет избежать необходимости асинхронной загрузки каждого требуемого сценария.
Если у вас особенно причудливое взаимодействие, которое не всегда используется, для чего требуется большой скрипт какого-либо типа, было бы полезно избежать загрузки этот сценарий пока не понадобится (ленивая загрузка).
* скрипты, загруженные с помощью $.getScript
, скорее всего, не будут кэшироваться
Для всех, кто может использовать современные функции, такие как объект Promise
, функция loadScript
стала значительно проще:
function loadScript(src) {
return new Promise(function (resolve, reject) {
var s;
s = document.createElement('script');
s.src = src;
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
}
Имейте в виду, что эта версия больше не принимает callback
, поскольку возвращенное обещание будет обрабатывать обратный вызов. Теперь было бы loadScript(src, callback)
loadScript(src).then(callback)
.
У этого есть дополнительный бонус, позволяющий обнаруживать и обрабатывать сбои, например, можно вызвать ...
loadScript(cdnSource)
.catch(loadScript.bind(null, localSource))
.then(successCallback, failureCallback);
] ... и будет обрабатывать изъяны CDN изящно.
Ну, x.parentNode
возвращает элемент HEAD, поэтому вы вставляете скрипт непосредственно перед тегом head. Возможно, это проблема.
Вместо этого попробуйте x.parentNode.appendChild()
.
Вот отличное современное решение для загрузки асинхронного скрипта, хотя оно адресовано только сценарию js с асинхронным ложным.
Существует большая статья, написанная на www.html5rocks.com - Глубокое погружение в мутные воды загрузки скрипта .
После рассмотрения многих возможных решений, автор пришел к выводу, что добавление js-скриптов в конец элемента body является наилучшим способом избежать блокировки отображения страницы с помощью js-скриптов.
В то же время автор добавил другое хорошее альтернативное решение для тех людей, которые отчаянно пытаются загрузить и выполнить сценарии асинхронно.
Учитывая, что у вас есть четыре сценария с именем script1.js, script2.js, script3.js, script4.js
, вы можете сделать это с помощью async = false:
[
'script1.js',
'script2.js',
'script3.js',
'script4.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
Теперь, Spec говорит: Скачайте вместе, выполните в порядке как скоро как вся загрузка.
Firefox & lt; 3.6, Opera говорит: я понятия не имею, что это за «асинхронная» вещь, но это так происходит. Я запускаю скрипты, добавленные через JS, в том порядке, в котором они добавлены.
Safari 5.0 говорит: «Я понимаю», async ", но не понимают, что он устанавливает значение" false "с помощью JS. Я буду выполнять ваши скрипты, как только они приземлятся, в любом порядке.
IE & lt; 10 говорит: «Не знаю, как« асинхронно », но есть обходное решение, использующее« onreadystatechange ».
Все остальное говорит:« Я твой друг, мы сделаем это по книге ».
Теперь полный код с IE & lt; 10:
var scripts = [
'script1.js',
'script2.js',
'script3.js',
'script4.js'
];
var src;
var script;
var pendingScripts = [];
var firstScript = document.scripts[0];
// Watch scripts load in IE
function stateChange() {
// Execute as many scripts in order as we can
var pendingScript;
while (pendingScripts[0] && ( pendingScripts[0].readyState == 'loaded' || pendingScripts[0].readyState == 'complete' ) ) {
pendingScript = pendingScripts.shift();
// avoid future loading events from this script (eg, if src changes)
pendingScript.onreadystatechange = null;
// can't just appendChild, old IE bug if element isn't closed
firstScript.parentNode.insertBefore(pendingScript, firstScript);
}
}
// loop through our script urls
while (src = scripts.shift()) {
if ('async' in firstScript) { // modern browsers
script = document.createElement('script');
script.async = false;
script.src = src;
document.head.appendChild(script);
}
else if (firstScript.readyState) { // IE<10
// create a script and add it to our todo pile
script = document.createElement('script');
pendingScripts.push(script);
// listen for state changes
script.onreadystatechange = stateChange;
// must set src AFTER adding onreadystatechange listener
// else we’ll miss the loaded event for cached scripts
script.src = src;
}
else { // fall back to defer
document.write('<script src="' + src + '" defer></'+'script>');
}
}
Несколько примечаний:
s.async = true
не очень корректно относится к HTML-типу HTML5, верно s.async = 'async'
(фактически использование true
является правильным, благодаря amn , которые указали это в комментарии ниже чуть ниже) Поскольку существует новая причина для загрузки файлов асинхронно, но в порядке, я бы рекомендовал немного более функционально-ориентированный путь по вашему примеру (удалите console.log
для использования в производстве :)):
(function() {
var prot = ("https:"===document.location.protocol?"https://":"http://");
var scripts = [
"path/to/first.js",
"path/to/second.js",
"path/to/third.js"
];
function completed() { console.log('completed'); } // FIXME: remove logs
function checkStateAndCall(path, callback) {
var _success = false;
return function() {
if (!_success && (!this.readyState || (this.readyState == 'complete'))) {
_success = true;
console.log(path, 'is ready'); // FIXME: remove logs
callback();
}
};
}
function asyncLoadScripts(files) {
function loadNext() { // chain element
if (!files.length) completed();
var path = files.shift();
var scriptElm = document.createElement('script');
scriptElm.type = 'text/javascript';
scriptElm.async = true;
scriptElm.src = prot+path;
scriptElm.onload = scriptElm.onreadystatechange = \
checkStateAndCall(path, loadNext); // load next file in chain when
// this one will be ready
var headElm = document.head || document.getElementsByTagName('head')[0];
headElm.appendChild(scriptElm);
}
loadNext(); // start a chain
}
asyncLoadScripts(scripts);
})();
s.async = true
правильный i>. Свойство async
указано явно как логическое выражение в рекомендации W3C по HTML 5 в w3.org/TR/html5/scripting-1.html#attr-script-async . Вы сбиваете с толку атрибут async
i> с свойством async
, отображаемым объектами, реализующими интерфейс DOM HTMLScriptElement
. В самом деле, при манипулировании соответствующим атрибутом элемента через что-то вроде Element.setAttribute
, вы должны использовать element.setAttribute("async", "async")
, поскольку все атрибуты HTML являются в первую очередь текстом.
– amn
28 June 2016 в 00:17
Вот мое пользовательское решение для устранения JavaScript-рендеринга:
// put all your JS files here, in correct order
const libs = {
"jquery": "https://code.jquery.com/jquery-2.1.4.min.js",
"bxSlider": "https://cdnjs.cloudflare.com/ajax/libs/bxslider/4.2.5/jquery.bxslider.min.js",
"angular": "https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.2/angular.min.js",
"ngAnimate": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.2/angular-animate.min.js"
}
const loadedLibs = {}
let counter = 0
const loadAsync = function(lib) {
var http = new XMLHttpRequest()
http.open("GET", libs[lib], true)
http.onload = () => {
loadedLibs[lib] = http.responseText
if (++counter == Object.keys(libs).length) startScripts()
}
http.send()
}
const startScripts = function() {
for (var lib in libs) eval(loadedLibs[lib])
console.log("allLoaded")
}
for (var lib in libs) loadAsync(lib)
Короче говоря, он асинхронно загружает все ваши сценарии, а затем выполняет их соответственно.
Github repo : https://github.com/mudroljub/js-async-loader
No 'Access-Control-Allow-Origin' header is present on the requested resource
– Abram
7 March 2016 в 23:22
Новый атрибут «async» HTML5 должен сделать трюк. «defer» также поддерживается в большинстве браузеров, если вы беспокоитесь об IE.
async - HTML
<script async src="siteScript.js" onload="myInit()"></script>
defer - HTML
<script defer src="siteScript.js" onload="myInit()"></script>
При анализе нового рекламного блока AdSense я заметил атрибут и поиск приведи меня сюда: http://davidwalsh.name/html5-async
async
или defer
он будет блокировать рендеринг во время загрузки. Установка async
подскажет, чтобы он не блокировал и не запускал сценарий как можно скорее. Установка defer
покажет, что он не заблокирован, но подождите, пока сценарий работает i>, пока страница не будет выполнена. Обычно нет проблем запускать сценарии ASAP, если у них нет зависимостей (например, jQuery). Если один сценарий имеет зависимости от другого, используйте onLoad
, чтобы дождаться его.
– Stijn de Witt
19 April 2016 в 08:28
Я бы предложил сначала изучить мини-файлы и посмотреть, дает ли это вам достаточно большой прирост скорости. Если ваш хост работает медленно, можно попробовать поставить статический контент на CDN.
Считаете ли вы использование Fetch Injection? Я обработал библиотеку с открытым исходным кодом, названную fetch-inject , чтобы обрабатывать такие случаи. Вот что может выглядеть ваш загрузчик с помощью lib:
fetcInject([
'js/jquery-1.6.2.min.js',
'js/marquee.js',
'css/marquee.css',
'css/custom-theme/jquery-ui-1.8.16.custom.css',
'css/main.css'
]).then(() => {
'js/jquery-ui-1.8.16.custom.min.js',
'js/farinspace/jquery.imgpreload.min.js'
})
. Для обнаружения функции обратной совместимости и возврата к XHR Injection или Script DOM Elements или просто встраивайте теги в страницу с помощью document.write
.
Здесь немного ES6, если кто-то хочет использовать его в React, например
import {uniqueId} from 'lodash' // optional
/**
* @param {String} file The path of the file you want to load.
* @param {Function} callback (optional) The function to call when the script loads.
* @param {String} id (optional) The unique id of the file you want to load.
*/
export const loadAsyncScript = (file, callback, id) => {
const d = document
if (!id) { id = uniqueId('async_script') } // optional
if (!d.getElementById(id)) {
const tag = 'script'
let newScript = d.createElement(tag)
let firstScript = d.getElementsByTagName(tag)[0]
newScript.id = id
newScript.async = true
newScript.src = file
if (callback) {
// IE support
newScript.onreadystatechange = () => {
if (newScript.readyState === 'loaded' || newScript.readyState === 'complete') {
newScript.onreadystatechange = null
callback(file)
}
}
// Other (non-IE) browsers support
newScript.onload = () => {
callback(file)
}
}
firstScript.parentNode.insertBefore(newScript, firstScript)
} else {
console.error(`The script with id ${id} is already loaded`)
}
}
Пример из google
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js?onload=onLoadCallback';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
Благодаря HTML5 вы можете теперь объявить сценарии, которые вы хотите загрузить асинхронно, добавив в тег «async»:
<script async>...</script>
Примечание. Асинхронный атрибут предназначен только для внешних скриптов (и должен использоваться только в том случае, если присутствует атрибут src).
Примечание. Существует несколько способов выполнения внешнего скрипта:
См. это: http: // www .w3schools.com / теги / att_script_async.asp
Вы можете использовать LABJS или RequreJS
Скриптовые загрузчики, такие как LABJS
, RequireJS
, улучшат скорость и качество вашего кода.
Я бы предложил вам взглянуть на Modernizr . Это небольшая небольшая библиотека, в которую вы можете асинхронно загружать свой javascript с функциями, которые позволяют вам проверить, загружен ли файл, и выполнить сценарий в другом, указанном вами.
Вот пример загрузки jquery:
Modernizr.load([
{
load: '//ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.js',
complete: function () {
if ( !window.jQuery ) {
Modernizr.load('js/libs/jquery-1.6.1.min.js');
}
}
},
{
// This will wait for the fallback to load and
// execute if it needs to.
load: 'needs-jQuery.js'
}
]);
Проверьте этот https://github.com/stephen-lazarionok/async-resource-loader . В нем есть пример, который показывает, как загрузить JS, CSS и несколько файлов одним выстрелом.
Вы можете найти эту статью в вики интересной: http://ajaxpatterns.org/On-Demand_Javascript
В ней объясняется, как и когда использовать такую технику.
Одна из причин, по которой ваши скрипты могут загружаться настолько медленно, - это если вы запускали все свои скрипты при загрузке страницы, например:
callMyFunctions();
вместо:
$(window).load(function() {
callMyFunctions();
});
Этот второй бит скрипта ждет, пока браузер полностью не загрузит весь ваш код Javascript до того, как он начнет выполнение каких-либо из ваших сценариев, что приведет к тому, что пользователь будет загружен быстрее.
вы хотите улучшить пользовательский опыт, уменьшив время загрузки, я бы не пошел на опцию «загрузка экрана». По-моему, это было бы гораздо более раздражающим, чем просто медленная загрузка страницы.
Я бы выполнил ответ zzzzBov с проверкой наличия обратного вызова и разрешить передачу аргументов:
function loadScript(src, callback, args) {
var s, r, t;
r = false;
s = document.createElement('script');
s.type = 'text/javascript';
s.src = src;
if (typeof(callback) === 'function') {
s.onload = s.onreadystatechange = function() {
if (!r && (!this.readyState || this.readyState === 'complete')) {
r = true;
callback.apply(args);
}
};
};
t = document.getElementsByTagName('script')[0];
t.parent.insertBefore(s, t);
}
Я загрузил скрипты асинхронно (html 5 имеет эту функцию), когда все сценарии, где была сделана загрузка, я перенаправил страницу в index2.html, где index2.html использует те же библиотеки. Поскольку браузеры имеют кеш, когда страница перенаправляется на index2.html, index2.html загружается менее чем за секунду, потому что у нее есть все необходимое для загрузки страницы. На моей странице index.html я также загружаю изображения, которые планирую использовать, чтобы браузер размещал эти изображения в кеше. поэтому мой index.html выглядит так:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Project Management</title>
<!-- the purpose of this page is to load all the scripts on the browsers cache so that pages can load fast from now on -->
<script type="text/javascript">
function stylesheet(url) {
var s = document.createElement('link');
s.type = 'text/css';
s.async = true;
s.src = url;
var x = document.getElementsByTagName('head')[0];
x.appendChild(s);
}
function script(url) {
var s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = url;
var x = document.getElementsByTagName('head')[0];
x.appendChild(s);
}
//load scritps to the catche of browser
(function () {
stylesheet('css/custom-theme/jquery-ui-1.8.16.custom.css');
stylesheet('css/main.css');
stylesheet('css/marquee.css');
stylesheet('css/mainTable.css');
script('js/jquery-ui-1.8.16.custom.min.js');
script('js/jquery-1.6.2.min.js');
script('js/myFunctions.js');
script('js/farinspace/jquery.imgpreload.min.js');
script('js/marquee.js');
})();
</script>
<script type="text/javascript">
// once the page is loaded go to index2.html
window.onload = function () {
document.location = "index2.html";
}
</script>
</head>
<body>
<div id="cover" style="position:fixed; left:0px; top:0px; width:100%; height:100%; background-color:Black; z-index:100;">Loading</div>
<img src="images/home/background.png" />
<img src="images/home/3.png"/>
<img src="images/home/6.jpg"/>
<img src="images/home/4.png"/>
<img src="images/home/5.png"/>
<img src="images/home/8.jpg"/>
<img src="images/home/9.jpg"/>
<img src="images/logo.png"/>
<img src="images/logo.png"/>
<img src="images/theme/contentBorder.png"/>
</body>
</html>
еще одна приятная вещь в том, что я могу разместить загрузчик на странице, и когда страница будет сделана, загрузка загрузчика исчезнет и в матах миллисекунды новая страница будет запущена.
Я написал небольшое сообщение, чтобы помочь с этим, вы можете прочитать здесь https://timber.io/snippets/asynchronously-load-a-script-in-the-browser-with-javascript/ , но я добавил вспомогательный класс ниже. Он будет автоматически ждать загрузки сценария и возврата указанного атрибута окна.
export default class ScriptLoader {
constructor (options) {
const { src, global, protocol = document.location.protocol } = options
this.src = src
this.global = global
this.protocol = protocol
this.isLoaded = false
}
loadScript () {
return new Promise((resolve, reject) => {
// Create script element and set attributes
const script = document.createElement('script')
script.type = 'text/javascript'
script.async = true
script.src = `${this.protocol}//${this.src}`
// Append the script to the DOM
const el = document.getElementsByTagName('script')[0]
el.parentNode.insertBefore(script, el)
// Resolve the promise once the script is loaded
script.addEventListener('load', () => {
this.isLoaded = true
resolve(script)
})
// Catch any errors while loading the script
script.addEventListener('error', () => {
reject(new Error(`${this.src} failed to load.`))
})
})
}
load () {
return new Promise(async (resolve, reject) => {
if (!this.isLoaded) {
try {
await this.loadScript()
resolve(window[this.global])
} catch (e) {
reject(e)
}
} else {
resolve(window[this.global])
}
})
}
}
Использование выглядит так:
const loader = new Loader({
src: 'cdn.segment.com/analytics.js',
global: 'Segment',
})
// scriptToLoad will now be a reference to `window.Segment`
const scriptToLoad = await loader.load()
document.head.appendChild
, однако есть некоторые проблемы с нишей с добавлением скриптов к<head>
; ничего, что помешало бы загрузке и выполнению сценариев. – zzzzBov 12 October 2011 в 18:38document.write
до загрузки документа, сценарий будет выполняться синхронно как часть загрузки страницы и не будет включать асинхронное поведение обратного вызова сам по себе. Если вы создаете элемент сценария и добавляете его на страницу, у вас будет доступ к добавлению прослушивателей событий для асинхронного запуска. tl; dr: зависит от того, как вы загружаете скрипт с помощью JS. – zzzzBov 30 October 2014 в 02:20