Эффективная строковая замена JavaScript

Вам нужно подождать, пока ваше изображение загрузится, прежде чем вы сможете нарисовать его на холсте.

Для этого просто используйте обработчик события load вашего элемента :

// create a new image
var img = new Image();
// declare a function to call once the image has loaded
img.onload = function(){
  var canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  var context = canvas.getContext('2d');
  context.drawImage(img, 0,0);
  var dataURL = canvas.toDataURL();
  // now you can do something with the dataURL
  doSomething(dataURL);
}
// now set the image's src
img.src = "http://somerandomWebsite/picture.png";

Кроме того, для холста 'context.toDataURL() и context.getImageData для работайте правильно, вы должны получить свой ресурс изображения в соответствии с кросс-оригинальным способом , в противном случае холст «испорчен», что означает, что любой метод получения данных с пикселями будет заблокирован.

  • Если ваше изображение поступает с одного и того же сервера, нет проблем.
  • Если ваше изображение подано с внешнего сервера, убедитесь, что оно позволяет вашим в своих кросс-начальных заголовках и установить img.crossOrigin на "use-credentials".
  • Если сервер разрешает анонимные запросы, вы можете установить img.crossOrigin на "anonymous".

Nota Bene : Сервер CORS отправляется сервером, а атрибут cross-origin сообщает, что вы хотите использовать CORS для получения данных изображения, и вы не сможете обойти его, если сервер установлен неправильно. Кроме того, некоторые UserAgents (IE & amp; Safari) до сих пор не реализовали этот атрибут.

Edge Case : Если некоторые из ваших изображений находятся на вашем сервере, а некоторые из них соответствуют требованиям CORS один, тогда вы можете захотеть использовать обработчик события onerror, который должен срабатывать, если вы установите атрибут cross-origin на "anonymous" на сервере без CORS.

function corsError(){
  this.crossOrigin='';
  this.src='';
  this.removeEventListener('error', corsError, false);
} 
img.addEventListener('error', corsError, false);

32
задан 18 December 2008 в 14:24
поделиться

6 ответов

Я сомневаюсь, что будет что-либо более эффективное. Альтернатива разделила бы его на части и затем конкатенировала бы, но я не думаю, что это было бы очень эффективно. Возможно, еще меньше, полагая, что каждая конкатенация приводит к новой строке, которая имеет тот же размер как его операнды.

Добавленный: Это - вероятно, самый изящный способ записать это. Кроме того - по поводу чего Вы волнуетесь? Использование памяти? Это в изобилии, и JavaScript имеет достойного диспетчера памяти. Скорость выполнения? Затем у Вас должна быть некоторая гигантская строка. По моему скромному мнению, это хорошо.

12
ответ дан 27 November 2019 в 19:44
поделиться

Похоже, что Вы хотите использовать шаблон.

//Updated 28 October 2011: Now allows 0, NaN, false, null and undefined in output. 
function template( templateid, data ){
    return document.getElementById( templateid ).innerHTML
      .replace(
        /%(\w*)%/g, // or /{(\w*)}/g for "{this} instead of %this%"
        function( m, key ){
          return data.hasOwnProperty( key ) ? data[ key ] : "";
        }
      );
}

Объяснение кода:

  • Ожидает templateid быть идентификатором существующего элемента.
  • Ожидает data быть объектом с данными.
  • Использование два параметра для замены, чтобы сделать замену:
  • первым является regexp, который ищет весь %keys% (или {keys}, если Вы используете альтернативную версию). Ключ может быть комбинацией A-Z, a-z, 0-9 и подчеркнуть _.
  • второй является анонимная функция, которая требуется каждое соответствие.
  • анонимная функция ищет объект данных ключ, который нашел regexp. Если ключ найден в данных, то значение ключа возвращено, и то значение будет заменять ключ в окончательном результате. Если ключ не найден, пустая строка возвращается.

Пример шаблона:

<div id="mytemplate">
  <p>%test%</p>
  <p>%word%</p>
</div>

Пример вызова:

document.getElementById("my").innerHTML=template("mytemplate",{test:"MYTEST",word:"MYWORD"});
80
ответ дан 27 November 2019 в 19:44
поделиться

Вы могли, вероятно, адаптировать этот код, чтобы сделать то, что Вы хотите:

var user = {
    "firstName": "John",
    "login": "john_doe",
    "password": "test",
};

var textbody = ""
+"Hey {firstName},\n"
+"\n"
+"You recently requested your password.\n"
+"login: {login}\n"
+"password: {password}\n"
+"\n"
+"If you did not request your password, please disregard this message.\n"
+"";

textbody = textbody.replace(/{[^{}]+}/g, function(key){
    return user[key.replace(/[{}]+/g, "")] || "";
});

Вы могли бы также хотеть изучить JavaScriptTemplates

18
ответ дан 27 November 2019 в 19:44
поделиться

Ваш метод является стандартным способом реализовать систему шаблонной обработки плохого человека, таким образом, он прекрасен.

Это могло стоить Вашего, в то время как проверить некоторые библиотеки шаблонной обработки JavaScript, такой как JST.

2
ответ дан 27 November 2019 в 19:44
поделиться

Можно сделать это более эффективным путем объединения в цепочку замен вместо того, чтобы делать все эти временные присвоения.

т.е.

with(document.getElementById('sample'))
{
  innerHTML = innerHTML.replace(a, A).replace(b, B).replace(c, C); //etc
}
1
ответ дан 27 November 2019 в 19:44
поделиться

Если Вы готовы использовать библиотека Prototype , они имеют хороший созданный в шаблонной обработке функциональности.

, Который был бы похож:

element.innerHTML = (new Template(element.innerHTML)).evaluate({
    title: 'a title',
    keyword: 'some keyword',
    content: 'A bunch of content',
    id: 'id here'
})

Это было бы особенно хорошо при выполнении кода в цикле из-за простоты создания литералов объектов объектов/JavaScript JSON.

однако, я не ожидал бы увеличения скорости.

кроме того, необходимо было бы изменить стиль разделителя на #{keyword}, а не %keyword%

1
ответ дан 27 November 2019 в 19:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: